使用 Direct3D 进行高级文本渲染

发布于 2024-09-06 06:14:20 字数 464 浏览 7 评论 0原文

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

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

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

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

所以,我不确定我是否进入了正确的方向。请提供建议、经验、文献、资料来源......

Let me describe the "battlefield" of my task:

  • Multi-room audio/video chat with more than 1M users;
  • Custom Direct3D renderer;

What I need to implement is a TextOverVideo feature. The Text itself goes via network and is to be rendered on the recipient side with Direct3D renderer. AFAIK, it is commonly used in game development to create your own texture with letters/numbers and draw this items. Because our application must support many languages, we ought to use a standard. That's why I've been working with ID3DXFont interface but I've found out some unsatisfied limitations.

What I've faced is a lack of scalability. E.g. if user is resizing video window I have to RE-create D3DXFont with new D3DXFONT_DESC while he's doing that. I think it is unacceptable.
That is why the ONLY solution I see (due to my skills) is somehow render the text to a texture and therefore draw sprite with scaling, translation etc.

So, I'm not sure if I go into the correct direction. Please help with advice, experience, literature, sources...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南笙 2024-09-13 06:14:20

你的问题有点不清楚。据我了解,您需要易于缩放的字体。

我认为这是不可接受的

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

可能的解决方案:

  1. 使用 ID3DXRenderTarget 将文本渲染到纹理上。当你放大太多时,字体会被过滤。有些人会认为它看起来很丑。
  2. 编写支持矢量字体的自定义库。即 - 它应该能够从字体中提取字体轮廓,并从中构建文本。它会比 ID3DXFont 慢得多(ID3DXFont 已经比传统的“纹理”字体慢)。文本将很容易缩放。使用这种方式,您很可能会得到小文本的可见伪影(“噪音”)。除非你想要大字母(40+像素),否则我不会使用这种方法。 Freetype 库可能具有处理字体轮廓的功能。
  3. 或者您可以尝试使用 D3DXCreateText。这将为一个字符串创建 3D 文本。根本不会快。

我会忘记它。只要用户对整体性能感到满意,改进字体渲染例程(因此他们的行为看起来对您来说很好)就不值得付出努力。

--编辑--

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

Your question is a bit unclear. As I understand it, you want easily scalable font.

I think it is unacceptable

As far as I know, this is standard behavior for fonts - even for system fonts. They aren't supposed to be easily scalable.

Possible solutions:

  1. Use ID3DXRenderTarget for rendering text onto texture. Font will be filtered when you scale it up too much. Some people will think that it looks ugly.
  2. Write custom library that supports vector fonts. I.e. - it should be able to extract font outline from font, and build text from it. It will be MUCH slower than ID3DXFont (which is already slower than traditional "texture" fonts). Text will be easily scalable. Using this way, you are very likely to get visible artifacts ("noise") for small text. I wouldn't use that approach unless you want huge letters (40+ pixels). Freetype library may have functions for processing font outlines.
  3. Or you could try using D3DXCreateText. This will create 3D text for ONE string. Won't be fast at all.

I'd forget about it. As long as user is happy about overall performance, improving font rendering routines (so their behavior looks nice to you) is not worth the effort.

--EDIT--

About ID3DXRenderTarget.
EVen if you use ID3DXRenderTarget, you'll need ID3DXFont. I.e. you use ID3DXFont to render text onto texture, and then use texture to blit text onto screen.
Because you said that performance is critical, you can delay creation of new ID3DXFont until user stops resizing video. I.e. When user starts resizing video, you use old font, but upscale it using texture. There will be filtering, of course. Once user stops resizing, you create new font when you have time. you probably can do that in separate thread, but I'm not sure about it. OR you could simply always render text in the same resolution as video. This way you won't have to worry about resizing it (it still will be filtered - along with the video). Some video players work this way.
Few more things about ID3DXFont. There is one problem with ID3DXFont - it is slow in situations where you need a lot of text (but you still need it, because it supports unicode, and writing texturefont with unicode support is pain). Last time I worked with it I optimized things by caching commonly used strings in the textures. I.e. any string that was drawn more than 3 frames in the row were rendered onto D3DFMT_A8R8G8B8 texture/render target, and then I've been copying that string from texture instead of using ID3DXFont. Strings that weren't rendered for a while, were removed from texture. That gave some serious boost. This solution, however is tricky - monitoring empty space in the texture, removing unused strings, and defragmenting the texture isn't exactly trivial (there is nothing exceptionally complicated, but it is easy to make a mistake). You won't need such complicated system unless your screen is literally covered by text.

野心澎湃 2024-09-13 06:14:20

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

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

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

ID3DXFont fonts are flat, always parallel to the screen. D3DXCreateText are meshes that can be scaled and rotated.

Texture fonts are fuzzy and don't look very clear. Not good for an app that uses lots of small text.

I am writing an app that can create 500 text meshes, each mesh averaging 3,000-5,000 vertices. The text meshes are created once, then are static. I get 700 fps on a GeForce 8800.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文