Jump to content
  • Advertisement
Sign in to follow this  
Pseelo

[SlimDX] Text Drawing efficiency (DrawString)

This topic is 3612 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I have a problem with drawing text. I use C# + SlimDX and I've just found out that DrawString dramatically slows my application down. Let's say I have 20 text objects. Each of them (and for every frame) is drawn with following code:
fontSprite.Transform = Matrix.Translation(box.X, box.Y, 0.5f);
fontSprite.Begin(SpriteFlags.AlphaBlend);
font.DrawString(fontSprite, text, rect, DrawTextFormat.Left, color);
fontSprite.End();

fontSprite and font are static (one pair for all the text objects) and loaded with:
fontSprite = new Sprite(device);
font = new SlimDX.Direct3D9.Font(device, Settings.TextHeight, 
  0, FontWeight.Normal, 0, false, CharacterSet.Default,
  Precision.Default, FontQuality.ClearTypeNatural, PitchAndFamily.DontCare, "tahoma");

Unfortunately, when I add 20 more objects (or increase their length two times), my FPS rate goes down significantly. My application displays a lot of text, so I am afraid that when it goes to draw an average scene (200+ text objects), the FPS will fall under 20. I hope something can be done because the objects change their "text" property very rarely - that is once for 10-60 seconds, so probably their "look" (the effect of the DrawString method) can be cached somehow as something more efficient to display. What can I do to speed up the drawing process? I've read some posts about PreloadText but the code was in C++/Pure DirectX and I just cannot use it with C#/SlimDX. I mean, I see that font has a method called PreloadText, but can it be used to improve my application's efficiency? Best regards. Chris.

Share this post


Link to post
Share on other sites
Advertisement
Avoid calling Begin/End on the sprite for each Font object you render. Call Begin, then call DrawString multiple times on the same sprite, then call End.

The reason you're seeing a performance hit is that DX likes working in large batches. Each batch is a Begin/End pair, and you're using too many small batches, instead of one large batch.

Hope this helps.

Share this post


Link to post
Share on other sites
Yes, it helped a lot.
I performed two tests:

1. The old way:

for (int i = 0; i < 200; i++)
{
TextLine.fontSprite.Transform = Matrix.Translation(i * 3, i * 3, 0.5f);
TextLine.fontSprite.Begin(SpriteFlags.AlphaBlend);
TextLine.font.DrawString(TextLine.fontSprite, "test", new Rectangle(0, 0, 100, 100), DrawTextFormat.Center, new Color4(1f, 0, 0, 0));
TextLine.fontSprite.End();
}



2. Your method:

TextLine.fontSprite.Begin(SpriteFlags.AlphaBlend);
for (int i = 0; i < 200; i++)
{
TextLine.fontSprite.Transform = Matrix.Translation(i * 3, i * 3, 0.5f);
TextLine.font.DrawString(TextLine.fontSprite, "test", new Rectangle(0, 0, 100, 100), DrawTextFormat.Center, new Color4(1f, 0, 0, 0));
}
TextLine.fontSprite.End();



The second loop was drawn four times faster.
Thanks, Sirob.

BTW: Can anyone explain me how to use the mentioned PreloadText method? Maybe this can be drawn even faster using it?

Best regards.
Chris.

[Edited by - Pseelo on November 30, 2008 4:35:00 AM]

Share this post


Link to post
Share on other sites
PreloadText, as the name says, preloads a text to improve rendering.

1) Save device state
2) Preload text in loading objects
3) Restore device state
4) Check new performaces.

Share this post


Link to post
Share on other sites
@XVincentX:
I'm planning to make myself a t-shirt with your motto: "PreloadText, as the name says, preloads a text to improve rendering".

But seriously speaking - as I said earlier, I cannot use the PreloadText or I do something wrong with it. I tried to use it just after the static font object (SlimDX.Direct3D9.Font class) is created. I tried also text preloading within a frame rendering code. In both cases there was no change in performance.

So - one more time - can anybody tell me what is the proper use of the method PreloadText? (please, don't try to explain to me what is the meaning of preloading text - a sample code snippet will be greatly appreciated).

Best regards.
Chris.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!