资源预览内容
第1页 / 共7页
第2页 / 共7页
第3页 / 共7页
第4页 / 共7页
第5页 / 共7页
第6页 / 共7页
第7页 / 共7页
亲,该文档总共7页全部预览完了,如果喜欢就下载吧!
资源描述
关于 Direct3D11 里汉字显示的一些思考这篇文章里,浅墨希望与大家一起探讨一下 Direct3D11 中关于字体显示的一些问题。一、关于 Direct2D 与 DirectWrite先讲讲 Direct2D 和 DirectWrite 吧,下面关于字体讨论的时候有涉及到的地方。首先,Direct2D,它是 DirectX11 附带着发布的全新的二维图形 API。顾名思义,看到Direct2D 立马想到了它的大哥 Direct3D。的确,Direct2D 就是仿照着 Direct3D 来设计的,一款支持硬件加速的即时模式的二维图形 API,因为支持硬件加速,Direct2D 跑起来比 GDI,GDI+ 效率都高。Direct2D 用于取代 DirectDraw,可用于 2D 游戏开发,但是目前世界范围内对 Direct2D 研究热情似乎不高。关于 DirectWrite,它也是 DirectX11 中的新组件,主要是配合 Direct2D 使用,用于 Direct2D 应用程序中的字体和文字渲染。二、Direct3D11 里文字显示的一些讨论然后我们就开始正题,Direct3D11 中关于文字显示方案的一些讨论,特别是汉字的显示问题。Direct3D11 中微软非常奇葩地移除了 ID3DXFont 这个在 Direct3D 9 中非常好用的字体接口,这样导致了目前的 Direct3D11 中竟然没有一个官方的字体解决方案 - -,这真心不科学。要在 Direct3D11 中显示文字,除去那已经在 DirectX11 中离我们远去的 D3DXFont接口,我们还可以想到的字体解决方案主要就以下三种(且不管方法正不正确,我们先把他们列举出来):第一种方案,用子图形贴图的方式。第二种方案,与 GDI/GDI+进行交互,使用 GDI/GDI+中虽然相对 Direct3D 来说低效,却五脏俱全的 2D 字体体系。第三种方案,使用 DirectX11 中专门设计用来加强 Windows 中 2D 文字显示质量的全新APIDirectWrite。下面我们按上面的三种解决方案分别来进行一个小小的分析。第一种方案,用子图形贴图的方式解决 Direct3D11 里文字显示的问题。没错,这个是目前使用最广泛的 Direct3D11 文字解决方案。这种方案理解起来很简单,就是我们实际上在屏幕上贴出的是图片,而这些图片的内容就是一个个字母,这些图片组合在一起,就成了一段段的文字。正所谓巧妇难为无米之炊,说到图片,就必须有图片素材文件。使用这种方案需要准备如下所示的纹理素材: 关于使用方法的细节,我们可以参考下面这张图片: 很容易理解,如果要显示“D”字母,就把素材文件中“D“字母所在的矩形区域贴到文字需要显示的地方,这样就完成了 D 字母的显示。 然后,问题就来了,我们可以看到,英文也就那 26 个字母,算上大写小写,阿拉伯数字,符号等等,需要的也就是数量不超过 100 个的字体元。然而中文怎么办?中华浩浩荡荡上下五千年,厚重的文化底蕴孕育了浩如烟海、动辄数千的汉字,且不说还有繁体字,古体字 所以,第一种方案总结一下Direct3D11 中想用子图形贴图方式作为显示汉字的方案有待考究。且我们不要被这忙忙多的汉字吓到。来看一下,这种字体图集的做法,可以使用GDI/GDI+的字体绘制 API 函数,配合 FreeType(TTF 字体),将某种特定字体的每个字母元(单个汉字)渲染到一张纹理图集上。然后制作出来的纹理图集可以作为 cache 使用,进行字体的显示。汉字虽然多,但是按理来说,是可以实现的。实现代码如下:cpp view plaincopyprint?1. void SpriteBatch:DrawString(ID3D11DeviceContext* dc, 2. FontSheet& fs, 3. const std:wstring& text, 4. const POINT& pos, 5. XMCOLOR color) 6. 7. BeginBatch(fs.GetFontSheetSRV(); 8. UINT length = text.length(); 9. int posX = pos.x; 10. int posY = pos.y; 11. / For each character in the string. 12. for(UINT i = 0; i length; +i) 13. 14. WCHAR character = texti; 15. / Is the character a space char? 16. if(character = ) 17. 18. posX += fs.GetSpaceWidth(); 19. 20. / Is the character a newline char? 21. else if(character = n) 22. 23. posX = pos.x; 24. posY += fs.GetCharHeight(); 25. 26. else 27. 28. / Get the bounding rect of the character on the fontsheet. 29. const CD3D11_RECT& charRect = fs.GetCharRect(character); 30. int width = charRect.right - charRect.left; 31. int height = charRect.bottom - charRect.top; 32. / Draw the character sprite. 33. Draw(CD3D11_RECT(posX, posY, 34. posX + width, 35. posY + height), 36. charRect, 37. color); 38. / Move to the next character position. 39. posX += width + 1; 40. 41. 42. EndBatch(dc); 43. 第二种方案,我们可以让 Direct3D11 与 GDI/GDI+进行交互,使用 GDI/GDI+中虽然相对 Direct3D 来说低效,却五脏俱全的 2D 字体体系。是的,与 GDI/GDI+进行交互是目前 Direct3D11 里汉字显示主流方案,但是执行效率差强人意,个人觉得完全没有 Direct3D 9 中的 ID3DXFont 字体接口用起来舒服。第三种方案,在 Direct3D11 中使用 DirectX11 中专门设计用来加强 Windows中 2D 文字显示质量的全新 APIDirectWrite。这种方法行不行得通呢?答案是不行的,这种方案不可取。目前 Direct3D11 无法直接与 Direct2D/DirectWrite 进行交互。很有意思的是,Direct3D 10 同样也不能直接与 Direct2D/DirectWrite 交互,而Direct3D 10.1 却可以通过 GXDI 进行共享表面来实现,浅墨记得好像Direct2D/DirectWrite 就是在 Direct3D 10.1 的架构上进行开发的,所以他们的关系才会如此微妙。总结起来就是,目前 Direct3D11 中可以使用的汉字显示解决方案,第一种与第二种方案都可以。作者:孙广东 邮箱: 1224708372qq.com 欢迎邮件交流编程心得由于百度文库不支持压缩文件格式,源代码不能分享,很抱歉,想要源代码的请把邮箱号码发给我。我会把源代码发给你。我的百度空间文库:http:/www.baidu.com/p/a1224708372?from=wenku 欢迎访问,有更多专业资料。
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号