一 、使用OpenGL实现立方体旋转
@interface ViewController ()
{
EAGLContext *_context;
GLKBaseEffect *_baseEffect;
int _angle;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.OpenGL ES 相关初始化
[self setUpConfig];
//2.加载顶点/纹理坐标数据
[self setUpVertexData];
//3.加载纹理数据(使用GLBaseEffect)
[self setUpTexture];
}
-(void)setUpTexture
{
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"qiyu" ofType:@"jpg"];
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft : @(YES)};
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
// 纹理设置
_baseEffect = [[GLKBaseEffect alloc] init];
_baseEffect.texture2d0.enabled = GL_TRUE;
_baseEffect.texture2d0.name = textureInfo.name;
// 透视投影矩阵
CGFloat aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0);
_baseEffect.transform.projectionMatrix = projectionMatrix;
}
-(void)setUpVertexData
{
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
// 顶点缓存
GLuint bufferID;
glGenBuffers(1, &bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//顶点坐标数据
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
//纹理坐标数据
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
}
- (void)setUpConfig
{
_context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (!_context) {
NSLog(@"Create ES context Failed");
}
//设置当前上下文
[EAGLContext setCurrentContext:_context];
GLKView *view =(GLKView *) self.view;
view.context = _context;
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
glClearColor(0.8, 0.8, 0.8, 1.0);
}
#pragma mark -- GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 更新旋转
[self update];
[_baseEffect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 48);
}
- (void)update {
_angle = (_angle + 2) % 360;
GLKMatrix4 modelviewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0, 0, -4.0);
modelviewMatrix = GLKMatrix4Rotate(modelviewMatrix, GLKMathDegreesToRadians(_angle), 0.3, 0.5, 0.7);
_baseEffect.transform.modelviewMatrix = modelviewMatrix;
}
@end
二、 使用核心动画实现立方体旋转
使用 Core Animation 完成上面的功能也非常简单,利用layer.transform的数据结构CATransform3D即可完成3D变换。为了实现立方体整体的旋转动画,不需要为为一个面都专门做变换。只需要将它们放在同一个父视图中,利用父视图的layer.sublayerTransform即可对所有子视图进行统一变换。
@interface ViewController ()
@property (nonatomic, strong) UIView *containerView;
@end
@implementation ViewController
- (void)addFace:(int)index withTransform:(CATransform3D)transform
{
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"qiyu" ofType:@"jpg"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
imageView.image = [UIImage imageWithContentsOfFile:filePath];
[self.containerView addSubview:imageView];
CGSize containerSize = self.containerView.bounds.size;
imageView.center = CGPointMake(containerSize.width / 2.0, containerSize.height / 2.0);
// 变换
imageView.layer.transform = transform;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.lightGrayColor;
self.containerView = [[UIView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:self.containerView];
//add cube face 1
CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);
[self addFace:0 withTransform:transform];
//add cube face 2
transform = CATransform3DMakeTranslation(100, 0, 0);
transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
[self addFace:1 withTransform:transform];
//add cube face 3
transform = CATransform3DMakeTranslation(0, -100, 0);
transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
[self addFace:2 withTransform:transform];
//add cube face 4
transform = CATransform3DMakeTranslation(0, 100, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
[self addFace:3 withTransform:transform];
//add cube face 5
transform = CATransform3DMakeTranslation(-100, 0, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
[self addFace:4 withTransform:transform];
//add cube face 6
transform = CATransform3DMakeTranslation(0, 0, -100);
transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
[self addFace:5 withTransform:transform];
__block int step = 0;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
step = (step + 2) % 360;
self.containerView.layer.sublayerTransform = CATransform3DMakeRotation(M_PI / 180.0 * step, -0.3, 0.5, -0.7);
}];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
@end
另外,核心动画旋转代码:
- (void)addSubview{
self.view.backgroundColor = [UIColor whiteColor];
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 100, 40);
[button addTarget:self action:@selector(CATransform3DTouch:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"Touch" forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[self.view addSubview:button];
self.imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(100, 200, 150, 100)];
self.imageView1.backgroundColor = [UIColor redColor];
[self.view addSubview: self.imageView1];
self.imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(100, 350, 150, 100)];
self.imageView2.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.imageView2];
}
- (void)CATransform3DTouch:(UIButton *)sender{
sender.selected = !sender.selected;
[UIView animateWithDuration:2 animations:^{
if (sender.selected) {
//CALayer的3D旋转
CATransform3D turnTrans = CATransform3DMakeRotation(M_PI/4, 1, 0, 0);
self.imageView1.layer.transform = turnTrans;
self.imageView2.layer.transform = turnTrans;
//或
//self.imageView1.transform = CGAffineTransformMakeRotation(M_PI/4);
//self.imageView2.transform = CGAffineTransformMakeRotation(M_PI/4);
}else{
self.imageView1.layer.transform = CATransform3DIdentity;
self.imageView2.layer.transform = CATransform3DIdentity;
//或
//self.imageView2.transform = CGAffineTransformIdentity;
//self.imageView2.transform = CGAffineTransformIdentity;
}
}];
}
网友评论