DirectX9 - 高效绘制精灵

4

我正在尝试创建一个平台游戏,为了绘制关卡,我需要使用各种精灵块,并将它们拼接在一起。这就需要在每一帧中在屏幕上绘制大量精灵。良好的计算机可以轻松处理所有精灵的绘制,但对于旧计算机来说会影响性能。由于这不是一个大型游戏,我希望它可以运行在几乎任何计算机上。目前,我正在使用以下DirectX函数来绘制我的精灵:

D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);

D3DXVECTOR3 position(static_cast<float>(x), static_cast<float>(y), z);

(my LPD3DXSPRITE object)->Draw((sprite texture pointer), NULL, &center, &position, D3DCOLOR_ARGB(a, r, g, b));

有没有更有效率的方法在屏幕上绘制这些图片?我能否使用更简单的图片文件(现在我正在使用普通的png文件)来加快速度?

总之,什么是在DirectX中绘制精灵最具性能友好的方式?谢谢!

2个回答

4
你正在使用的ID3DXSPRITE接口已经非常高效。请确保所有的精灵绘制调用在精灵开始和结束调用之间尽可能地批处理。这样可以让精灵接口以最有效的方式安排绘制。
为了获得额外的性能,您可以将多个较小的纹理加载到一个较大的纹理中,并使用纹理坐标来获取它们。这使得纹理不必频繁交换。参见:

http://nexe.gamedev.net/directknowledge/default.asp?p=ID3DXSprite

您正在使用的纹理文件类型并不重要,只要它们被预加载到纹理中即可。确保在游戏/关卡加载时将它们全部加载到纹理中。一旦它们被加载到纹理中,原始格式就无关紧要了。
如果仍然无法获得所需的性能,请尝试使用PIX来分析您的应用程序并找出瓶颈所在。
编辑:
这段文字太长了,无法放入评论中,因此我会编辑这篇文章。
当我说交换纹理时,我的意思是将它们绑定到一个纹理阶段上,使用SetTexture方法。每次调用SetTexture都会有一点性能损失,因为它会更改纹理阶段的状态。通常这种延迟很小,但如果DirectX必须从系统内存中提取纹理到视频内存中,则可能会很糟糕。
ID3DXsprite会为您重新排序begin和end之间的绘制内容。这意味着SetTexture通常只会针对每个纹理调用一次,而不管您以何种顺序绘制它们。
通常情况下,将小纹理加载到大纹理中是值得的。例如,如果所有小纹理都能适合一个大纹理中,那么纹理阶段就可以一直绑定到该纹理上进行绘制。通常情况下,这样做会带来明显的改善,但只有测试才能确切知道它会有多大帮助。虽然看起来很糟糕,但您可以随意添加任何大纹理并假装它是组合后的纹理,以测试性能差异。

非常有帮助!谢谢!只有几个问题。交换纹理是什么意思,它如何降低性能?比如我连续三次绘制图像x,然后连续两次绘制图像y,然后再次绘制图像x,每次都在不同的alpha级别下...这会导致2次纹理交换吗?如果将这些图像合并成一个纹理映射图像,会显著提高性能吗?如果是这样,我很乐意这样做,但这需要很多工作,因为目前我的所有精灵都是单独的图像文件。 - Jeremy
非常好的想法。我会尝试为所有内容渲染相同的图像,并查看差异是什么。再次感谢...非常非常有帮助! - Jeremy

2

我同意dschaeffer的观点,但是我想补充一下,如果你使用了大量不同的纹理,最好将它们压缩到单个(或几个)较大的纹理中,并根据不同精灵调整纹理坐标。纹理状态更改的成本很高,这可能会加速旧系统的运行速度。


这听起来像是一些非常好的信息。谢谢! - Jeremy

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