使用Direct3D进行高级文本渲染

时间:2010-06-21 09:42:34

标签: direct3d fonts render-to-texture

让我描述一下我的任务的“战场”:

  • 超过1M用户的多房间音频/视频聊天;
  • 自定义Direct3D渲染器;

我需要实现的是TextOverVideo功能。文本本身通过网络进行,并使用Direct3D渲染器在接收方进行渲染。 AFAIK,它通常用于游戏开发中,用字母/数字创建自己的纹理并绘制这些项目。因为我们的应用程序必须支持多种语言,所以我们应该使用标准。这就是为什么我一直在使用ID3DXFont界面,但我发现了一些不满意的限制。

我所面临的是缺乏可扩展性。例如。如果用户正在调整视频窗口的大小,我必须使用新的D3DXFONT_DESC重新创建D3DXFont,而他正在这样做。我认为这是不可接受的。 这就是为什么我看到的唯一解决方案(由于我的技能)以某种方式将文本渲染为纹理,因此使用缩放,翻译等绘制精灵。

所以,我不确定我是否朝着正确的方向前进。请帮助提供建议,经验,文献,资料......

2 个答案:

答案 0 :(得分:3)

你的问题有点不清楚。据我了解,您希望轻松扩展字体。

  

我认为这是不可接受的

据我所知,这是字体的标准行为 - 即使对于系统字体也​​是如此。它们不应该容易扩展。

可能的解决方案:

  1. 使用ID3DXRenderTarget将文本渲染到纹理上。当您将其放大太多时,将过滤字体。有些人会认为它看起来很难看。
  2. 编写支持矢量字体的自定义库。即 - 它应该能够从字体中提取字体轮廓,并从中构建文本。它比ID3DXFont慢得多(它已经慢于传统的“纹理”字体)。文本将很容易扩展。使用这种方式,您很可能会获得小文本的可见伪像(“噪音”)。除非你想要大字母(40+像素),否则我不会使用这种方法。 Freetype库可能具有处理字体轮廓的功能。
  3. 或者您可以尝试使用D3DXCreateText。这将为一个字符串创建3D文本。一点也不快。
  4. 我会忘记它。只要用户对整体性能感到满意,改进字体渲染例程(因此他们的行为看起来对您很好)就不值得付出努力。

    - 编辑 -

    关于ID3DXRenderTarget。
    即使你使用ID3DXRenderTarget,你也需要ID3DXFont。即您使用ID3DXFont将文本渲染到纹理上,然后使用纹理将文本blit到屏幕上 因为您说性能至关重要,所以您可以延迟创建新的ID3DXFont,直到用户停止调整视频大小。即当用户开始调整视频大小时,您使用旧字体,但使用纹理升级它。当然会有过滤。一旦用户停止调整大小,您就可以在有时间时创建新字体。你可能可以在单独的线程中做到这一点,但我不确定。或者您可以简单地以与视频相同的分辨率渲染文本。这样您就不必担心调整它的大小(它仍将被过滤 - 与视频一起)。有些视频播放器以这种方式工作 关于ID3DXFont的更多信息。 ID3DXFont存在一个问题 - 在需要大量文本的情况下它很慢(但是你仍然需要它,因为它支持unicode,而使用unicode支持编写texturefont很痛苦)。上次我使用它时,我通过缓存纹理中常用的字符串来优化事物。即在行中绘制超过3帧的任何字符串都被渲染到D3DFMT_A8R8G8B8纹理/渲染目标上,然后我一直在从纹理复制该字符串而不是使用ID3DXFont。从纹理中删除了一段时间没有渲染的字符串。这给了一些严重的推动。然而,这个解决方案很棘手 - 监视纹理中的空白空间,删除未使用的字符串,并对纹理进行碎片整理并不是很简单(没有什么特别复杂,但很容易出错)。除非你的屏幕完全由文字覆盖,否则你不需要这么复杂的系统。

答案 1 :(得分:0)

ID3DXFont 字体是平的,始终与屏幕平行。 D3DXCreateText 是可以缩放和旋转的网格。

纹理字体模糊,看起来不太清晰。不适合使用大量小文本的应用。

我正在编写一个可以创建500个文本网格的应用程序,每个网格平均有3,000-5,000个顶点。文本网格创建一次,然后是静态的。我在GeForce 8800上获得700 fps。