我目前正在iOS和Android平台上编写OpenGL ES 2.0应用程序。
在这个应用程序中,我渲染了所有使用VBO的多个网格物体。在优化渲染的过程中,我意识到渲染的网格共享两种顶点格式。所以我想做以下事情:
首先,设置所有顶点属性指针偏移,然后简单地绑定每个使用此顶点格式的VBO并渲染它而不再调用glVertexAttribPointer
函数。
但它给了我奇怪的结果。
我的问题是:每次绑定新的VBO时,我们是否必须进行调用glVertexAttribPointer
?
答案 0 :(得分:2)
首先,与每个OpenGL状态一样,设置为glVertexAttribPointer
的状态保持不变,直到其他人再次调用glVertexAttribPointer
(对于相同的属性索引)。但重要的是,用glVertexAttribPointer
改变的内部状态不仅存储用于渲染的缓冲区偏移,而是在调用glDraw...
时偏移到VBO边界。在调用glVertexAttribPointer
时,它还存储绑定的实际缓冲区对象。
所以是的,每当你想要从另一个VBO获取你的顶点数据时,你需要绑定这个VBO并在绑定这个VBO时进行适当的glVertexAttribPointer
调用。虽然这在你的情况下看起来很麻烦,但实际上这是一件好事。这样,在渲染内容时,您不必担心当前绑定的缓冲区,而只需要关注使用glVertexAttribPointer
设置的内容。更重要的是,它允许在渲染之前绑定不同的VBO,因此您可以在单个渲染调用中从不同的VBO中获取不同的顶点属性(您还会怎么做?)。
编辑但是,您可以使用Vertex Array Objects来简化设置顶点数据的过程。它们封装了从一堆数组中渲染所需的所有状态(因此所有内容都由glVertexAttribPointer
,gl(En/Dis)ableVertexAttribArray
和绑定到GL_ELEMENT_ARRAY_BUFFER
的缓冲区更改,但是如上所述,不绑定到GL_ARRAY_BUFFER
的缓冲区。当然,在调用glVertexAttribPointer
之前,您仍然需要正确绑定缓冲区。但是使用VAO,你只需要在一些设置例程中使用这个代码,而你需要做的只是调用glBindVertexArray
。虽然我不知道您的特定ES设备是否支持它们。
答案 1 :(得分:1)
我在使用VAO / VBO绘图时发现了一些很酷的资源
http://www.arcsynthesis.org/gltut/Positioning/Tutorial%2005.html#d0e4720
它显示了如何驱动多个对象,例如几个VAO和一个VBO(每个VAO保持指针具有不同的偏移到同一个VBO)
明确值得一看,没有提到你学到的部分
glBindBuffer(GL_ARRAY_BUFFER...
不绑定任何数据,它只是一个
执行实际数据绑定的以下glVertexAttribPointer
调用的全局指针BUT
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER...
将元素数组绑定/保存到当前的VAO