SFML community forums

Help => Graphics => Topic started by: wademcgillis on September 09, 2009, 09:44:14 pm

Title: Text Drawing is SLOWWWW!
Post by: wademcgillis on September 09, 2009, 09:44:14 pm
Why is it so slow?

Why does drawing the text dynamically slow it down so much?

Code: [Select]

void draw_text(int x, int y, char* text)
    {
    sf::String displayText = sf::String();
    displayText.SetColor(sf::Color(globalsys::current_color->getRed(),globalsys::current_color->getGreen(),
        globalsys::current_color->getBlue(),255*globalsys::current_alpha));
    displayText.SetFont(globalsys::current_font.font);
    displayText.SetSize(globalsys::current_font.size);
    if (view_enabled)
        displayText.Move(x-view_xview,y-view_yview);
    else
        displayText.Move(x,y);
displayText.SetText(text);
    App.Draw(displayText);
    }
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 09, 2009, 10:23:38 pm
What is "slow" to you? What is your configuration?

How do you use this function? Can you extract a minimal and complete example using this function that is slow?
Title: Text Drawing is SLOWWWW!
Post by: wademcgillis on September 09, 2009, 10:39:31 pm
Slow meaning it drops in frame rate by a lot when I draw large text. Like, drawing 1 piece of text at 12 pt is fine. But when I do 64pt there is a noticeable drop, and when I do 128pt it is awful.

http://www.wademcgillis.com/downloads/fps3D.zip

Right click to draw big text.
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 09, 2009, 11:18:02 pm
It shouldn't be so slow. I'd like to see your code, if possible.
Title: Text Drawing is SLOWWWW!
Post by: Tank on September 10, 2009, 01:39:17 am
I really bet you call that "draw_text" function each frame. Please tell me you're not. ;)
Title: Text Drawing is SLOWWWW!
Post by: wademcgillis on September 10, 2009, 01:41:32 am
I am.
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 10, 2009, 08:49:26 am
Quote
I really bet you call that "draw_text" function each frame. Please tell me you're not.

What's wrong with that? He's just setting up and drawing a graphical string. It's not as if he was loading the font on each call ;)
Title: Text Drawing is SLOWWWW!
Post by: Tank on September 10, 2009, 12:10:26 pm
Quote from: "Laurent"
Quote
I really bet you call that "draw_text" function each frame. Please tell me you're not.

What's wrong with that? He's just setting up and drawing a graphical string. It's not as if he was loading the font on each call ;)

Well, that maybe gives you a hint on how the rest of his program is written. I think it's a total waste of resources and time.

wademcgillis, could you please show us the rest of your (relevant) code?
Title: Text Drawing is SLOWWWW!
Post by: Nexus on September 10, 2009, 12:11:44 pm
Did you profile it and find out what part of code is responsible for the bad frame rate?

And you're not testing in debug mode, are you?
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 10, 2009, 12:20:43 pm
Quote
Well, that maybe gives you a hint on how the rest of his program is written. I think it's a total waste of resources and time.

I agree. But it's perfectly ok to use SFML drawables like this, nothing is wasted.

From the (incomplete) source code I got in PM, I can find only one potential cause for the bad performances. What is the ptototype of the draw_set_font function?
If the font is passed by value rather than by reference, then you're copying the whole font (including its OpenGL texture) everytime you call it.
Title: Text Drawing is SLOWWWW!
Post by: Tank on September 10, 2009, 12:34:09 pm
Quote from: "Laurent"
I agree. But it's perfectly ok to use SFML drawables like this, nothing is wasted.

You must be kidding. ;)

Code: [Select]
sf::String displayText = sf::String();
Standard constructor, assignment. Why not directly assign the text? (this may be optimized by your favorite compiler, but that doesn't mean you shouldn't do it right)


Code: [Select]
displayText.SetColor(sf::Color(globalsys::current_color->getRed(),globalsys::current_color->getGreen(),
        globalsys::current_color->getBlue(),255*globalsys::current_alpha));

Absolute unnecessary sf::Color temporary.

Code: [Select]
displayText.SetFont(globalsys::current_font.font);
displayText.SetSize(globalsys::current_font.size);

Again, this can be done through the constructor, saves calls.

The problem is not within that single function. It's that when it's done everywhere like this (and I think it is), performance will decrease sooner or later.

But okay, it's getting off topic here. ;)
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 10, 2009, 12:59:26 pm
Quote
You must be kidding

Absolutely not ;)

All he does is assigning a few primitive types (either pointer, float or int). Internally, nothing happens until the call to Draw.

I know that this kind of design is globally bad, but some people prefer this C-like approach instead of a clean OO design. And SFML won't be slower for these people.
Title: Text Drawing is SLOWWWW!
Post by: wademcgillis on September 10, 2009, 02:27:27 pm
Oops. I forgot to send the other .h files.
Title: Text Drawing is SLOWWWW!
Post by: Laurent on September 10, 2009, 04:50:43 pm
I was right:
Code: [Select]
void draw_set_font(Font f)
    {
    globalsys::current_font = f;
    }


You're creating / copying / destroying a huge amout of data and resources on every call.

This should be like this:
Code: [Select]
const sf::Font* current_font;

void draw_set_font(const Font& f)
{
    globalsys::current_font = &f;
}
Title: Text Drawing is SLOWWWW!
Post by: wademcgillis on September 10, 2009, 06:30:07 pm
Oh wow... THANK YOU!