Jump to content
  • Advertisement
Sign in to follow this  
BiiXteR

How to display variables in SDL_TTF

This topic is 1083 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

As the title says I want to display a variable on screen, which I already have done using this : 

std::stringstream strm;
strm << FramesPassed;
FPS_Text_Surface = TTF_RenderText_Solid(Sans, strm.str().c_str(), Color_White);

However, this is called in a Init function which is called at the start of the game, and if I place it in my draw function it takes around 100mb of ram every 20 seconds.

 

How can I display a variable on screen, which updates when the variable does?

Like If I want to display score on screen, the code I currently use doesn't change to 1 when someone scores, it stays at 0 even if the score variable is 10000.

 

Hopefully this made some sense... :P

Share this post


Link to post
Share on other sites
Advertisement
Put the call in the render loop, and draw the result to the screen.

You do have to release the produced FPS_Text_Surface surface after use, (as is documented in the TTF_RenderText_Solid function description).

Share this post


Link to post
Share on other sites

Put the call in the render loop, and draw the result to the screen.

You do have to release the produced FPS_Text_Surface surface after use, (as is documented in the TTF_RenderText_Solid function description).

Alright, did that but now it doesn't display anything at all :/

Share this post


Link to post
Share on other sites

 

However, this is called in a Init function which is called at the start of the game,
...
Like If I want to display score on screen, the code I currently use doesn't change to 1 when someone scores, it stays at 0 even if the score variable is 10000.

TTF_RenderText_Solid() says "Make this text into an image."
If you call it once, it only makes the text at the time of the function call into the image. It doesn't keep track of the variables you passed it.
 

and if I place it in my draw function it takes around 100mb of ram every 20 seconds.

It sounds like you are using Window's Task Manager to measure your performance and memory usage. That doesn't give you accurate measurements, because it's measuring how much RAM and CPU power the OS is currently making available to your program, not how much RAM your program is actually using.
 

How can I display a variable on screen, which updates when the variable does?

Every time you need to draw, then:

1) Create the image with the current text
2) Draw the image
3) Free the image

Do that first, to make sure it's working. Then move on to below.

Creating the image is time-consuming, and doing it every single frame is bad for performance.
So instead, you want to do:
Every time you need to draw, then:

1) If the text (your score) has changed since the previous frame...
1.1) Free the image (if it's already been created)
1.2) Create the image with the current text
2) Draw the image

99) In your destructor (when the game is exiting), free the image

You need to do this for every different bit of text in your game. (i.e. re-use one surface for the score, another for health, another for the menu text, and so on).

 

You can wrap this in a class for safety and convenience:

class TextSurface
{
public:
    TextSurface() = default;
    ~TextSurface()
    {
       SDL_FreeSurface(surface);
    }
    
    void SetColor(const SDL_Color &color)
    {
       //If we already had this color set, don't bother updating.
       if(this->color == color)
           return;
       
       this->color = color;
       needToRegenerate = true;
    }

    void SetText(const std::string &text)
    {
       //If we already had this text set, don't bother updating.
       if(this->text == text)
           return;
       
       this->text = text;
       needToRegenerate = true;
    }
    
    //WARNING: Ownership is not transferred. You must make sure the font continues to exist.
    void SetFont(TTF_Font *font)
    {
       //If we already had this font set, don't bother updating.
       if(this->font == font)
           return;
       
       this->font = font;
       needToRegenerate = true;
    }
    
    void Draw(......)
    {
        if(needToRegenerate) regenerateSurface();
        
        SDL_ASSERT(SDL_BlitSurface(surface, ..., screen, ...) == 0, "SDL_BlitSurface failed");
    }
    
private:
    void regenerateSurface()
    {
       SDL_FreeSurface(surface);
       surface = TTF_RenderText_Solid(font, test.c_str(), color);
       SDL_ASSERT(surface != nullptr, "TTF_RenderText_Solid returned null");

       needToRegenerate = false;
    }

private:
    TTF_Font *font = nullptr;
    SDL_Surface *surface = nullptr;
    std::string text;
    SDL_Color color;
    bool needToRegenerate = true;
};

///===================================================================
//Convenience functions located elsewhere:
///===================================================================

//So we can do "if(myColor == anotherColor)".
bool operator==(const SDL_Color &colorA, const SDL_Color &colorB)
{
    return (colorA.r == colorB.r) && (colorA.g == colorB.g)
    && (colorA.b == colorB.b) && (colorA.a == colorB.a);
}

//For error-checking.
#define SDL_ASSERT(equation, message) SDL_Assert((equation)), #equation, message, __PRETTY_FUNCTION__, __FILE__, __LINE__)

void SDL_Assert(bool valid, const char *equationString, const char *message, const char *function, const char *file, int line)
{
    if(valid) return;

    std::cerr << "SDL_Assert() : \" " << equation << " \" on line " << line << " of " << function << " in file: " << file
              << "\n\t" << message << " : " << SDL_GetError() << std::endl;

    std::exit(EXIT_FAILURE);
}

This worked, thanks! :D

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!