【发布时间】:2009-09-27 21:49:06
【问题描述】:
我正在尝试编写一个涉及许多圈子的游戏(好吧,Triangle Fans,但你明白了)。每个圆都有一个 x 位置、一个 y 位置和一个质量属性。每个圆圈的质量属性都会不同。另外,我想给一些不同的圆圈组上色,同时保持一个透明的圆圈中心,并沿着圆圈的周边褪色到不透明。
我被告知要使用 VBO,并且整天都在谷歌上搜索。我想要一个完整的例子,说明我将如何绘制这些圆圈,并解释 VBO 的工作原理,同时保持解释简单。
【问题讨论】:
我正在尝试编写一个涉及许多圈子的游戏(好吧,Triangle Fans,但你明白了)。每个圆都有一个 x 位置、一个 y 位置和一个质量属性。每个圆圈的质量属性都会不同。另外,我想给一些不同的圆圈组上色,同时保持一个透明的圆圈中心,并沿着圆圈的周边褪色到不透明。
我被告知要使用 VBO,并且整天都在谷歌上搜索。我想要一个完整的例子,说明我将如何绘制这些圆圈,并解释 VBO 的工作原理,同时保持解释简单。
【问题讨论】:
我自己还没有实现 VBO,但据我了解,它们的工作方式类似于纹理对象。事实上,当我提醒自己并向其他人解释 VBO 是什么时,我喜欢错误地将纹理对象称为“纹理缓冲区对象”,以加强概念上的相似性。
(不得与来自 NVIDIA 指定扩展 GL_EXT_texture_buffer_object 的 buffer textures 混合。)
那么让我们想一想:什么是纹理对象?它们是您使用glGenTextures() 生成的对象。 glGenBuffersARB() 做类似的事情。类比适用于glBindTexture() 和glBindBufferARB()。
(从 OpenGL 1.5 开始,函数 glGenBuffers() 和 glBindBuffer() 已进入核心 OpenGL,因此您可以使用它们代替扩展等效项。)
但是这些“纹理对象”到底是什么,它们有什么作用?好吧,考虑一下您实际上可以在每一帧中使用glTexture2D() 来设置纹理。纹理对象仅用于减少 GPU 和主内存之间的流量;而不是发送整个像素数组,您只发送您知道是静态的纹理对象的“OpenGL 名称”(即整数标识符)。
VBO 也有类似的用途。您无需一遍又一遍地发送顶点数组,而是使用glBufferData() 上传一次数组,然后只发送对象的“OpenGL 名称”。它们非常适合静态对象,而不适合动态对象。事实上,许多通用 3D 引擎(例如 Ogre3D)为您提供了一种指定网格是动态还是静态的方法,很可能是为了让您在 VBO 和顶点数组之间做出决定。
出于您的目的,VBO 不是正确答案。您需要大量不断变形和变化的简单对象。简单来说,我的意思是那些顶点少于 200 个的那些。除非您打算编写一个非常智能和复杂的顶点着色器,否则 VBO 不适合您。您想使用顶点数组,您可以轻松地从主 CPU 操作并在每帧更新它们,而无需对显卡进行特殊调用以将整个 VBO 重新上传到显卡上(这可能比仅发送顶点数组要慢)。
这是来自 nVidia about VBO API 的非常好的 letscallit “手册页”。阅读它以获取更多信息!
【讨论】:
你正在做的看起来像粒子,你可能想谷歌“粒子渲染”以防万一。
【讨论】: