opengl – 什么时候应该调用glVertexAttribPointer?

当应该调用glVertexAttribPointer时,文档不太明显。它似乎是VBO初始化的一部分,但我注意到在渲染过程中调用它的示例代码。

glVertexAttribPointer(vertexAttributeId,2,GL_FLOAT,GL_FALSE,sizeof(Vertex2D),reinterpret_cast< const GLvoid *>(offsetof(Vertex2D,m_x)));

在GL_ARRAY_BUFFER初始化期间应该调用glVertexAttribPointer,还是应该在渲染过程中调用(在调用glBindBuffer之后)?

函数glVertexAttribPointer指定渲染某些东西(即下一个glDraw …调用)时使用的顶点属性的格式和源缓冲区(忽略客户端数组的不推荐使用)。

现在有两种情况。您可以使用顶点数组对象(VAO),也可以不使用(尽管不使用VAO在现代OpenGL中已被弃用,不鼓励/禁止)。如果你不使用VAO,那么通常会在渲染之前调用glVertexAttribPointer(和相应的glEnableVertexAttribArray)来正确设置状态。如果使用VAO,您实际上会在VAO创建代码(通常是初始化或对象创建的一部分)内调用它(和启用函数),因为它的设置存储在VAO中,并且渲染时需要做的绑定VAO并调用绘图功能。

但是无论何时调用glVertexAttribPointer,都应该在之前绑定相应的缓冲区(无论何时实际创建和填充),因为glVertexAttribPointer函数将当前绑定的GL_ARRAY_BUFFER设置为此属性的源缓冲区(并存储此设置,因此之后你可以自由绑定另一个VBO)。

所以在使用VAO(推荐使用)的现代OpenGL中,通常类似于这个工作流程:

//initialization
glGenVertexArrays
glBindVertexArray

glGenBuffers
glBindBuffer
glBufferData

glVertexAttribPointer
glEnableVertexAttribArray

glBindVertexArray(0)

glDeleteBuffers //you can already delete it after the VAO is unbound, since the
                //VAO still references it, keeping it alive (see comments below).

...

//rendering
glBindVertexArray
glDrawWhatever

当不使用VAO时,会是这样的:

//initialization
glGenBuffers
glBindBuffer
glBufferData

...

//rendering
glBindBuffer
glVertexAttribPointer
glEnableVertexAttribArray
glDrawWhatever
http://stackoverflow.com/questions/17149728/when-should-glvertexattribpointer-be-called

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:opengl – 什么时候应该调用glVertexAttribPointer?