在OpenGL ES中指定顶点数据可以使用一个顶点数组对每个顶点指定,例如顶点位置信息 ,也可以将一个常量值用于一个图元的所有顶点,例如图元的颜色。
即常量顶点属性和顶点数组。
常量顶点属性
我们使用glVertexAttrib*命令来加载 index 指定的通用顶点属性。
顶点数组
顶点数组指定每个顶点的属性,是保存在应用程序地址空间的缓冲区。使用 glVertexAttribPointer 和 glVertexAttribIPointer 来指定。
分配和存储顶点数据有两种常用的方法,结构数组和数组结构。
结构数组:在一个缓冲区中,把每个顶点的多种属性作为一个结构,多个结构以数组的形式存储在缓冲区中。
数组结构:把多个顶点的每种顶点属性提取出来,不同的顶点属性分开存储在不同顶点属性的缓冲区中,然后组成一个结构。
用一张简图来表示结构数组和数组结构的区别:
下面在代码中来观察结构数组和数组结构的不同使用表现:
结构数组
#define VERTEX_POS_SIZE 3 //x,y,z
#define VERTEX_NORMAL_SIZE 3 //x,y,z
#define VERTEX_TEXCOORD0_SIZE 2 //s and t
#define VERTEX_TEXCOORD1_SIZE 2 //s and t
#define VERTEX_POS_INDEX 0
#define VERTEX_NORMAL_INDEX 1
#define VERTEX_TEXCOORD0_INDEX 2
#define VERTEX_TEXCOORD1_INDEX 3
#define VERTEX_POS_OFFSET 0
#define VERTEX_NORMAL_OFFSET 3
#define VERTEX_TEXCOORD0_OFFSET 6
#define VERTEX_TEXCOORD1_OFFSET 8
#define VERTEX_ATTRIBUTE_SIZE (VERTEX_POS_OFFSET+VERTEX_NORMAL_OFFSET+VERTEX_TEXCOORD0_OFFSET+VERTEX_TEXCOORD1_OFFSET)
//假设有1000个Vertex;
int numVertices=1000;
float* p=(float*)malloc(numVertices*VERTEX_ATTRIBUTE_SIZE*sizeof(float));
//设置顶点位置属性;
glVertexAttribPointer(VERTEX_POS_INDEX,VERTEX_POS_SIZE,GL_FLOAT,GL_FALSE,VERTEX_ATTRIBUTE_SIZE*sizeof(float),p);
//设置顶点法线属性;
glVertexAttribPointer(VERTEX_NORMAL_INDEX,VERTEX_NORMAL_SIZE,GL_FLOAT,GL_FALSE,VERTEX_ATTRIBUTE_SIZE*sizeof(float),p+VERTEX_NORMAL_OFFSET);
//设置TexCoord0;
glVertexAttribPointer(VERTEX_TEXCOORD0_INDEX,VERTEX_TEXCOORD0_SIZE,GL_FLOAT,GL_FALSE,VERTEX_ATTRIBUTE_SIZE*sizeof(float),p+VERTEX_TEXCOORD0_OFFSET);
//设置TexCoord1;
glVertexAttribPointer(VERTEX_TEXCOORD1_INDEX,VERTEX_TEXCOORD1_SIZE,GL_FLOAT,GL_FALSE,VERTEX_ATTRIBUTE_SIZE*sizeof(float),p+VERTEX_TEXCOORD1_OFFSET);
数组结构:
#define VERTEX_POS_SIZE 3 //x,y,z
#define VERTEX_NORMAL_SIZE 3 //x,y,z
#define VERTEX_TEXCOORD0_SIZE 2 //s and t
#define VERTEX_TEXCOORD1_SIZE 2 //s and t
#define VERTEX_POS_INDEX 0
#define VERTEX_NORMAL_INDEX 1
#define VERTEX_TEXCOORD0_INDEX 2
#define VERTEX_TEXCOORD1_INDEX 3
#define VERTEX_POS_OFFSET 0
#define VERTEX_NORMAL_OFFSET 3
#define VERTEX_TEXCOORD0_OFFSET 6
#define VERTEX_TEXCOORD1_OFFSET 8
#define VERTEX_ATTRIBUTE_SIZE (VERTEX_POS_OFFSET+VERTEX_NORMAL_OFFSET+VERTEX_TEXCOORD0_OFFSET+VERTEX_TEXCOORD1_OFFSET)
//假设有1000个Vertex;
int numVertices=1000;
/********* 数组结构 Start ******/
float* position=(float*)malloc(numVertices*VERTEX_POS_SIZE*sizeof(float));
float* normal=(float*)malloc(numVertices*VERTEX_NORMAL_SIZE*sizeof(float));
float* texcoord0=(float*)malloc(numVertices*VERTEX_TEXCOORD0_SIZE*sizeof(float));
float* texcoord1=(float*)malloc(numVertices*VERTEX_TEXCOORD1_SIZE*sizeof(float));
glVertexAttribPointer(VERTEX_POS_INDEX,VERTEX_POS_SIZE,GL_FLOAT,GL_FALSE,VERTEX_POS_SIZE*sizeof(float),position);
glVertexAttribPointer(VERTEX_NORMAL_INDEX,VERTEX_NORMAL_SIZE,GL_FLOAT,GL_FALSE,VERTEX_NORMAL_SIZE*sizeof(float),normal);
glVertexAttribPointer(VERTEX_TEXCOORD0_INDEX,VERTEX_TEXCOORD0_SIZE,GL_FLOAT,GL_FALSE,VERTEX_TEXCOORD0_SIZE*sizeof(float),texcoord0);
glVertexAttribPointer(VERTEX_TEXCOORD1_INDEX,VERTEX_TEXCOORD1_SIZE,GL_FLOAT,GL_FALSE,VERTEX_TEXCOORD1_SIZE*sizeof(float),texcoord1);
/********* 数组结构 End ******/
因为在结构数组中,每个定点的属性数据可以顺序方式读取,所以在 大部分情况下,使用结构数组更高效。