I'm playing around with MonoGame, and I've noticed the SpriteFont class draws static text very inefficiently. Each time the text is drawn the spacing is recalculated. This isn't a big deal on my quad core PC, but on mobile applications it might be a problem.

Before I go and program some text which caches the arrangement of its letters in an array and then feeds that array to the SpriteBatch, I would like to make sure there isn't something available to do this already, either in MonoGame itself or a class someone has implemented and made available for general use.

  • 3
    \$\begingroup\$ "but on mobile applications it might be a problem" Is it actually a problem yet? Don't spend too much time on pre-optimizing something that might not need optimizing at all. \$\endgroup\$ – Marton Nov 25 '12 at 9:38
  • \$\begingroup\$ Just to second Marton here: Even though it could be faster (at the expense of memory, mind you!), it's probably not worth optimising because, if you're drawing enough text for it to matter, your text will be unreadable! \$\endgroup\$ – Andrew Russell Nov 25 '12 at 14:20
  • \$\begingroup\$ It was an issue with slower phones on Android using Java/LibGDX when only printing a single line. LibGDX has a BitmapFontCache class for this very reason. You're right though, as I'm just making a game for fun and don't even know if I'll be running it on Android, I'm guilty of premature optimization here. Still, if someone has already made such a class, I may as well use it. \$\endgroup\$ – Casey Nov 25 '12 at 15:17

you can convert the spritefont into a Texture2D (RenderTarget inherits from Texture2d i think)

as described in this article http://nullcandy.com/particle-text-in-xna-and-javascript/

Vector2 size = font.MeasureString(text) + new Vector2(0.5f);
int width = (int)size.X;
int height = (int)size.Y;

RenderTarget2D target = new RenderTarget2D(device, width, height);

SpriteBatch spriteBatch = new SpriteBatch(device);
spriteBatch.DrawString(font, text, Vector2.Zero, Color.White);

device.SetRenderTarget(null);   // unset the render target

// read back the pixels from the render target
Color[] data = new Color[width * height];

if required it may be possible to create your text this way

| improve this answer | |

One option is to use bitmap font rendering instead.


| improve this answer | |
  • \$\begingroup\$ This is essentially the solution that already exists. The draw method is recalculating the spacing of the text 60 times a second. \$\endgroup\$ – Casey Nov 26 '12 at 0:18
  • 1
    \$\begingroup\$ Ah I see, sorry I didn't fully understand the performance bottleneck. Personally I'd just optimise it later once you know how much static vs dynamic text you're actually going to need. \$\endgroup\$ – craftworkgames Nov 26 '12 at 2:43
  • \$\begingroup\$ you can write your own text drawing system, its pretty easy. But, this should not really be an issue since the calculations for drawing text are pretty simple \$\endgroup\$ – CobaltHex Nov 26 '12 at 3:10
  • \$\begingroup\$ Actually the SpriteFont will be interpreted on the pipeline stage and will be converted to a bitmap font. \$\endgroup\$ – Gustavo Maciel Aug 12 '14 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.