好的,glVertexAttribPointer函数是用来设置顶点属性指针的,它的原型如下:
```
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
```
参数的含义如下:
- `index`:指定要设置的顶点属性的索引。这个索引对应着顶点着色器中的attribute变量的位置,它是一个非负整数。
- `size`:指定每个顶点属性的分量数。它的值可以是1、2、3或4,表示顶点属性是一个标量、向量、矩阵等。
- `type`:指定顶点属性的数据类型。它的值可以是GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_HALF_FLOAT、GL_FLOAT、GL_DOUBLE、GL_FIXED等。
- `normalized`:指定顶点属性是否需要被标准化。它的值可以是GL_TRUE或GL_FALSE。如果设置为GL_TRUE,则OpenGL会将所有的顶点属性都标准化到[-1, 1]或[0, 1]的范围内;如果设置为GL_FALSE,则不进行标准化处理。
- `stride`:指定连续的顶点属性之间的字节跨度。这个参数的值通常是sizeof(Vertex)或sizeof(GLfloat)*3,表示相邻顶点之间的属性在顶点缓冲区中的偏移量。
- `pointer`:指定顶点缓冲区中顶点属性的起始位置。这个参数的值通常是0或者(void*)offsetof(Vertex, position),表示顶点属性在顶点缓冲区中的偏移量。
下面是一个使用glVertexAttribPointer函数设置顶点属性指针的例子:
```
struct Vertex {
vec3 position;
vec3 normal;
vec2 texcoord;
};
Vertex vertices[] = {
{vec3(-1.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f), vec2(0.0f, 0.0f)},
{vec3(1.0f, -1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f), vec2(1.0f, 0.0f)},
{vec3(1.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f), vec2(1.0f, 1.0f)},
{vec3(-1.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f), vec2(0.0f, 1.0f)}
};
GLuint vbo, vao;
// 创建顶点缓冲对象
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 创建顶点数组对象
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(2);
```
在这个例子中,我们先创建了一个包含顶点位置、法向量和纹理坐标的结构体Vertex,并把顶点数据存储在一个顶点数组vertices中。然后我们创建了一个顶点缓冲对象vbo,并把顶点数据传递给OpenGL。
接着,我们创建了一个顶点数组对象vao,并绑定它。在这个顶点数组对象中,我们使用glVertexAttribPointer函数来设置三个顶点属性指针。第一个参数表示顶点属性的索引,这里分别是0、1、2。第二个参数表示顶点属性的分量数,分别是3、3、2。第三个参数表示顶点属性的数据类型,这里都是GL_FLOAT。第四个参数表示顶点属性是否需要被标准化,这里都是GL_FALSE。第五个参数表示连续的顶点属性之间的字节跨度,这里都是sizeof(Vertex)。最后一个参数表示顶点缓冲区中顶点属性的起始位置,这里使用了offsetof宏来计算偏移量,以确保每个顶点属性在顶点缓冲区中的位置都是正确的。在设置完顶点属性指针后,我们需要通过glEnableVertexAttribArray函数来启用这些顶点属性。