1

我目前正在 iOS 和 Android 平台上编写 OpenGL ES 2.0 应用程序。

在这个应用程序中,我渲染了多个都使用 VBO 的网格。在优化渲染的过程中,我意识到我渲染的网格共享两种顶点格式。所以我想做以下事情:

首先,设置所有顶点属性指针偏移量,然后简单地绑定每个使用这种顶点格式的 VBO 并渲染它,而无需glVertexAttribPointer再次调用该函数。

但它给了我奇怪的结果。

glVertexAttribPointer我的问题是:每次我们绑定一个新的 VBO 时都必须调用吗?

4

2 回答 2

2

首先,就像每个 OpenGL 状态一样,设置的状态glVertexAttribPointer保持不变,直到其他人再次调用glVertexAttribPointer(对于相同的属性索引)。但这里重要的是,内部状态更改为glVertexAttribPointer不只是存储用于渲染的缓冲区偏移量,调用时偏移到 VBO 范围内glDraw...。它还存储调用时绑定的实际缓冲区对象glVertexAttribPointer

所以是的,每当您想要从另一个 VBO 获取顶点数据时,您需要绑定此 VBO 并在绑定此 VBO 时执行适当的glVertexAttribPointer调用。虽然这在您的情况下可能看起来很麻烦,但这实际上是一件好事。这样,您在渲染某些内容时无需担心当前绑定的缓冲区,而只需担心使用glVertexAttribPointer. 更重要的是,让我们在渲染之前绑定不同的 VBO,因此您可以在单个渲染调用中从不同的 VBO 获取不同的顶点属性(否则您会怎么做?)。

编辑:但是,您可以使用顶点数组对象来简化设置顶点数据的过程。它们封装了从一堆数组中渲染所需的所有状态(因此所有由 更改的东西glVertexAttribPointergl(En/Dis)ableVertexAttribArray以及绑定到 的缓冲区GL_ELEMENT_ARRAY_BUFFER,但就像说的那样,不是绑定到 的缓冲区GL_ARRAY_BUFFER)。当然,您仍然必须在调用之前正确绑定缓冲区glVertexAttribPointer。但是使用 VAO,您只需要在某些设置例程中使用此代码,渲染所需要做的就是调用glBindVertexArray. 虽然我不知道您的特定 ES 设备是否支持它们。

于 2013-01-30T10:26:17.290 回答
1

我在使用 VAO / VBO 绘图时发现的一些很酷的资源

http://www.arcsynthesis.org/gltut/Positioning/Tutorial%2005.html#d0e4720

它展示了如何驱动多个对象,例如具有多个 VAO 和单个 VBO(每个 VAO 持有指向同一个 VBO 的不同偏移量的指针)

绝对值得一看,更不用说你学到的部分

  • glBindBuffer(GL_ARRAY_BUFFER...不绑定任何数据,它只是用于glVertexAttribPointer执行实际数据绑定的以下调用的全局指针

  • glBindBuffer(GL_ELEMENT_ARRAY_BUFFER...是否将元素数组绑定/保存到当前 VAO
于 2013-02-01T03:51:23.653 回答