OpenGL ES (Swift) Dev 2

作者: YxxxHao | 来源:发表于2016-07-07 17:08 被阅读367次

    上一节OpenGL的HelloWorld中,初步认识OpenGL,接着将对上节内容的中EAGLContext和GLKVertexAttribArrayBuffer进行封装,利用封装的函数减少应用需要调用OpenSE函数的数量,这同时也是减少缓存管理中的7个步骤相关的错误和代码的数量:

    7个步骤:

    1. 生成(Generate)
    2. 绑定(Bind)
    3. 缓存数据(Buffer Data)
    4. 启用(Enable)或者禁用(Disable)
    5. 设置指针(Set Pointers)
    6. 绘图(Draw)
    7. 删除(Delete)

    EAGLContext的封装类AGLKContext

    这个相信不用注释一样能看得懂了~~~~

    class AGLKContext: EAGLContext {
        
        var clearColor: GLKVector4 {
            set {
                self.clearColor = newValue
                glClearColor(
                    newValue.r,
                    newValue.g,
                    newValue.b,
                    newValue.a);
            }
            get {
                return self.clearColor
            }
        }
        func clear(mask: GLbitfield) {
            glClear(mask);
        }
        func disable(capability: GLenum) {
            glDisable(capability);
        }
        func enable(capability: GLenum) {
            glEnable(capability);
        }
        func setBlendSourceFunction (sfactor: GLenum, dfactor: GLenum) {
            glBlendFunc(sfactor, dfactor);
        }
    }
    

    GLKVertexAttribArrayBuffer的封装类AGLKVertexAttribArrayBuffer

    以下代码每一步都有相应的注释~~~~主要还是要考虑到代码的重用才进行封装。

    enum AGLKVertexAttrib: GLuint {
        case AGLKVertexAttribPosition = 0
        case AGLKVertexAttribNormal = 1
        case AGLKVertexAttribColor = 2
        case AGLKVertexAttribTexCoord0 = 3
        case AGLKVertexAttribTexCoord1 = 4
    }
    
    //封装顶点数组缓存
    class AGLKVertexAttribArrayBuffer: NSObject {
        //步幅,表示每个顶点需要多少个字节
        var stride = GLsizei()
        //缓存大小
        var bufferSizeBytes = GLsizeiptr()
        //缓存唯一标识
        var bufferId = GLuint()
        
        
        
        /**
         创建顶点数组缓存
         
         - parameter stride:           步幅
         - parameter numberOfVertices: Vertices大小
         - parameter bytes:            Vertices内存地址
         - parameter usage:            是否缓存在GPU
         
         */
        func initWithAttribStride(stride: GLsizei, numberOfVertices: GLsizei, dataPtr: UnsafePointer<Void>, usage: GLenum) {
            self.stride = stride
            bufferSizeBytes = Int(stride) * Int(numberOfVertices);
            
            glGenBuffers(1, &bufferId)
            glBindBuffer(GLenum(GL_ARRAY_BUFFER), self.bufferId)
            glBufferData(
                GLenum(GL_ARRAY_BUFFER),
                bufferSizeBytes,
                dataPtr,
                usage
            )
        }
        
        //重新加载缓存数据
        func reinitWithAttribStride(stride: GLsizei, numberOfVertices:GLsizei, dataPtr:  UnsafePointer<Void>) {
            self.stride = stride;
            bufferSizeBytes = Int(stride) * Int(numberOfVertices);
            
            glBindBuffer(GLenum(GL_ARRAY_BUFFER),
                         self.bufferId);
            glBufferData(
                GLenum(GL_ARRAY_BUFFER),
                bufferSizeBytes,
                dataPtr,
                GLenum(GL_DYNAMIC_DRAW)
            );
        }
        
        /**
         Description
         
         - parameter index:               VertexAttrib
         - parameter numberOfCoordinates: 坐标轴数
         - parameter attribOffset:        从开始的每个顶点偏移
         - parameter shouldEnable:        启用(Enable)或者禁用(Disable)
         */
        func prepareToDrawWithAttrib(vertexAttrib: GLuint, numberOfCoordinates: GLint, attribOffset: GLsizeiptr, shouldEnable: Bool) {
        
            glBindBuffer(GLenum(GL_ARRAY_BUFFER), self.bufferId);
            
            if(shouldEnable)
            {
                glEnableVertexAttribArray(vertexAttrib)
            }
            
            glVertexAttribPointer(         
                vertexAttrib,
                numberOfCoordinates,                // 坐标轴数
                GLenum(GL_FLOAT),                   // 数据类型
                GLboolean(UInt8(GL_FALSE)),
                self.stride,
                nil + attribOffset);                // 从开始的每个顶点偏移
        }
        
        //绘制图片
        func drawArrayWithMode(mode:GLenum, startVertexIndex: GLint, numberOfVertices: GLsizei) {
            glDrawArrays(mode, startVertexIndex, numberOfVertices);
        }
        
        //删除缓存
        deinit {
            if 0 != bufferId {
                glDeleteBuffers (1, &bufferId);
                bufferId = 0;
            }
        }
        
    }
    

    接口调用例子

    self.vertextBuffer.initWithAttribStride(
            GLsizei(sizeofValue(vertices[0])),
            numberOfVertices: GLsizei(vertices.count),
            dataPtr: vertices,
            usage:GLenum(GL_STATIC_DRAW)
        )
    self.vertextBuffer.prepareToDrawWithAttrib(
        AGLKVertexAttrib.AGLKVertexAttribPosition.rawValue,
        numberOfCoordinates: 3,
        attribOffset:0,
        shouldEnable: true
    )
    self.vertextBuffer.drawArrayWithMode(
        GLenum(GL_TRIANGLE_FAN),
        startVertexIndex: 0,
        numberOfVertices:
        GLsizei(vertices.count)
    )
    

    详细的的调用例子请参看源码。
    源码点这里,喜欢就关注吧,持续更新中。

    相关文章

      网友评论

        本文标题:OpenGL ES (Swift) Dev 2

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