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


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.

SDL2 TTF?


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.

Installation


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

Linux


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.

Windows


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 SDL2_image.lb )

And with that, it should work.

Mac


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

Initialization


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_CloseFont
(
   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 :

TTF_RenderText_Solid


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 :


TTF_RenderText_Blended


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 :

TTF_RenderText_Shaded


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
./Game

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