美文网首页OpenGL相关
OpenGL ES / Core Animation分别实现旋转

OpenGL ES / Core Animation分别实现旋转

作者: 沙克阿拉卡 | 来源:发表于2020-08-27 20:17 被阅读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;
        }
    }];
    

    }

    相关文章

      网友评论

        本文标题:OpenGL ES / Core Animation分别实现旋转

        本文链接:https://www.haomeiwen.com/subject/iuehsktx.html