美文网首页
(六)顶点属性、顶点数组和缓冲区对象

(六)顶点属性、顶点数组和缓冲区对象

作者: YongtaoHuang | 来源:发表于2019-10-14 09:12 被阅读0次

    顶点数据也称作顶点属性,指定每个顶点的数据。

    指定顶点数据属性

    顶点属性数据可用一个顶点数组对每个顶点指定,也可将一个常量值用于一个图元的所有顶点。
    所有OpenGL ES 3.0实现必须支持最少16个顶点属性。

    可以通过glGetIntegerv函数查询特定实现支持的顶点属性的准确数量。

    GLint maxVertexAttribs; // n will be >= 16
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
    

    常量顶点属性

    常量顶点属性对于一个图元的所有顶点都相同,所以对一个图元的所有顶点只需指定一个值。

    void glVertexAttrib4fv(GLuint index, const GLfloat *values);
    

    glVertexAttrib*函数用于加载index指定的通用顶点属性。glVertexAttrib4fv在通用顶点属性种加载(x, y, z, w)。

    顶点数组

    顶点数组指定每个顶点的属性,是保存在应用程序地址空间的缓冲区。顶点数组用

    void glVertexAttribPointer(GLuint index, 
        GLint size,
        GLenum type,
        GLboolean normalized,
        GLsizei stride,
        const void *ptr)
    // ===============================
    void glVertexAttribIPointer(GLuint index, 
        GLint size,
        GLenum type,
        GLsizei stride,
        const void *ptr)
    

    这两个函数指定。

    两种最常用的顶点属性存储方法:结构数组和数组结构。

    结构数组

    数组结构

    三角形示例

        const char vShaderStr[] =
            "#version 300 es \n"
            "layout(location = 0) in vec4 a_color; \n"
            "layout(location = 1) in vec4 a_position; \n"
            "out vec4 v_color; \n"
            "void main() \n"
            "{ \n"
            " v_color = a_color; \n"
            " gl_Position = a_position; \n"
            "}";
        const char fShaderStr[] =
            "#version 300 es \n"
            "precision mediump float; \n"
            "in vec4 v_color; \n"
            "out vec4 o_fragColor; \n"
            "void main() \n"
            "{ \n"
            " o_fragColor = v_color; \n"
            "}" ;
    
    int Init ( ESContext *esContext ) {
        UserData *userData = (UserData*) esContext->userData;
        const char vShaderStr[] = "...";
        const char fShaderStr[] = "..."; // 如上
        GLuint programObject;
        // Create the program object
        programObject = esLoadProgram ( vShaderStr, fShaderStr );
        if ( programObject == 0 )
            return GL_FALSE;
        // Store the program object
        userData->programObject = programObject;
        glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
        return GL_TRUE;
    }
    void Draw ( ESContext *esContext ){
        UserData *userData = (UserData*) esContext->userData;
        GLfloat color[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
        // 3 vertices, with (x, y, z) per-vertex
        GLfloat vertexPos[3 * 3] = {
            0.0f, 0.5f, 0.0f, // v0
            -0.5f, -0.5f, 0.0f, // v1
            0.5f, -0.5f, 0.0f // v2
        };
        glViewport ( 0, 0, esContext->width, esContext->height );
        glClear ( GL_COLOR_BUFFER_BIT );
        glUseProgram ( userData->programObject );
    // =============
        glVertexAttrib4fv ( 0, color );
        glVertexAttribPointer ( 1, 3, GL_FLOAT, GL_FALSE, 0, vertexPos );
        glEnableVertexAttribArray ( 1 );
        glDrawArrays ( GL_TRIANGLES, 0, 3 );
        glDisableVertexAttribArray ( 1 );
    }   
    

    上述例子描述如何绘制一个三角形,该三角形的一个顶点属性是常量,其他属性用顶点数组组成。

    顶点属性color是一个常量,用glVertexAttrib4fv指定,不启用顶点属性数组0。
    vertexPos属性用glVertexAttribPointer 以一个顶点数组指定,并用glEnableVertexAttribArray启用数组。Color值对于所绘制的三角形的所有顶点均相同,而vertexPox属性对于三角形的各个顶点可以不同。

    在顶点着色器中声明顶点属性变量

    顶点缓冲区对象

    顶点数组对象

    映射缓冲区对象

    复制缓冲区对象

    小结

    相关文章

      网友评论

          本文标题:(六)顶点属性、顶点数组和缓冲区对象

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