OpenGL相关

OpenGL ES / Core Animation分别实现旋转

2020-10-22  本文已影响0人  沙克阿拉卡

一 、使用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;
    }
}];

}

上一篇下一篇

猜你喜欢

热点阅读