我正面临着一个问题,我相信这是VAO依赖的,但我不确定..
我不确定VAO的正确用法,我以前在GL初始化时做的是一个简单的
glGenVertexArrays(1,&vao)后跟一个
glBindVertexArray(vao)后来,在我的绘图管道中,我只调用了glBindBuffer()、glVertexAttribPointer()、glEnableVertexAttribArray()等等。而不关心初始绑定的VAO
这是正确的做法吗?
发布于 2012-01-19 16:53:52
就绑定方式而言,VAO的行为类似于VBO和纹理。在整个程序长度上使用一个VAO不会带来任何性能上的好处,因为您可能根本不需要VAOs就可以进行渲染。事实上,它可能会更慢,这取决于实现如何在绘制顶点属性设置时截获它们。
VAO的要点是在初始化期间运行一次绘制对象所需的所有方法,并在主循环期间削减所有额外的方法调用开销。关键是要有多个VAO,并在绘图时在它们之间切换。
就最佳实践而言,以下是您应该如何组织代码:
initialization:
for each batch
generate, store, and bind a VAO
bind all the buffers needed for a draw call
unbind the VAO
main loop/whenever you render:
for each batch
bind VAO
glDrawArrays(...); or glDrawElements(...); etc.
unbind VAO这避免了绑定/解除绑定缓冲区和传递每个顶点属性的所有设置的混乱,并将其替换为仅一个方法调用,即绑定VAO。
发布于 2012-01-19 16:53:15
不,这不是你使用VAO的方式。您应该以与使用VBO、纹理或着色器相同的方式使用VAO。首先设置它。并且在渲染过程中只绑定它们,而不修改它。
因此,使用VAO时,您可以执行以下操作:
void Setup() {
glGenVertexArrays(..);
glBindVertexArray(..);
// now setup all your VertexAttribPointers that will be bound to this VAO
glBindBuffer(..);
glVertexAttribPointer(..);
glEnableVertexAttribArray(..);
}
void Render() {
glBindVertexArray(vao);
// that's it, now call one of glDraw... functions
// no need to set up vertex attrib pointers and buffers!
glDrawXYZ(..)
}另请参阅以下链接:
发布于 2012-01-19 22:39:09
这是正确的做法吗?
是的,这是完全合法和有效的。是不是很好?好吧..。
在这类事情上有一些informal performance testing。而且看起来,至少在NVIDIA硬件上进行了测试,VAOs的“正确”使用(即:其他人所提倡的)在许多情况下实际上是较慢的。如果更改VAOs不会更改绑定的缓冲区,则尤其如此。
据我所知,没有在AMD硬件上进行过类似的性能测试。一般来说,除非它们发生了变化,否则这是一种可以接受的VAOs用法。
https://stackoverflow.com/questions/8923174
复制相似问题