Monogame使用Graphics.DrawString(而不是SpriteBatch.DrawString)渲染文本

时间:2015-01-25 13:21:36

标签: monogame drawstring spritebatch spritefont

使用Graphics.DrawString向屏幕外位图呈现(相当静态)一组文本,将其转换为Texture2D一次,然后只需调用SpriteBatch.Draw,是否有任何不利之处,而不是使用内容管道和使用SpriteFont呈现文本?这基本上是一个文本页面,绘制在一张纸上,然后用户也可以选择调整字体大小,这意味着我必须包含不同大小的spritefonts。

由于这是一个仅限Windows的应用程序(不打算移植它),我可以访问所有字体,例如普通的WinForms应用程序,我相信使用Graphics.DrawString时渲染质量会更好(甚至是TextRenderer)而不是使用精灵字体。

此外,似乎性能可能会更好,因为SpriteBatch.DrawString需要"渲染"每次迭代中的整个文本(即分别为每个字母发送顶点),而使用位图我只做一次,所以在CPU端的工作量应该稍微少一点。

  1. 我在这里没有看到任何问题或缺点吗?
  2. 是否可以使用spritefonts获取alpha混合文本?我已经看过周围提到的Nuclex框架,但它没有被移植到Monogame AFAIK。
  3. [更新]

    从技术方面来看,它似乎比通过精灵字体更好地完成文本渲染。如果它们是水平渲染的,我甚至会得到ClearType。可能存在的一个问题是字体的spritesheets(可能是?)在纹理内存方面比为文本页面创建单独的纹理更有效。

2 个答案:

答案 0 :(得分:1)

似乎没有任何缺点
实际上,您似乎遵循文本呈现的标准方法。

正确呈现文字'与渲染纹理四边形相比,处理速度相对较慢,即使SpriteFonts剪切掉所有拼接字形,如果渲染文本页面,那么您仍然可以拼出大量三角形。

每当我一直在寻找GL / XNA的不同文本渲染解决方案时,人们倾向于推荐您的方法。将文本墙一次绘制为可重复使用的纹理,然后渲染该纹理。

您可能还想将 RenderTarget2D 视为可移植的解决方案。
举个例子:

NSData* data =...

然后在场景渲染中,您可以// Render the new text on the texture LoadPageText(int pageNum) { string[] text = this.book[pageNum]; GraphicsDevice.SetRenderTarget(pageTarget); // TODO: draw page background this.spriteBatchCache.Begin(); for (int i = 0; i < text.Length; i++) { this.spriteBatchCache.DrawText(this.font, new Vector2(10, 10 + this.fontHeight * i), text[i], this.color); } this.spriteBatchCache.End(); GraphicsDevice.SetRenderTarget(null); } 渲染文本。 这样,您只需要1个 all 页面的纹理,只需记住在字体更改时重绘。

要考虑的其他事项是您的SpriteBatches排序模式,有时在渲染许多三角形时可能会影响性能。

在第2点,正如我上面提到的,SpriteFonts是预渲染纹理,这意味着透明度被烘焙到它们的spritesheet上。因此,默认库似乎不使用透明度/抗锯齿。

如果你渲染它们两倍大而白色在黑色上并使用SourceColor作为alpha通道然后渲染它们缩小与Color.Black混合你可以得到它。

答案 1 :(得分:0)

请尝试使用指针进行颜色混合:

MixedColor = ((Alpha1 * Channel1) + (Alpha2 * Channel2))/(Alpha1 + Alpha2)