码迷,mamicode.com
首页 > 其他好文 > 详细

OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)

时间:2015-11-06 06:45:02      阅读:425      评论:0      收藏:0      [点我收藏+]

标签:

  顶点数据,也称为顶点属性,指每一个顶点数据。指能被用来描述每个顶点的数据,或能被所有顶点使用的常量值。例如你想绘制一个具有颜色的立方体三角形。你指定一个恒定的值用于三角形的所有三个顶点颜色。但三角形的三个顶点位置是不同的,你需要指定一个顶点矩阵存储三个位置值。

指定顶点属性数据

  顶点属性数据可以使用顶点数组或常量值指定每个顶点数据,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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!