美文网首页OpenGL
0010--OpenGL ES初探:GLKit 案例实现-旋转立

0010--OpenGL ES初探:GLKit 案例实现-旋转立

作者: 清风烈酒2157 | 来源:发表于2020-07-27 15:20 被阅读0次

    前言

    学习OpenGL ES纹理贴图之后,对一个四边形进行贴图基本上已经掌握,接下来做一个立方体的贴图,并旋转.

    准备工作

    立方体和单个四边形区别,多了5个面,定点数也有原来的6个变成36个.

    • 首先创建需要的类已经一个OPVertex来存放顶点和纹理顶点.
    
    
    ypedef struct OPVertex{
        GLKVector3 positionCoord;//顶点坐标
        GLKMatrix2 texturecoord; //纹理
    }OPVertex;
    
    //总共顶点数
    static int const kCoordCount = 36;
    
    
    
    EAGLContext *context; //上下文
    GLKBaseEffect *cEffect;// 着色器
    NSInteger angle; //记录旋转的角度
    GLKView *glkView; //glkView
    
    @property(nonatomic, assign) OPVertex *vertices;
    
    
    

    绘制

    • 初始化上下文&设置当前上下文,设置渲染区和背景颜色

    这一步和之前绘制没有变化

    
    -(void)setUpConfig
    {
       
        context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
        //判断context是否创建成功
        if (!context) {
            NSLog(@"Create ES context Failed");
        }
        //设置当前上下文
        [EAGLContext setCurrentContext:context];
        
        //2.获取GLKView & 设置context
        GLKView *view =(GLKView *) self.view;
        view.context = context;
       
        //3.配置视图创建的渲染缓存区.
        view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
        view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
        glkView = view;
        
        //4.设置背景颜色
        glClearColor(1, 0, 0, 1.0);
    }
    
    
    • 加载顶点/纹理坐标数据
    1. 使用malloc分配内存
    
     self.vertices = malloc(sizeof(OPVertex) * kCoordCount);
    
    
    1. 6个面对应的顶点和纹理坐标
    
    // 前面
        self.vertices[0] = (OPVertex){{-0.5, 0.5, 0.5},  {0, 1}};
        self.vertices[1] = (OPVertex){{-0.5, -0.5, 0.5}, {0, 0}};
        self.vertices[2] = (OPVertex){{0.5, 0.5, 0.5},   {1, 1}};
        
        self.vertices[3] = (OPVertex){{-0.5, -0.5, 0.5}, {0, 0}};
        self.vertices[4] = (OPVertex){{0.5, 0.5, 0.5},   {1, 1}};
        self.vertices[5] = (OPVertex){{0.5, -0.5, 0.5},  {1, 0}};
        
        // 上面
        self.vertices[6] = (OPVertex){{0.5, 0.5, 0.5},    {1, 1}};
        self.vertices[7] = (OPVertex){{-0.5, 0.5, 0.5},   {0, 1}};
        self.vertices[8] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
        self.vertices[9] = (OPVertex){{-0.5, 0.5, 0.5},   {0, 1}};
        self.vertices[10] = (OPVertex){{0.5, 0.5, -0.5},  {1, 0}};
        self.vertices[11] = (OPVertex){{-0.5, 0.5, -0.5}, {0, 0}};
        
        // 下面
        self.vertices[12] = (OPVertex){{0.5, -0.5, 0.5},    {1, 1}};
        self.vertices[13] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[14] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};
        self.vertices[15] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[16] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};
        self.vertices[17] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
        
        // 左面
        self.vertices[18] = (OPVertex){{-0.5, 0.5, 0.5},    {1, 1}};
        self.vertices[19] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[20] = (OPVertex){{-0.5, 0.5, -0.5},   {1, 0}};
        self.vertices[21] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[22] = (OPVertex){{-0.5, 0.5, -0.5},   {1, 0}};
        self.vertices[23] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
        
        // 右面
        self.vertices[24] = (OPVertex){{0.5, 0.5, 0.5},    {1, 1}};
        self.vertices[25] = (OPVertex){{0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[26] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
        self.vertices[27] = (OPVertex){{0.5, -0.5, 0.5},   {0, 1}};
        self.vertices[28] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
        self.vertices[29] = (OPVertex){{0.5, -0.5, -0.5},  {0, 0}};
        
        // 后面
        self.vertices[30] = (OPVertex){{-0.5, 0.5, -0.5},   {0, 1}};
        self.vertices[31] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
        self.vertices[32] = (OPVertex){{0.5, 0.5, -0.5},    {1, 1}};
        self.vertices[33] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
        self.vertices[34] = (OPVertex){{0.5, 0.5, -0.5},    {1, 1}};
        self.vertices[35] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};
    
    
    1. 开辟顶点缓存区
    
    GLuint bufferID;
        glGenBuffers(1, &bufferID);
        //(2).绑定顶点缓存区.(明确作用)
        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
        //(3).将顶点数组的数据copy到顶点缓存区中(GPU显存中)
        glBufferData(GL_ARRAY_BUFFER, sizeof(OPVertex) * kCoordCount, self.vertices, GL_STATIC_DRAW);
        
        // 顶点坐标数据
      glEnableVertexAttribArray(GLKVertexAttribPosition);
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(OPVertex) , offsetof(OPVertex, positionCoord) + NULL);   
        
        
        //纹理坐标数据
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(OPVertex), offsetof(OPVertex, texturecoord) + NULL);
    
    

    sizeof(OPVertex) * kCoordCount传入内容的大小
    offsetof(OPVertex, positionCoord) + NULL,对应顶点或者纹理起始点的内存偏移值

    • 加载纹理数据
    
    
    {
        //1.获取纹理图片路径
        NSString *filePath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"jpg"];
        
        //2.设置纹理参数
        //纹理坐标原点是左下角,但是图片显示原点应该是左上角.
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
        
        GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
        
        //3.使用苹果GLKit 提供GLKBaseEffect 完成着色器工作(顶点/片元)
        cEffect = [[GLKBaseEffect alloc]init];
        cEffect.texture2d0.enabled = GL_TRUE;
        cEffect.texture2d0.name = textureInfo.name;
        cEffect.texture2d0.target = textureInfo.target;
        
         [self setTimer];
    }
    
    

    cEffect.texture2d0.target = textureInfo.target;将目标对象交给cEffect;
    [self setTimer]; 开启一个定时器

    • 开始定时器
    
    - (void)setTimer{
        
        NSTimer* timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
            
            [self transforms];
        }];
        [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    }
    - (void)transforms{
        angle = (angle + 10) % 360;
        //使用模型矩阵
        cEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(angle), 0.3, 1, -1.7);
       
       //重新绘制
        [glkView display];
    }
    
    
    • 绘制
    
    #pragma mark -- GLKViewDelegate
    
    - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
    {
        //1.清屏
        glClear(GL_COLOR_BUFFER_BIT);
        
        //2.准备绘制
        [cEffect prepareToDraw];
        
        //3.开始绘制
        glDrawArrays(GL_TRIANGLES, 0, 36);
        
        
    }
    
    

    这里36绘制的定点数.

    效果图:

    image.png

    相关文章

      网友评论

        本文标题:0010--OpenGL ES初探:GLKit 案例实现-旋转立

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