在应该调用glVertexAttribPointer
时,文档中并不明显。看起来它是VBO初始化的一部分,但我注意到在渲染过程中调用它的示例代码。
glVertexAttribPointer(vertexAttributeId, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), reinterpret_cast<const GLvoid*>(offsetof(Vertex2D, m_x)));
在glVertexAttribPointer
初始化期间应该调用GL_ARRAY_BUFFER
还是在渲染期间(调用glBindBuffer
之后)调用它?
答案 0 :(得分:47)
函数glVertexAttribPointer
指定在呈现某些内容时使用的顶点属性的格式和源缓冲区(忽略客户端数组的弃用用法)(即下一个glDraw...
调用)。
现在有两种情况。您可以使用顶点数组对象(VAO),也可以不使用(虽然不使用VAO,但现代OpenGL中不鼓励/禁止使用VAO)。如果您不使用VAO,那么您通常会在呈现正确设置状态之前调用glVertexAttribPointer
(以及相应的glEnableVertexAttribArray
)。如果使用VAO,你实际上在VAO创建代码中调用它(和启用函数)(这通常是一些初始化或对象创建的一部分),因为它的设置存储在VAO中,并且在渲染时你需要做的就是绑定VAO并调用绘制函数。
但无论何时调用glVertexAttribPointer
,都应该在之前绑定相应的缓冲区(无论何时实际创建和填充),因为glVertexAttribPointer
函数设置当前绑定的{{1}作为此属性的源缓冲区(并存储此设置,因此之后您可以自由绑定另一个VBO)。
所以在使用VAO的现代OpenGL中(推荐),它通常与此工作流程类似:
GL_ARRAY_BUFFER
当不使用VAO时,它会是这样的:
//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
答案 1 :(得分:4)
glVertexAttribPointer
不属于缓冲区,也不属于程序 - 就是说 - glue 他们之间。 (其功能在Opengl 4.3中分为不同的功能VertexAttrib*Format
,VertexAttribBinding
和BindVertexBuffer
可通过ARB_vertex_attrib_binding提供
但是如果你想说它是某些东西的一部分我会说它是VAO
的一部分,它存储了哪些Buffer对象被绑定的状态,哪些attribs被启用以及Buffer数据如何被被传递给程序。
因此它属于您设置VAO
的部分。
修改强> 简单的设置说明了顺序:
Buffer
并创建程序VAO
定义哪些attribs已启用,哪些缓冲区应在使用VAO
时绑定,以及该数据如何传递给程序(glVertexAttribPointer
)答案 2 :(得分:2)
缓冲区,通用顶点属性和着色器属性变量的关联非常微妙。 glVertexAttribPointer
建立了这种关联。有关详细说明,请参阅OpenGL-Terminology。
此外,链接OpenGL-VBO,shader,VAO显示了一个包含必要的API调用序列的工作示例。
答案 3 :(得分:1)
glVertexAttribPointer
(在大多数情况下),当适当的(即你要使用的)VBO被绑定时。然后它的最后一个参数在所述缓冲区中偏移。
最后一个参数在the reference manual中定义得特别好:
指定第一个通用顶点的第一个组件的偏移量 当前绑定的缓冲区的数据存储中的数组中的属性 到GL_ARRAY_BUFFER目标。初始值为0.
适当的顶点指针与VBO源的绑定存储在VAO中,如果可能,您应该使用它。
简短的例子(原谅我的伪代码):
// Setup
CreateVAO(); BindVAO();
CreateVBO(); BindVBO();
VertexAttribPointer(/*id*/ 0, 3, GL_FLOAT, /*starting at offset*/ 0);
// We have specified Vertex attribute bound to location 0,
// with size of 3 floats, starting at offset 0 of VBO we've just created.
//Draw
BindVAO();
Draw();