标签:
顶点数据,也称为顶点属性,指每一个顶点数据。指能被用来描述每个顶点的数据,或能被所有顶点使用的常量值。例如你想绘制一个具有颜色的立方体三角形。你指定一个恒定的值用于三角形的所有三个顶点颜色。但三角形的三个顶点位置是不同的,你需要指定一个顶点矩阵存储三个位置值。
指定顶点属性数据
顶点属性数据可以使用顶点数组或常量值指定每个顶点数据,OpenGL ES 3.0 必须至少支持16 个顶点属性。应用应该能够查询编译器支持的确切属性数。下面的程序指出如何查询。
GLint maxVertexAttribs; // n will be >= 8 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
常量顶点属性
常量顶点属性是指基元的所有顶点属性是相同的,因此仅仅对基元的所有顶点仅仅需要指定一个值。顶点属性常量使用下面的函数指定:
void glVertexAttriblf(GLuint index, GLfloat x); void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y); void glVertexAttrib3f( GLuint index, GLfloat x, GLfloat y, GLfloat z); void glVertexAttrib4f( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void glVertexAttriblfv(GLuint index, const GLfloat *values); void glVertexAttrib2fv(GLuint index, const GLfloat *values); void glVertexAttrib3fv(GLuint index, const GLfloat *values); void glVertexAttrib4fv(GLuint index, const GLfloat *values);
glVertexAttrib*通过索引来装在一般顶点属性,glVertexAttriblf和glVertexAttriblfv加载(x, 0.0, 0.0, 1.0)到顶点属性,glVertexAttrib2f and glVertexAttrib2fv 装载(x, y, 0.0, 1.0),glVertexAttrib3f 和glVertexAttrib3fv 装载(x, y, z, 1.0),glVertexAttrib4f and
glVertexAttrib4fv 装载(x, y, z, w)
顶点数组
顶点数组指定每个顶点的属性数据即存储在应用程序地址空间(OpenGL ES 叫clientspace)缓冲区的数据。它们提供有效的和灵活的方法指定顶点属性数据。顶点数组使用glVertexAttribPointer 或glVertexAttribIPointer函数指定:
存储所有的顶点属性在一个缓冲区中,这种存储顶点属性的方法叫结构数组,这种方法描述每个顶点的所有属性。存储每个顶点属性到分开的缓冲区,这种存储顶点属性的方法叫数组结构每个顶点有四个属性—位置、法线、两个贴图坐标,这些属性被存储在一个缓冲区中,被所有顶点分享。顶点位置属性是三个浮点数(x, y, z)的矢量。法线也是三个浮点数的矢量,每个贴图坐标是两个浮点数的矢量。
结构数组代码示例
#define VERTEX_POS_SIZE 3 // x, y, and z #define VERTEX_NORMAL_SIZE 3 // x, y, and z #define VERTEX_TEXCOORD0_SIZE 2 // s and t #define VERTEX_TEXCOORDl_SIZE 2 // s and t #define VERTEX_POS_INDX 0 #define VERTEX_NORMAL_INDX 1 #define VERTEX_TEXCOORD0_INDX 2 #define VERTEX_TEXCOORDl_INDX 3 // the following 4 defines are used to determine the locations // of various attributes if vertex data are stored as an array // of structures #define VERTEX_POS_OFFSET 0 #define VERTEX_NORMAL_OFFSET 3 #define VERTEX_TEXCOORD0_OFFSET 6 #define VERTEX_TEXC00RD1_0FFSET 8 #define VERTEX_ATTRIB_SIZE (VERTEX_POS_SIZE + \ VERTEX_NORMAL_SIZE + VERTEX_TEXCOORD0_SIZE + VERTEX_TEXC00RD1_SIZE)
float *p = (float*) malloc(numVertices * VERTEX_ATTRIB_SIZE * sizeof(float)); // position is vertex attribute 0 glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, VERTEX_ATTRIB_SIZE * sizeof(float), p); // normal is vertex attribute 1 glVertexAttribPointer(VERTEX_NORMAL_INDX, VERTEX_NORMAL_SIZE, GL_FLOAT, GL_FALSE, VERTEX_ATTRIB_SIZE * sizeof(float), (p + VERTEX_NORMAL_OFFSET)); // texture coordinate 0 is vertex attribute 2 glVertexAttribPointer(VERTEX_TEXCOORDO_INDX, VERTEX_TEXCOORD0_SIZE, GL_FLOAT, GL_FALSE, VERTEX_ATTRIB_SIZE * sizeof(float), (p + VERTEX_TEXCOORD0_OFFSET)); // texture coordinate 1 is vertex attribute 3 glVertexAttribPointer(VERTEX_TEXCOORDl_INDX, VERTEX_TEXC00RD1_SIZE, GL_FLOAT, GL_FALSE, VERTEX_ATTRIB_SIZE * sizeof(float), (p + VERTEX_TEXC00RD1_0FFSET));
数组结构示例代码
float *position = (float*) malloc(numVertices * VERTEX_POS_SIZE * sizeof(float)); float *normal = (float*) malloc(numVertices * VERTEX_NORMAL_SIZE * sizeof(float)); float *texcoordO = (float*) malloc(numVertices * VERTEX_TEXCOORD0_SIZE * sizeof(float)); float *texcoordl = (float*) malloc(numVertices * VERTEX_TEXC00RD1_SIZE * sizeof(float)); // position is vertex attribute 0 glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, VERTEX_POS_SIZE * sizeof(float), position); // normal is vertex attribute 1 glVertexAttribPointer(VERTEX_NORMAL_INDX, VERTEX_NORMAL_SIZE, GL_FLOAT, GL_FALSE, VERTEX_NORMAL_SIZE * sizeof(float), normal); // texture coordinate 0 is vertex attribute 2 glVertexAttribPointer(VERTEX_TEXCOORDO_INDX, VERTEX_TEXCOORD0_SIZE, GL_FLOAT, GL_FALSE, VERTEX_TEXCOORD0_SIZE * sizeof(float), texcoordO); // texture coordinate 1 is vertex attribute 3 glVertexAttribPointer(VERTEX_TEXCOORDl_INDX, VERTEX_TEXC00RD1_SIZE, GL_FLOAT, GL_FALSE, VERTEX_TEXC00RD1_SIZE * sizeof(float), texcoordl);
性能提示
1.如何存储不同的顶点属性。
使用结构数组要比使用数组结构性能更有优,原因是每个顶点的属性数据能够被连续的读出,这种内存结构更有效。但使用array of structures 不好的是当我们想去修改指定的属性时。如果一个顶点属性需要被修改(像贴图坐标),这将必须更新顶点缓冲区。当顶点缓冲区作为缓冲区对象时,整个
顶点属性缓冲区将需要更新加载,
2.顶点属性使用哪种数据格式
顶点属性数据格式 通过调用glVertexAttribPointer 函数的参数type指定,这样做不但影响顶点属性的绘图数据的存储要求,也影响全部的执行工作,它是渲染帧时的内存带宽的要求。数据量越小,对带宽要求越低。OpenGL ES 3支持16位浮点顶点格式命名gl_half_float,建议尽量使用gl_half_float,Texture coordinates, normals, binormals, tangent vectors都适合使用gl_half_float来存储,颜色使用四个GL_UNSIGNED_BYTE来存储每个顶点颜色,顶点位置应该存储为GL_FLOAT。
3.如何标准化glVertexAttribPointer 工作
顶点属性在被顶点着色器使用前,作为单一精度的浮点值被存储在内存中。如果顶点属性的数据类型不是浮点数,那么它们的值将在着色器使用前转变为浮点值。normalized标志指示非浮点顶点属性数据转化为单一精度的浮点值。如果normalized符为false,顶点数值被直接转化为浮点值,转化非浮点变量为浮点类型是相似的
GLfloat f; GLbyte b; f = (GLfloat)b; // f represents values in the range [-128.0, // 127.0]
如果normalized为true,顶点数据类型如果是GL_BYTE, GL_SHORT 或 GL_FIXED 被匹配到[-1.0,1.0],数据类型如果是GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT 被匹配到[0.0,1.0]。下面描述非浮点值数据类型normalized转换过程
也有可能访问整数顶点属性数据为整数的顶点着色器,而不将它们转换为浮点数。在这种情况下,glvertexattribipointer功能应使用顶点属性应该被声明为一个整数类型的顶点着色。
4.在常量顶点属性和顶点数组之间选择
int Init ( ESContext *esContext ) { UserData *userData = (UserData*) esContext->userData; 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" "}" ; 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 ); }
OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)
标签:
原文地址:http://www.cnblogs.com/salam/p/4941282.html