大家绘制D3D中的2D元素为什么不用现成的ID3DXSprite呢?

来源:互联网 发布:淘宝一般发货时间 编辑:程序博客网 时间:2024/05/22 23:27
3D场景中免不了要绘制一些2D元素,诸如UI等等。
个人感觉ID3DXSprite应当算是个比较好用的接口,使用起来也很方便。
不过,看前辈们貌似都很抵触这个接口,好像说是因为效率不行?好像大家采取的比较普遍的做法,就是固定Z坐标,然后直接在屏幕上绘制矩形+纹理。
求教各位大侠:大家普遍认为ID3DXSprite效率底下的原因或者依据是什么呢?又或者说大侠们还有其他的见解?
感激不尽~

==============抽象的分割线===============

小弟写过Xna,里面有一个SpriteBatch类,是这个环境下2D绘制公认的王道。基本的原理好像就是两个三角形拼合成一个矩形+纹理绘制+批处理。

D3D下的ID3DXSprite写法跟SpriteBatch挺像,有没有可能是采用了同样的机制呢?





ID3DXSprite内部也是“矩形+纹理绘制+批处理”的方法处理的,所以效率不差,关键是要正确的使用。
很多人对“批处理”的概念不了解,所以使用ID3DXSprite的时候都是一个图元一个图元绘制的,没有能发挥出“批处理”的性能优势。另外一个原因就是ID3DXSprite提供的绘制接口使用不方便,文档里面也没说清楚具体的用法。网上或者一些书本里面提供的例子大多只是简单的画个图像,也没有体现出批处理的特性。
久而久之,ID3DXSprite就被人误解了。



原来如此~ 非常感谢您的解惑~
关于ID3DXSprite用于批处理的方法,能不能有劳您再提点一二呢?我想我现在的使用方式应该就是像您说的那样,是“一个图元一个图元”的错误绘制方式。
另外,最近在使用ID3DXSprite还发现了一个问题,那就是图片绘制期间不能动态缩放,其尺寸需要Create到Texture的时候事先指定。
ManagedDirectX中的Sprite出现了一个区别于Draw方法的Draw2D方法,解决了这个问题。能否请教您下,在Direct3D中应当怎样通过ID3DXSprite实现图片尺寸的动态缩放?





批处理很简单的:
ID3DXSprite::Begin()
绘制对象
绘制对象
绘制对象
...
...
... 
ID3DXSprite::End()

但是很多书上或者网上的代码为了简化,只绘制了一个对象,让读者产生了一个错觉,以为每绘制一个对象都要begin...end一次。

至于图像的缩放,需要自己计算一个矩阵,然后用ID3DXSprite::SetTransform设置这个矩阵,再去绘制,绘制完了视情况可能还得再恢复到之前的矩阵。具体的可以参考DXUI里面UI绘制的代码。这就是ID3DXSprite不方便的地方,太底层了。




批处理是这样:把多个三角形写入一个VB,然后再用XYZRHW方式绘制。这就是批量化

比如,我有100个矩形,只要把100*2*3个顶点写入一个VB,然后只要一次DrawPrimitive就能全部画出来

但是每次改变了渲染状态(比如SetTransform)后,批量队列就被打断了

关键问题在于,如何管理批量队列及其状态




其实以现在的硬件, 就算你不搞批处理, 速度也很快. 尤其是2D


怪不得有个Begin和End,原来就是为了实现批处理。
单个纹理的批处理渲染,很简单,就是不知道多个纹理,批处理还会不会有效果?

原创粉丝点击