d3dopengl:如何用D3D/OpenGL在制作2D游戏中高效地显示文字



  废话很久很久记不起和大家分享所学经验了主要是怕自己学东西不彻底写出东西容易误导人:)也就很久没有写过什么东西啦~在用d3d/opengl制作2d游戏时候,遇到问题最多还是在于文字显示今天就把个人所遇到问题和解决办法和大家分享

   在GDI/DDraw中显示文字不是什么麻烦事情大不了TextOut( hdc,...)就可以解决速度也不会慢到哪儿去实在不行也可以自己定义字库往ddrawlocked backbuffer里面直接写数据,这里就不多说了在d3d中,往device里面backbuffer直接写数据显然是不明智那将会造成性能急剧下降(不用多说了吧如果lock了显存buffer,县卡其他操作就会暂停下来)而d3d本身提供ID3DXFont这个类确实不敢恭维(DirectX9.0C以上例外)恐怕用过人都深有体会了~~这里也就不多说了当然DX9.0C对这个做了很大优化速度比以前简直不是个数量级就不用多说了下面来谈谈我做法

   *以下思路方法都是基于点阵字库处理TrueType字体本文不考虑

   解决思路方法:创建个足够大纹理(比如县卡支持最大纹理)在纹理中使用buffer机制把文字数据写到纹理上去般来说是不可能把所有文字都写上去(e文only除外)所以就要用种机制把最常用文字数据放到纹理中显示时候只要把相应纹理坐标计算出来就可以了如果使这种解决办法效率达到最高就看各人算法了管理纹理中文字数据思路方法比如可以用LRU算法也比较好事实证明这种思路方法可行

   解决思路方法 2:使用dos下hzk字体文件比如hzk16(ASCII16同理)由于字库编码范围为A1A1-F7FE 共也就(F7-A1)*(FE-A1) = 1F3E = 7998个按照每个大小16x16来计算如果创建大小为256x256纹理(该大小纹理贴图速度据说是最快)则每个纹理可以容纳256个这样算下来hzk16需要7998 / 256 = 31.25个纹理如果纹理格式为a4r4g4b4来算占用内存为 32 * 256*256*(16/8) = 4M这个应该不算是很大容量所以如果把hzk16数据全部放入这32张纹理中从内存消耗上来说是可以接受当然纹理贴图速度就不用说了~具体做法也很简单预先把hzk中字模数据写到32个纹理中去(自己定义纹理坐标-〉文字map规则) 这种思路方法优点很明显速度当然也有缺点hzk没有容纳足够多.
 
   解决思路方法 3:预先把Windows里面truetype字库所有数据转换成自己定义大小点阵字库(这个转换思路方法最简单是在某个设备上(比如DC)显示所有从设备中得到字模数据然后按照自己定义字库规范标准写入)在d3d中使用时候创建个vertexbuffer,显示文字时候就根据字模信息往vertexbuffer里面填数据vb满了后就DrawPrimitive polist,继续填充这种思路方法速度比较快而且占用内存也不多(我定义16x16大小字库也就1M大)至于效率就要看vb大小了据我经验1024-2048范围能达到最优水平

   以上几种思路方法都可以完全遗址到OpenGL中这里就不再陈述了

   这里给出上面说显示文字思路方法2和3例子以及源代码(需要dx8.0sdk编译注意在dx9.0CSDK下编译会有问题)各位如果有其他更好解决办法还请不吝赐教

mail : [email protected]
OICQ : 30784290
kylinx, 2004/12/18于无聊中.

Tags:  opengl opengl纹理文字 opengl文字 d3dopengl

延伸阅读

最新评论

发表评论