我们首先明确一点,顶点(Vertex)不单单指位置,它还包含纹理位置,法线等属性。顶点的位置坐标仅仅是顶点的一个属性。
在中
OpenGL中的顶点缓冲区(Vertex Buffer)
我们已经探究了如何利用顶点缓冲区向GPU传递数据用来绘制图形,但GPU并不知道这些数据代表什么,如何利用这些数据。它只知道这些是数据,因此我们需要设置顶点属性,告诉GPU “嗨,这一部分数据代表顶点的位置信息,那一块数据是纹理坐标…”。而OpenGL给我们提供了具有这样功能的API——glVertexAttribPointer()。
参数:i
index:指定属性的索引。顶点有很多属性,我们需要对这些属性进行编号索引。比如我们将位置信息的索引设置为1,也就是让位置为第一个属性。
size: 指定每个通用顶点属性的组件数。必须是 1、2、3、4。
type: 指定数组中每个组件的数据类型。
normalized: 对于 glVertexAttribPointer,指定在访问定点数据值时是否应归一化(GL_TRUE) 或直接转换为定点值 (GL_FALSE)。
stride: 指定连续通用顶点属性之间的
字节
偏移量。如果 stride 为 0,则通用顶点属性被理解为紧密封装在数组中。初始值为 0。
pointer: 表示我们的位置数据在缓冲区起始位置的偏移量。这个值受到VBO的影响;1:在不使用VBO的情况下,就是一个指针,指向的是需要上传到顶点数据指针,项目中通常在不使用VBO的情况下,绘制之前,执行glBindBuffer(GL_ARRAY_BUFFER, 0),否则会导致数组顶点无效,界面无法显示;2:使用VBO的情况下,先要执行glBindBuffer(GL_ARRAY_BUFFER, 1),如果一个名称非零的缓冲对象被绑定至GL_ARRAY_BUFFER目标且此时一个定点属性数组被指定了,那么pointer被当做该缓冲对象数据存储区的字节偏移量。并且,缓冲对象绑定(GL_ARRAY_BUFFER_BINDING)会被存为索引为index的顶点属性数组客户端状态;此时指针指向的就不是具体的数据了。因为数据已经缓存在缓冲区了。这里的指针表示位置数据在缓冲中起始位置的偏移量(Offset)。
接下来我们来看一下如何使用这个函数。
我们先定义一个数组,这个数组每一行的数据包含了顶点的位置和颜色
float vertices[] = {
// positions // colors
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top
};
然后我们调用这个函数,告诉OpenGL,哪些数据是一组属性.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
//设置位置信息。把位置信息作为第一个属性,所以第一个参数为0;每个位置信息包含三个参数,
//所以size为3; 数据类型为float类型,所以type参数为GL_FLOAT;
//每组数据顶点大小是3个float类型的大小;偏移量为0.
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(3 * sizeof(float)));
最后别忘记启用设置好的属性
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
OpenGL小白,如有错误,请指出:)😜