美文网首页iOS
OpenGL ES 案例03:CoreAnimation绘制立方

OpenGL ES 案例03:CoreAnimation绘制立方

作者: Style_月月 | 来源:发表于2020-07-27 23:05 被阅读0次

    OpenGL + OpenGL ES +Metal 系列文章汇总

    在不会OpenGL ES的情况下,如何利用CoreAnimation实现一个立方体,并旋转,整体效果如下


    OpenGL_ES_03_效果图

    整体实现的思路如下


    整体实现思路

    主要分为两部分

    • ViewDidLoad函数:初始化工作
    • update更新:定时器实现旋转

    ViewDidLoad函数

    初始化工作包含两部分:

    • addFaces:添加6个面,通过变换组合成立方体
    • addCADisplayLink:添加定时器,并放入runloop

    addFaces函数
    这部分主要是将6个面作相应的变换添加到容器中

    6个面的变换
    • OC版本
    //添加面
    - (void)addFaces{
        self.faces = @[_view0, _view1, _view2, _view3, _view4, _view5];
        
    //    主view
        CATransform3D perspective = CATransform3DIdentity;
    //    核心动画设置透视投影
        perspective.m34 = -1.0 / 500.0;
    //    围绕x,y分别旋转,M_PI_4 = π/4,π=180°
    //      x:顺时针旋转45°,y:顺时针旋转45°
        perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
        perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
        self.containerView.layer.sublayerTransform = perspective;
        
        //添加face1
    //    z轴平移100
    //    (除了第一个视图外,其余的视图都是基于第一个视图的位置进行平移+旋转的)
        CATransform3D transform = CATransform3DMakeTranslation(0, 0, 100);
        [self addFace:0 withTransform:transform];
        
    ////    添加face2 --平移y+旋转y
        transform = CATransform3DMakeTranslation(100, 0, 0);
        transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
        [self addFace:1 withTransform:transform];
    //
    //     添加face3 -- 平移y+旋转x
        transform = CATransform3DMakeTranslation(0, -100, 0);
        transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
    //    [self addFace:2 withTransform:transform];
        
    //    添加face4 -- 平移y+旋转x
        transform = CATransform3DMakeTranslation(0, 100, 0);
        transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
        [self addFace:3 withTransform:transform];
    
    //    添加face5 -- 平移+旋转
        transform = CATransform3DMakeTranslation(-100, 0, 0);
        transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
        [self addFace:4 withTransform:transform];
    
    //    添加face6 -- 平移z+旋转y
        transform = CATransform3DMakeTranslation(0, 0, -100);
        transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
        [self addFace:5 withTransform:transform];
    }
    
    - (void)addFace: (NSInteger)index withTransform: (CATransform3D)transform
    {
    //    获取face视图,并将其加入容器中
        UIView *face = self.faces[index];
        [self.containerView addSubview:face];
        
    //    将face视图放在容器的中心
        CGSize containerSize = self.containerView.bounds.size;
        face.center = CGPointMake(containerSize.width/2.0, containerSize.height/2.0);
        
    //    添加tansform,tansform就是一个矩阵
        face.layer.transform = transform;
    }
    
    • Swift版本
    fileprivate func addFaces(){
            faces = [view0, view1, view2, view3, view4, view5]
            
    //        父view的layer图层
            var perspective: CATransform3D = CATransform3DIdentity
            perspective.m34 = -1.0 / 500.0
            perspective = CATransform3DRotate(perspective, -.pi/4, 1, 0, 0)
            perspective = CATransform3DRotate(perspective, -.pi/4, 0, 1, 0)
            self.containerView.layer.sublayerTransform = perspective
            
    //        添加face1
            var transform = CATransform3DMakeTranslation(0, 0, 100)
            self.addFaceWithTransform(0, transform)
            
    //        添加face2
            transform = CATransform3DMakeTranslation(100, 0, 0)
            transform = CATransform3DRotate(transform, .pi/2, 0, 1, 0)
            self.addFaceWithTransform(1, transform)
            
    //        添加face3
            transform = CATransform3DMakeTranslation(0, -100, 0)
    //        transform = CATransform3DRotate(transform, .pi/2, 1, 0, 0)
    //        self.addFaceWithTransform(2, transform)
    //
    //        添加face4
            transform = CATransform3DMakeTranslation(0, 100, 0)
            transform = CATransform3DRotate(transform, -.pi/2, 1, 0, 0)
            self.addFaceWithTransform(3, transform)
    //
    //        添加face5
            transform = CATransform3DMakeTranslation(-100, 0, 0)
    //        transform = CATransform3DRotate(transform, -.pi/2, 0, 1, 0)
            self.addFaceWithTransform(4, transform)
    //
    ////        添加face6
    //        transform = CATransform3DMakeTranslation(0, 0, -100)
    //        transform = CATransform3DRotate(transform, .pi, 0, 1, 0)
    //        self.addFaceWithTransform(5, transform)
    
        }
        
        private func addFaceWithTransform(_ index: Int, _ transform: CATransform3D){
    //        获取face,并加入容器中
            let face = self.faces[index]
            self.containerView.addSubview(face)
            
    //        将face视图放入容器的中心
            let containerSize = self.containerView.bounds.size
            face.center = CGPoint(x: containerSize.width/2, y: containerSize.height/2)
            
    //        添加transform
            face.layer.transform = transform
            
        }
    

    addCADisplayLink函数
    这部分主要初始化定时器,并将定时器加入runloop循环中

    • OC版本
    //添加定时器
    - (void)addCADisplayLink{
        self.angle = 0;
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
        [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }
    
    • Swift版本
    fileprivate func addCADisplayLink(){
        self.displayLink.add(to: RunLoop.main, forMode: .common)
       }
    

    update更新

    主要是计算旋转度数,并将容器的子layer围绕任意方向旋转

    • OC版本
    - (void)update{
        
    //    计算旋转度数
        self.angle = (self.angle + 5) % 360;
    //    将度数转化为弧度
        float deg = self.angle * (M_PI / 180);
        CATransform3D temp = CATransform3DIdentity;
    //    围绕(0.3, 1, 0.7)方向旋转
        temp = CATransform3DRotate(temp, deg, 0.3, 1, 0.7);
    //    旋转容器的子layer
        self.containerView.layer.sublayerTransform = temp;
    }
    
    • Swift版本
    @objc fileprivate func update(){
        self.angle = (self.angle+5).truncatingRemainder(dividingBy: 360)
        let deg = self.angle * (.pi/180)
        var temp = CATransform3DIdentity
        temp = CATransform3DRotate(temp, CGFloat(deg), 0.3, 1, 0.7)
        
        self.containerView.layer.sublayerTransform = temp
       }
    

    完整的代码见github - 09_CoreAnimation_立方体+旋转OC、09_CoreAnimation立方体+旋转_Swift,分别提供了OC和Swift版本

    相关文章

      网友评论

        本文标题:OpenGL ES 案例03:CoreAnimation绘制立方

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