glVertexAttribPointer()的stride参数

被glVertexAttribPointer()的stride参数坑过好几次了,每次用都会感觉好像用错了,看来不记下来是不行了!

官方文档

先来看一下官方文档

Name

1
glVertexAttribPointer — define an array of generic vertex attribute data

C Specification

1
2
3
4
5
6
7
void glVertexAttribPointer(
GLuint index,
GLint size,
GLenum type,
GLboolean normalized,
GLsizei stride,
const GLvoid * pointer);

Parameters

index
1
Specifies the index of the generic vertex attribute to be modified.
size
1
Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, or 4. The initial value is 4.
type
1
Specifies the data type of each component in the array. Symbolic constants GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, or GL_FLOAT are accepted. The initial value is GL_FLOAT.
normalized
1
Specifies whether fixed-point data values should be normalized (GL_TRUE) or converted directly as fixed-point values (GL_FALSE) when they are accessed.
stride
1
Specifies the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array. The initial value is 0.
pointer
1
Specifies a pointer to the first component of the first generic vertex attribute in the array. The initial value is 0.

stride参数

首先,stride参数类型为byte,其值表示相邻顶点属性之间步幅的字节数,每次读取size个数据,如果为0则表示数据是紧密排列的。stride是相对于一组属性来说的,而不是对于属性的每一个成分来说的。以位置属性为例,有x、y、z三个成分,将x、y、z看做一组,stride是每一组之间的步幅。

举个例子,有一些顶点数据:

1
2
3
4
5
6
7
8
static const GLfloat vertex_buffer_data[] = { 
-1.0f,-1.0f, 0.0f, // vertex 1
1.0f,-1.0f, 0.0f, // vertex 2
1.0f,-0.5f, 0.0f, // vertex 3
1.0f, 1.0f, 0.0f, // vertex 4
-1.0f, 1.0f, 0.0f, // vertex 5
-1.0f, 0.5f, 0.0f, // vertex 6
};

然后传入buffer中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GLuint vertex_buffer;
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(
0, // index, attribute 0
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized
0, // stride
(void*)0 // pointer, array buffer offset
);

这里stride为0表示数据是紧密排列的,其实把0改为12效果是相同的,因为3个float表示一个顶点的位置属性,3个float就是12个byte,来看一下结果:
1

现在把stride改为24,这样一来,两个属性之间步幅为24byte,也就是6个float,从顶点数据来看,第一个选择的顶点是vertex 1,第二个选择的顶点是vertex 3,第三个选择的顶点是vertex 5,来看一下结果:
2