使用OpenGL渲染/动画2D的最佳方法是什么?

4

我正在用C++制作一个游戏,现在遇到了一个抉择。

我正在计划如何处理动画和优化渲染。目前我使用的是立即模式渲染,但是我被告知这种方法非常慢。于是我开始寻找替代方案,发现有很多不同的方式,而且还要根据动画的处理方式而定。因此,我想问一下,什么是最好的优化方式呢?

对于动画,我考虑使用存储在内存中的图像序列,但是只测试了50张图像序列后,内存跳到了200MB,而之前只有30MB。(没有泄漏,它保持在200MB,但如果我有大型关卡,看起来我可能会用完内存)。在这种情况下,使用精灵表是否有帮助呢?

我被告知使用纹理集或精灵表的原因是绑定不同的纹理是一项昂贵的操作,所以唯一的方法是将我将在第1关中使用的所有纹理放入一个巨大的纹理中,这样我只需要绑定一次。这是否可以动态实现呢?

相比加载50个PNG文件,使用一个巨大的PNG文件是否更节省内存呢?

如果您能提供优化渲染的帮助或有关这些动画技术缺点的信息,我将不胜感激!

2个回答

4

使用顶点缓冲对象(VBO)代替即时模式:http://www.opengl.org/wiki/Vertex_Buffer_Object

精灵表有两个优点,第一个是你只需要绑定一个纹理。就内存而言,表只会让你的内存连续化(没有碎片),但实际内存量并不会减少。相比于加载50个小文件,加载一个大的.png肯定更快。你应该知道的一件事是,在将图像上传到OpenGL纹理后,可以释放实际的图像内存。否则,它会存在RAM和GPU内存中,这没有太多意义。

另一件事情是,你可以使用不同的动画技术,如关键帧或骨骼动画(在2D中也是一种有效的方法)来移动精灵,而不是为每个状态保存额外的图像/精灵。这肯定会极大地减少GPU和RAM内存的使用!

希望这可以帮助!


谢谢您的解释!那真的让我豁然开朗。 - Omar Shehata

4
我听说它非常缓慢。我建议忽略这个问题。除非你要使用疯狂数量的精灵(成千上万),否则瓶颈将是从纹理中读取数据,这受到显卡内存传输速率的限制。换句话说,如果你有1280x1024的视口,并且绘制一个覆盖整个视口的1280x1024纹理(每个像素都映射到屏幕像素),你的FPS将下降,而VBO将无法帮助。因此,在决定使用大量精灵之前,立即模式比VBO更容易用于2D。我考虑使用存储在内存中的图像序列。你需要将尽可能多的精灵压缩到单个纹理中。切换纹理会产生很大的减速,所以最好的方法是使用巨大的纹理(4096x4096或更大-16384x16384会不错)并将所有可用的精灵加载到其中。这可以使用“glSubTexImage2D”来完成。将每个帧单独存储到纹理中会导致巨大的减速。请注意,您无需将精灵存储在硬盘上合并为单个纹理。您可以在加载时将它们粘在一起。使用一个巨大的PNG在内存方面是否比加载50个PNG更好?PNG是存储在磁盘上的图像文件格式。它与OpenGL无关。一旦你加载纹理,它不再是“png”-它已完全解压缩。因此,如何在磁盘上存储图像数据几乎无关紧要。它将影响图像加载速度,但纹理性能/内存使用与图像存储格式无关。如果你的内存不足,那么你必须采取一些措施-实现游戏资产流式传输,或调整关卡的精灵/纹理“预算”。

1
谢谢你的帮助!很高兴知道我不必将渲染技术切换到VBO。关于PNG部分,这是个好消息!但我实际上只是在询问加载一个巨大的图像是否比加载50个较小的图像并将它们保存在内存中更好,但我猜两者在内存中占用的空间应该是相同的,对吗? - Omar Shehata

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