mandag 14. juli 2014

[ SDL2 - Part 10 ] Text rendering.

Rendering text

In the previous parts, we've look at how to render rectangles and images, both with and without transparency. Now it's time to look at how we can render text.

Rendering text is tricky. You'll want to be able to render any font, in any size and preferably every possible character. Luckily, with the SDL ttf library, this is easy.


SDL2_ttf, just like SDL2_image, is an additional library for SDL2. It can use just about every font, and you can set the size too!

What's TTF?

TTF, or TrueType Fonts is a type of fonts developed by Apple and Microsoft in the late 90's. True Type Fonts offers a high degree of control on how the font looks. The internals of TTF fonts and how they work isn't important here. The important part is that they're easy to use, will look really nice ( even scaled up. ) And they're also widely used, so finding fonts shouldn't be a problem.


As with SDL2_image, SDL2_ttf is a addon for SDL2 that deals with rendering text and makes it very easy. It is based on libfreetype, a library for writing text using TTF fonts. However, it's not very practical to use. SDL2_TTF makes using it a lot easier. But if you do want to use it yourself, you can take a look at their tutorial.

Setting up SDL2_TTF

Setting up SDL2 requires a tiny bit more work than SDL2_image, but don't be scared, it's still very easy. First we need to install the ttf library.


Installing SDL2_ttf is done exactly like SDL2_image. Just replace SDL2_image with SDL2_ttf


For Linux you can use need to install -lSDL2_ttf or -libSDL2_ttf or -SDL2_ttf ( the actual name might be different in different distributions. )

The linker flag is -lSDL2_ttf

The process is more or less identical to that of setting up SDL2_image.

If you can't find SDL2_ttf in any repositories and it's not installed by default, you might have to compile it yourself. For more information, see my blog post about setting up SDL2.


Similar to setting up SDL2 base.

The difference is that you have to download the development files for SDL2_ttf

And similarly add SDL2_ttf.lib to library includes and add SDL2_ttf.lib to the library flags ( where you previously added )

And with that, it should work.


See the first part of my tutorial. Just install SDL2_ttf instead of SDL2


Unlike SDL2_image does need to be initialized. Why? Because libfreetype, the library that SDL2_ttf builds upon needs to be initlaized, so naturally SDL_ttf needs to be initalized too.

Initializing SDL2_ttf requires a single function :
int TTF_Init()
Just like SDL_Init(Uint32 flags) this function returns -1 on error.

And just like with SDL_Init(Uint32 flags), we should print an error if the function fails. SDL2_TTF has its own function for printing errors :

char *TTF_GetError()
This means our routine for initializing SDL2_ttf will be the same as SDL2, just with the two functions above ( see full code for details. )

Loading fonts

This is the central structure of SDL2_ttf. It holds the font itself, the size and some other style information ( I'll go into this in the next part ). So, in order for us to use an TTF_Font we need to load it. This is done using a load function :
TTF_Font *TTF_OpenFont
    const char *file,
    int ptsize
So, the arguments are
  • const char *file - a pointer to the .ttf file
  • int ptsize - the size of the font
The function returns a NULL pointer of it can't find the file, or there is another error ( like SDL2_ttf isn't initialized. So this too should be handled by priting the error using TTF_GetError(), just like when initializing ttf

Cleaning up fonts

Just like we with SDL_Texture* and SDL_Surface*, we need to clean our fonts when done. This is just as easy for TTF_Fonts as with SDL_Texture* and SDL_Surface*. We simply call a function that does it for us :
   TTF_Font* font

Rendering text

There are three functions you can use to render text, depending on what you want. Let's start with the first one :


This function is used for quick and simple rendering of a text, using a specific font and a font color. The background of this is transparent. Here's the signature:
SDL_Surface *TTF_RenderText_Solid
    TTF_Font *font,
    const char *text,
    SDL_Color fg
The arguments are :
  •  TTF_Font *font - the font to use
  • const char *text - the text to render
  • SDL_Color fg -  the color to use for the text

The function returns the finished SDL_Surface*, or NULL if something went wrong ( like supplying a NULL pointer for font )

The result will look something like this :


This function has the exact same signature as TTF_RenderText_Solid, so I'll just show it without explaining it parameter by parameter :
SDL_Surface *TTF_RenderText_Blended
    TTF_Font *font,
    const char *text,
    SDL_Color fg
So what's the difference between TTF_RenderText_Solid and TTF_RenderText_Blended? The difference is that TTF_RenderText_Solid is very quick, but TTF_RenderText_Blended produces a better result. In our game, we won't be updating our text surfaces all that often, and there's not a lot of them either, so TTF_RenderText_Blended is a good choice.

Here's what TTF_RenderText_Blended looks like :

And here's a comparison between TTF_RenderText_Solid and TTF_RenderText_Blended :

The difference is not huge, but in the actual game it will be more clear. And the difference might also vary from font to font.

The third version is a tiny bit different :


This function will render the text, but with a specified background color.
SDL_Surface *TTF_RenderText_Solid
    TTF_Font *font,
    const char *text,
    SDL_Color fg,
    SDL_Color bg
The arguments are :
  •  TTF_Font *font - the font to use
  • const char *text - the text to render
  • SDL_Color fg -  the color to use for the text
  • SDL_Color bg -  the color to use for the background

So it's almost the same as the other two, just with a third argument for the background color. The return value is also the same as the other two.

The result will look something like this :

An example

Below is a simple example that should run and compile out of the box. For compilation details, look below.

Running it!

Running it is just as simple as with SDL2_image. So that means compilation on Windows is already set up when you installed TTF

Linux / Mac

If you are compiling using the compiler, you have to add -lSDL2_ttf to the compile string like so :
clang++ main.cpp -std=c++11 -o Game -lSDL2 -lSDL2_image -lSDL2_ttf

If you want to run it, you simply do

Updated game code

I have done a bit of cleaning up in the game code. I've added a new Texture class for text, cleaned up include, removed ( and added ) comments, improve delta calculation++ Everything should be explained in comments, but, of course, if you have any questions of any kinds, just comment or contact me, I'll be happy to help.

You can find the code here.

For a full list of my tutorials / posts, click here.

Feel free to comment if you have anything to say, any suggestion or any questions. I always appreciate getting comments.

Ingen kommentarer:

Legg inn en kommentar