游戏环境中的 OpenGL VBO/DisplayList

Posted

技术标签:

【中文标题】游戏环境中的 OpenGL VBO/DisplayList【英文标题】:OpenGL VBO / DisplayList in a game environment 【发布时间】:2011-11-03 23:02:38 【问题描述】:

我正在开发一个小游戏(使用 OS X Lion、Xcode 4、Objective-C / C++、Cocoa、OpenGL)。这是一个相当简单的概念。我有一些在二维数组中移动的对象。现在我想为我的游戏编写一个 OpenGL GUI。

我所做的是遍历我的数组并为其中的每个对象绘制一个立方体,在其特定位置,其纹理取决于对象的类型。当然,我的第一个简单实现有点 CPU 密集型,所以下一步是实现纹理图集。由于我有很多顶点,还有很大的改进空间。

我了解到 VBO 和 DisplayList 的速度要快得多。我完成了一些教程,但我仍然对在真实动态游戏环境中的实现有很多疑问。

假设我为我的游戏对象编译了一些显示列表。如果我想把它放在一个特定的位置,我必须 glTranslatef()。但是很多 glTranslatef() 可能会占用大量 CPU。我该如何处理?当然,我可以在每个可能的位置为每种游戏对象创建一个显示列表,但这似乎不切实际,而且它只会起作用,因为我的游戏是基于图块的......

VBO 似乎也遇到了同样的问题。当然(至少根据我的理解)我可以创建一个完整的顶点网格,然后遍历我的数组并为每个对象渲染一个与对象位置相关联的顶点立方体。但我不明白如何将纹理从整个顶点网格应用于特定立方体。我是否必须为网格内的每个立方体面创建纹理坐标,还是为立方体的所有 6 个面创建纹理坐标就足够了?

【问题讨论】:

“但是很多 glTranslatef() 可能会占用大量 CPU。”所以?你说你在做“一个小游戏”。你有理由相信一些矩阵乘法会显着降低你的游戏性能吗?除非您有数十万个对象,否则这并不重要。这个问题有过早优化的味道。不要沉迷于“OMGFASTER!!!!11”只要让它发挥作用;您会惊讶于显而易见的解决方案经常足够快。 嗯,我有大约 25*40 块大小的关卡,大约有 1000 个对象。我正在绘制 1000 个立方体/球体,执行 1000 个 glTranslatef()s。活动监视器显示 20% 的 CPU 使用率。随着 glTranslatef() 被注释掉(我仍然绘制所有对象,但都在一个地方)CPU 使用率下降到 12%。对我来说似乎很重要。我什至还没有实现任何效果和动画。现在仍在使用渲染对象的幼稚实现,但我猜使用 VBO 或 DisplayLists 不会使 glTranslatef() 更快。 当然我在这里可能完全错了,但我仍然想知道更大的游戏如何处理这些东西。 @cargath:这些图块是每一帧都在世界空间中移动,还是静止不动? @genpfault:我的一些对象是动画的,所以我必须每帧重绘世界。 【参考方案1】:

显示列表和 VBO 通常对琐碎的几何图形没有帮助。如果我从蓝色的 OpenGL 书中没记错的话,有时它们甚至可以减慢速度。

显示列表在 OpenGL 1.x 中“尽善尽美”,但在引入 VBO 后被视为遗留功能。

如果我们知道您的 OpenGL 目标版本是什么,将会有所帮助。在使用即时模式的 OpenGL 1.x 中,您所做的是设置“相机矩阵”(OpenGL 没有,您只需将其转置留在矩阵堆栈上)然后在渲染循环中为每个模型推送和弹出矩阵。

使用 OpenGL 2.x 或 1.xARB 扩展,您可以将变换置于统一矩阵中,然后为每个模型更新统一。由于更新制服也很慢,因此这并不能真正为您带来太多好处。

我认为你能做的最好的事情是在着色器中为 OpenGL 提供一个(一组)属性矩阵。这将通过一次性传输所有数据来减少您的 CPU 开销。我想不出技术实现细节,但我认为属性是每个顶点的,所以你必须传递一个索引,说明在你用来放置变换的另一个缓冲区中的查找位置。我从来没有这样做过,因为大多数模型包含的几何和纹理信息比设置变换的时间要多。

话虽如此,使用 VBO 重新设计它并提供属性转换可能需要大量工作才能使 CPU 使用率提高 8%。可能是 2.0ghz core 2 duo 的一个核心 8%

编辑

统一的缓冲区对象是我真正想要的。可能是为了统一的块布局。蓝皮书(可能还有橙皮书)和谷歌有更多细节。

【讨论】:

嗯,当然在这一点上没有实际需要改进,但正如我所说,我计划实现一些效果和动画。我仍处于开发的早期阶段,因此可能需要进行优化,而且我想我会更容易从一开始就使用最好的技术,而不是在我意识到幼稚的实现会变慢时重写所有内容。此外,8% 的 CPU 使用率可能不算多,但几乎是总 CPU 使用率的一半。 目标 OpenGL 3.3 / 4.2。不要使用立即模式或 GL1 的矩阵函数。我建议开始使用 Siftless 教程。使用在统一缓冲区填充的 unforms 中声明矩阵的着色器我认为是最有效的方法。 我以前用过 OpenGL,但只用于硬件加速的 2D 东西。这是我第一次创建 3D 东西,所以即使我可能不需要为这个游戏使用所有花哨的技术,我仍然有兴趣将它们用于学习目的。对于这么小的游戏来说,20% 的 CPU 使用率似乎很多,有些游戏的角色面部包含的多边形比我的整个游戏世界还多。我可能有一千个立方体,但像英雄萨姆这样的游戏会处理数百个敌人。我对它的工作原理非常感兴趣。 我真的不知道我用的是哪个版本。有没有办法找出来?我在 OS X Lion 上使用 Xcode 4 附带的库。一些标题建议使用 1.2,另一些建议使用 3.x。 感谢您的建议。这个周末我会调查他们,只要我有空闲时间:)

以上是关于游戏环境中的 OpenGL VBO/DisplayList的主要内容,如果未能解决你的问题,请参考以下文章

停靠栏下的窗口化opengl游戏中的双光标

如何在opengl游戏循环中使用双核?

OpenGL核心之SSAO技术讲解

OpenGL中的调色板动画

玩游戏时为了使画面的流畅性能更好,“OpenGL”中的三重缓冲是开启好还是不开启好? 电脑配置:

OpenGL 包装器中的 Alpha/纹理问题