OpenGL ES 案例03:CoreAnimation绘制立方体+旋转

简介: OpenGL ES 案例03:CoreAnimation绘制立方体+旋转

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

微信图片_20220514173742.png


整体实现的思路如下

微信图片_20220514173910.png

主要分为两部分


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


ViewDidLoad函数


初始化工作包含两部分:


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


addFaces函数


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


微信图片_20220514174123.png


  • 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
   }


相关文章
|
6月前
QT4.7版本的OPENGL的3D旋转模型例子
QT4.7版本的OPENGL的3D旋转模型例子
127 0
|
6月前
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
124 0
|
C++ 计算机视觉 Python
C++ VS OpenGL绘制教室三维立体旋转图像
C++ VS OpenGL绘制教室三维立体旋转图像
130 0
C++ VS OpenGL绘制教室三维立体旋转图像
|
存储 编解码 算法
Opengl ES之LUT滤镜(上)
Opengl ES之连载系列
458 0
|
数据安全/隐私保护 开发者
OpenGL ES 多目标渲染(MRT)
Opengl ES连载系列
322 0
|
数据安全/隐私保护 索引
Opengl ES之纹理数组
Opengl ES连载系列
258 0
|
数据安全/隐私保护
Opengl ES之水印贴图
Opengl ES之连载系列
151 0
|
缓存 C++
Opengl ES之FBO
Opengl ES连载系列
151 0
|
Java 数据安全/隐私保护 Android开发
Opengl ES之矩阵变换(下)
Opengl ES连载系列
130 0
|
Java API 数据安全/隐私保护
Opengl ES之矩阵变换(上)
Opengl ES连载系列
148 0