使用OpenGL来加速2D图形

3
我和我的朋友正在尝试使用OpenGL加速2D游戏。视频芯片组是Radeon X1250,似乎性能不足,最多可以显示80个1366x768的全帧/秒。鉴于我们在彼此之上绘制了许多精灵,性能会急剧下降,低于我们目标的60 FPS。请问您能否提供有关使用OpenGL快速渲染2D的优化提示?
编辑:一些澄清: 开发在Linux下用C++进行。我们曾尝试使用SDL进行开发,但性能不理想,因此我们决定转向OpenGL,这证明更快。当然,随后推出了更多功能的需求,需要我们每帧重绘整个屏幕。
我们的测试程序在1366x768屏幕上呈现纹理256x256的四边形瓦片。如果在缓冲区交换之前放置单层瓦片,则可获得80 FPS;如果放置两层,则帧率将下降到60 FPS以下。考虑到该板将需要同时解码和渲染一些小型MPEG,这可能是不令人满意的。
我只是想寻找从游戏是2D的事实中产生的优化,例如: 1)如果可能,禁用纹理缩放。 2)直接渲染到帧缓冲区(尽管我们听说glDrawPixels速度较慢)。

请问您能提供一些代码吗? - James Black
如果您能说明您所涉及的精灵数量,将会更有帮助。是100个、1000个还是10000个?这样就更容易判断您是否出现了错误或者如何进行优化。 - Foxfire
5个回答

4
听起来你遇到了显卡的最大填充率限制,再加上你正在进行混合操作,所以需要读取和写入缓冲区。如果过度绘制帧缓冲区(特别是在高分辨率下),那么由于显卡填充率的限制,最终会降低帧率。尽管现代显卡可以执行许多操作,但它们仍然有像素推送的限制。
为了减少这种情况,以下是一些建议:
- 如果可能,不要每帧都绘制所有内容-将一些部分渲染到其他缓冲区,然后在更低的分辨率下混合。 - 如果不必要,请勿使用混合-与绘制不透明的东西相比,混合要慢得多。 - 使用更便宜的片段着色器/片段程序-如果您使用可编程管道(注意:我不知道如何确定它的成本)。 - 尽可能多地使用剔除-避免绘制完全看不见的物体。如果精灵完全(或大部分)隐藏在其他物体后面,则无需绘制它。 - 缩放/插值可能相对便宜-使用较低的纹理分辨率并对其进行缩放-特别是如果您的纹理本来就很模糊。
如果您正在这样做以获得一些时髦的烟雾/粒子效果,则可能无法使用所有或许多这些优化。

2
请您能详细解释一下“不要在每帧中都画出所有东西”这句话吗? - pachanga

3

通常情况下,如果您指定了所针对的OpenGL版本,那么更精确的答案会更容易得出。似乎这是大多数关于OpenGL的问题在StackOverflow上缺失的内容。

如果您将大量逐顶点数据上传到服务器,请确保将顶点数据存储在缓冲区对象中。永远不要使用立即模式,也就是glBegin/glEnd成对使用。而是使用glDrawArraysglDrawElements或另一个数组绘制调用。这已经可以极大地提高性能。

过度绘制本身并不慢,但它肯定会浪费填充率。但遮挡剔除经常不值得初始性能设置成本。每片段混合会浪费很多填充率。

如果这些提示没有帮助,我建议您检查一下您的应用程序是否真正受限于GPU。我有疑问。瓶颈可能在其他地方。也许您的X视觉/FBConfig没有硬件加速?


2

OpenGL旨在追求高速运行,但是编写不良的代码可能会导致性能下降。

有许多未知因素需要考虑。例如,您使用的是哪种语言(我猜测是C ++),使用了哪个框架,还是自己编写的?

您要重建多少屏幕?例如,是否重新生成每个对象而不仅仅是转换它们?

你可能会发现这个问题很有用:关于OpenGL编程的最佳实践有哪些(特别是关于对象导向方面)?

如果您可以提供一些已经进行过分析以确定瓶颈所在的示例,那将非常有帮助。

如果只使用线框而没有填充或纹理,您的性能如何?

您的游戏循环是怎样的?例如,是否与鼠标或键盘进行交互,并且该逻辑是否影响帧率?

我曾经遇到过这样的问题,我的重绘速度为70fps,但我的音乐却没有按正确的毫秒开始或结束,于是我将循环更改为只进行30fps,并增加了音乐处理的频率,这样我的性能就得到了提高。


2

一个优化的方法是按前后顺序绘制图层(不考虑透明度),启用Z缓冲并利用Early Z功能。

但其他评论也是正确的。信息如此之少,无法确定如何获得加速。


1
你确定渲染是个问题,还是你的逻辑与渲染有关?OpenGL中的性能优化是一个相当大的话题,所以我会给你提供一个资源。

谷歌上的第一个链接


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