OpenGL 2.1中的顶点缓冲对象

7
(I指定了2.1版本,因为我的笔记本电脑无法使用更高版本。我可能会这样做,因为3.x及以上版本强制要求使用着色器?)。
感谢维基百科:http://en.wikipedia.org/wiki/Vertex_Buffer_Object,我开始理解如何简单地使用VBO(我仍然不确定IBO?)。到目前为止,我所理解的主要原因是使用它们可以提高性能,因为数据现在存储在视频内存中。
我想知道的是在实际情况下应该如何使用它们。例如,我看到的所有内容都是设置一个顶点缓冲对象并绘制一个三角形或一个立方体等等。如果我想画2个或更多个呢?我为每个要绘制的实体设置一个新的VBO吗?还是在早期设置的某些静态VBO中神奇地添加?

完全不相关的评论:如果您理解了VBO,又怎么会对IBO持否定态度呢?因为它们甚至更简单。在实际应用中,您通常会使用glDrawElements而不是glDrawArrays - Christian Rau
@Christian Rau:我可能没有表达清楚我的问题,我想知道是否需要创建多个VBO而不是一个全局的VBO。 - LunchMarble
我理解了(并回答了)你的问题。就像Ken所说的那样,IBOs并不比VBOs更不同或更难。 - Christian Rau
2个回答

5

这取决于问题的范围。

对于每个模型/对象/网格,使用一个VBO存储顶点属性和一个VBO存储索引是直接且可行的。您可以将所有模型存储在单个VBO中,这样您就不必经常绑定缓冲区,但是当这些模型不太静态时,会带来其他问题。此外,您可能会为每个对象使用多个VBO,例如一个用于动态数据,一个用于静态数据,或者一个用于几何数据(位置...),另一个用于与材质相关的数据(纹理坐标...)。

对于每个对象使用一个VBO也有其优缺点,而仅使用一个巨大的VBO可能不是很好的想法。这取决于具体的应用程序以及这些概念如何适合其中。但是,对于刚开始,直接采用每个对象一个VBO的方法并不是一个坏主意。只需不要使用每个三角形一个VBO即可 ;)


@Storm 你可以为每个四边形使用一个VBO,但这样你只能在每个绘制调用中渲染一个四边形,这可能适用于你的精灵对象(仅由单个四边形组成)。但是,如果你有许多相似的精灵(例如在粒子系统中),那么你应该将所有这些精灵/粒子打包到单个VBO中,这样你就可以一次性地渲染它们。正如我所说,这取决于具体的应用程序,而粒子系统肯定是支持单个VBO方法的其中之一。 - Christian Rau
有道理。是否有一种方法可以批处理非相似精灵的绘制调用?我认为XNA使用他们的SpriteBatch来实现这一点。 - LunchMarble
@Storm 问题在于,你不能通过这种方式为每个精灵更改纹理(或其他渲染参数)。你可以按纹理/材质/着色器等对精灵进行排序,然后相应地批处理它们。否则,您将不得不采用更高级的批处理技术,如纹理集、纹理数组或实例化渲染。 - Christian Rau
顺便说一句,XNA的“SpriteBatch”似乎只包含单个精灵图像,但我只是短暂地看了一眼,没有任何XNA经验。 - Christian Rau
我可以将所有的精灵帧打包到一个纹理中。然后,我只需要确保在同一绘制调用中不发生状态更改。是否可以从四边形到四边形变化纹理坐标?这样它们就可以有不同的图像,即使它们都共享一个纹理? - LunchMarble
显示剩余2条评论

2
这应该很简单 - 只需向VBO添加更多数据即可。
例如,如果您想呈现3个三角形而不仅仅是1个,请确保将9个顶点发送到glBufferData。然后,要呈现所有这些三角形,请使用调用glDrawArrays(GL_TRIANGLES, 0, 9);。它真的应该那么简单。
但是,关于IBO的一个要点是,它们与VBO几乎没有什么不同,我真的会习惯使用它们。这实际上是使用VBO的实用方法。由于通常有多个三角形用于覆盖同一表面(例如,立方体需要十二个三角形),仅使用VBO会在指定顶点数据时造成很多重复。通过使用索引缓冲区,事情变得更加高效,因为任何重复都从VBO中删除。我发现这里提供了一个简洁的示例,说明如何从仅使用VBO转换为使用VBO/IBO,并且还对此进行了很好的解释。

是的,我今天刚找到这本书,他简洁的写作风格给我留下了深刻印象。 - Ken Wayne VanderLinde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接