美文网首页
[OpenGL ES] - GLKit绘制与动画

[OpenGL ES] - GLKit绘制与动画

作者: coder_xiaoyu | 来源:发表于2018-05-05 16:29 被阅读0次

    1.配置OpenGL ES 上下文

            // OpenGL ES版本
            var context = EAGLContext.init(api: .openGLES3)
            if context == nil {
                context = EAGLContext.init(api: .openGLES2)
            }
            
            guard let ctx = context else {
                return
            }
            EAGLContext.setCurrent(ctx) // 设置当前上下文
    

    2.配置GLKView

            let view = self.view as! GLKView
            view.context = ctx
            // 32位RGB颜色 (R+G+B+A)
            view.drawableColorFormat = .RGBA8888
            // 深度格式
            view.drawableDepthFormat = .format24
    

    3.准备数据(顶点,着色器,纹理)

            // 1. 顶点数据
            let vertices: [Vertex] = [
                Vertex(Position: (-0.5, 0.5, 0.0), Color: (0.0, 0.0, 0.5, 1.0), TexCoord: (0.0, 1.0)), // 左上0
                Vertex(Position: (0.5, 0.5, 0.0), Color: (0.0, 0.5, 0.0, 1.0), TexCoord: (1.0, 1.0)), // 右上1
                Vertex(Position: (-0.5, -0.5, 0.0), Color: (0.5, 0.0, 1.0, 1.0), TexCoord: (0.0, 0.0)), // 左下2
                Vertex(Position: (0.5, -0.5, 0.0), Color: (0.0, 0.0, 0.5, 1.0), TexCoord: (1.0, 0.0)), // 右下3
    
                Vertex(Position: (0.0, 0.0, 1.0), Color: (1.0, 1.0, 1.0, 1.0), TexCoord: (0.5, 0.5)), // 顶点4
            ]
            // 2. 索引
            let indices:[GLubyte] = [
                0, 3, 2,
                0, 1, 3,
                
                0, 2, 4,
                0, 4, 1,
                2, 3, 4,
                1, 4, 3,
            ]
            // 3.顶点个数
            self.vCount = GLsizei(indices.count)
            
    //        glGenVertexArraysOES(1, &VAO)
    //        glBindVertexArrayOES(VAO)
            // 4.将顶点数组放到缓冲区
            glGenBuffers(GLsizei(1), &buffer)
            glBindBuffer(GLenum(GL_ARRAY_BUFFER), buffer)
            glBufferData(GLenum(GL_ARRAY_BUFFER), vertices.size(), vertices, GLenum(GL_STATIC_DRAW))
            
            // 5.将索引放入缓冲区
            glGenBuffers(GLsizei(1), &index)
            glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), index)
            glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), indices.size(), indices, GLenum(GL_STATIC_DRAW))
            
            // 6.使用顶点数据
            let positionSlotFirstComponent = UnsafePointer<Int>(bitPattern: 0)
            glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
            glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), positionSlotFirstComponent)
            // 7.颜色数据
            let colorSlotFirstComponent = UnsafePointer<Int>(bitPattern: MemoryLayout<GLfloat>.size * 3)
            glEnableVertexAttribArray(GLuint(GLKVertexAttrib.color.rawValue))
            glVertexAttribPointer(GLuint(GLKVertexAttrib.color.rawValue), 4, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), colorSlotFirstComponent)
            // 8.纹理数据
            let texSlotFirstComponent = UnsafePointer<Int>(bitPattern: MemoryLayout<GLfloat>.size * 7)
            glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
            glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<Vertex>.size), texSlotFirstComponent)
            
    //        glBindVertexArrayOES(0)
            // 9.获取纹理数据
            guard let textureInfo = self.loadTexture("cTest.jpg") else { return }
            
            // 10. 效果
            self.effect.texture2d0.enabled = GLboolean(GL_TRUE)
            self.effect.texture2d0.name = textureInfo.name
            
            // 11.透视投影
            let size = self.view.bounds.size
            
            let aspect = fabs(size.width/size.height)
            /*
             参数1:视角
             参数2:屏幕宽高比
             参数3:距离近平面的距离
             参数3:距离近平面的距离
             */
            var projectionMatrix = GLKMatrix4MakePerspective(GLKMathRadiansToDegrees(90), Float(aspect), 0.1, 10.0)
            
            projectionMatrix = GLKMatrix4Scale(projectionMatrix, 1, 1, 1)
            self.effect.transform.projectionMatrix = projectionMatrix
            
            let modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0, 0.0, -2.0)
    //        modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, 0.4)
    //        modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, 0.6)
    //        modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, 0.9)
            self.effect.transform.modelviewMatrix = modelViewMatrix
    

    4.在代理中绘制

    override func glkView(_ view: GLKView, drawIn rect: CGRect) {
            
           // 清除缓冲
            glClearColor(0.0, 0.0, 1.0, 1.0)
            glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
            
            glEnable(GLenum(GL_DEPTH_TEST))
            // 准备绘制
            self.effect.prepareToDraw()
    
    //        glBindVertexArrayOES(VAO)
            // 索引绘制 参数1:图元类型。参数2:顶点个数。参数3:索引值类型。参数4:指向索引数组的指针.
            glDrawElements(GLenum(GL_TRIANGLES), self.vCount, GLenum(GL_UNSIGNED_BYTE), nil)
    
    //        glBindVertexArrayOES(0)
     }
    

    5.GLKViewControllerDelegate代理中更新

      func glkViewControllerUpdate(_ controller: GLKViewController) {
            
            var modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0.0, 0.0, -2.0)
            
            modelViewMatrix = GLKMatrix4RotateX(modelViewMatrix, xDegree)
            modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, yDegree)
            modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, zDegree)
            
            self.effect.transform.modelviewMatrix = modelViewMatrix
        }
    
    update_display_loop

    结尾

    DEMO源码地址

    相关文章

      网友评论

          本文标题:[OpenGL ES] - GLKit绘制与动画

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