OpenGL 2D性能优化技巧

3

我目前正在开发一款类似东方Project的弹幕射击游戏。屏幕将被完全填充着子弹(所以我需要使用实例化技术),但是我希望这个游戏可以在旧硬件上运行,所以我现在正在按照以下方式进行,然而现在还没有颜色、纹理等内容,直到我解决这个问题。

glVertexPointer(3, GL_FLOAT, 0, SQUARE_VERTICES);
for (int i = 0; i < info.centers.size(); i += 3) {
    glPushMatrix();
    glTranslatef(info.centers.get(i), info.centers.get(i + 1), info.centers.get(i + 2));
    glScalef(info.sizes.get(i), info.sizes.get(i + 1), info.sizes.get(i + 2));
    glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, SQUARE_INDICES);
    glPopMatrix();
}

因为我希望它可以在旧硬件上运行,所以我试图避免使用着色器等内容。上面的设置对我失败了约80个多边形。我希望从这里至少获得几百个。"info"是一个struct结构,其中包含渲染所需的所有好东西,除了一些向量外,没有什么特别的。
我对OpenGL还很陌生,但我至少听说并尝试过可以做的所有事情,虽然不表示我擅长它。这个游戏是一个2D游戏,我从SDL切换到Opengl,因为它可以更容易地创建一些花哨的效果。显然,SDL的工作方式不同,但我从未在使用它时遇到过这个问题。
归根结底,很明显我在这里做错了什么,那么我如何正确实现老式硬件(OpenGL1.x)的实例化?此外,请给我任何提高性能的提示。

你使用过像GDebugger这样的工具进行过任何性能分析吗?那会告诉你瓶颈在哪里。 - Pubby
尽可能少地使用绘制调用,尝试将所有内容放入一个VA中(在CPU端自己完成所有翻译等操作)。 - harold
1个回答

9
Also, 给我一些提高性能的技巧。
如果你要使用sprites....
1. 将所有的sprites加载到单个大纹理中。如果它们不适合,使用几个纹理,但保持纹理数量较少-以避免纹理切换。 2. 尽可能少地更改纹理和OpenGL状态。理想情况下,您应该设置一次纹理,并用它绘制您可以绘制的所有内容。 3. 对于文本,请使用纹理字体。FTGL字体可能看起来不错,但对于复杂字体,它会严重影响性能。 4. 在可能的情况下避免alpha-blending,使用alpha-testing。 5. 在alpha-blending时,始终使用alpha-testing来减少绘制的像素数。当您的纹理有许多alpha == 0的像素时,请使用alpha-test将它们删除。 6. 减少非常大的sprites的数量。巨大的屏幕对齐/像素对齐sprite(1024 * 1024)即使在非常好的硬件上也会降低FPS。 7. 不要使用非2的幂大小的纹理。它们(过去)会在某些ATI卡上产生巨大的性能下降。
glTranslatef
对于基于2D精灵的游戏,你完全可以避免使用矩阵(除了相机/投影矩阵可能需要用到)。我认为在2D游戏中,矩阵并不能给你带来很大的好处。
在2D游戏中,你的主要瓶颈将是GPU内存传输速度-从纹理到屏幕的数据传输。因此,“尽量少使用绘制调用”和“将所有内容放入VA”并不能帮助你-你甚至可以因一个精灵而降低性能。

然而,如果你要使用不使用纹理的矢量图形(参见area2048(youtube)或rez),那么上面大部分的建议都不适用,并且这样的游戏与3D游戏并没有太大的区别。在这种情况下,合理使用顶点数组、顶点缓存对象或显示列表(取决于可用性)和利用矩阵函数是很有必要的,因为你的瓶颈将是顶点处理。你仍然需要最小化状态切换的数量。


非常好的技巧!但是有一个问题:“减少非常大的精灵数量。即使在非常好的硬件上,巨大的屏幕对齐/像素对齐精灵(1024*1024)也会降低FPS。” - 如果我有一个用作静态背景的大型高分辨率精灵,并且不想放弃它,我该怎么办?还有其他选择吗? - nietaki
关于屏幕上的子弹,它们将是从头开始绘制的矢量图形。那么,我应该如何修改当前的方法来解决这个问题呢?在等待答案的时候,我尝试了顶点数组,但并没有看到明显的改善,尽管这个过程相对较快。我到底做错了什么?现在我正在查看area2048。游戏主要由矢量图形组成。 - SpaceFace
即使是纹理精灵,"将所有东西放入VA"的原则仍然适用。不相信吗?试试看。一百万次绘制调用会严重影响性能。 - harold
@harold:如果你在2D射击游戏中有百万次绘制调用,那么你的游戏/引擎设计问题非常严重。保持现实——只有当你真正达到这个水平时才需要担心“百万次绘制调用”。实际上,你的AI/碰撞检测程序早在此之前就会崩溃。 - SigTerm

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