OpenGL:VAO/VBO 混淆
Posted
技术标签:
【中文标题】OpenGL:VAO/VBO 混淆【英文标题】:OpenGL: VAO/VBO confusion 【发布时间】:2014-01-03 15:24:07 【问题描述】:OpenGL Wiki: Vertex Specification 声明:
注意:
GL_ARRAY_BUFFER
绑定是不是 VAO 状态的一部分!我知道这很令人困惑,但事实就是如此。
以下是我如何使用 VAO,它似乎按预期工作。这里有什么问题?我对 OpenGL(或 OpenGL Wiki)、我的 OpenGL 驱动程序 (OSX 10.9) 或 OpenGL Wiki 的理解?
// ------ Pseudo-code ------
// setup
[...]
glBindVertexArray(vertexArrayObjectIdx1);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferId1);
for each vertex attribute
glEnableVertexAttribArray(...);
glVertexAttribPointer(...);
glBindVertexArray(vertexArrayObjectIdx2);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferId2);
for each vertex attribute
glEnableVertexAttribArray(...);
glVertexAttribPointer(...);
// rendering
[...]
glBindVertexArray(vertexArrayObjectIdx1);
glDrawElements(...);
glBindVertexArray(vertexArrayObjectIdx2);
glDrawElements(...);
【问题讨论】:
【参考方案1】:这意味着当你重新绑定VAO
时GL_ARRAY_BUFFER
不会反弹
但是,glVertexAttribPointer
确实将(当时)绑定的GL_ARRAY_BUFFER
绑定到了 VAO 中的正确属性,因此它可以按您的意愿工作。
实际上他们可以将glVertexAttribPointer
定义为:
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, uint bufferName, const GLvoid * pointer);
并消除它对绑定GL_ARRAY_BUFFER
的依赖。但事后诸葛亮……
重要的是要记住GL_ARRAY_BUFFER
对于绘图并不重要,但顶点属性的绑定方式很重要。
相比之下,GL_ELEMENT_ARRAY_BUFFER
存储在 VAO 中
【讨论】:
实际上有一个glVertexAttribPointer (...)
的版本,其签名大致相同。但是你必须使用Direct State Access 扩展(它基本上排除了Apple、Intel 和Mesa 的实现,只留下了AMD 和NV)。 非常 一开始你会觉得很尴尬(主要是因为函数名),但是这个丑陋的函数:glVertexArrayVertexAttribOffsetEXT (...)
会让你设置一个指向 VBO 的数据存储的指针,指向特定索引处的 VAO,而不绑定 VBO 或 VAO。
也就是说,他们真的不能那样定义glVertexAttribPointer (...)
,因为这个函数是通过ARB顶点程序扩展引入OpenGL的。并且 ARBVP1 可以在没有顶点缓冲区对象的情况下实现(ARBVP1 比 VBO 早 2-3 年)。
@AndonM.Coleman 不否认,如果他们可以从头开始重新设计,那么他们将大大减少对全局状态的依赖
当然会。我只是指出 glVertexAttribPointer (...)
最初并不是这样设计的,因为当着色器首次引入 OpenGL 时 VBO 并不存在。 Long's Peak 会让 OpenGL 成为一个更好的 API,但我们剩下的只是 DSA 扩展,它没有得到广泛支持:(【参考方案2】:
在同一个 Wiki 条目的下方,您也可以看到解释 - This is also why GL_ARRAY_BUFFER is not VAO state; the actual association between an attribute index and a buffer is made by glVertexAttribPointer.
...
【讨论】:
以上是关于OpenGL:VAO/VBO 混淆的主要内容,如果未能解决你的问题,请参考以下文章