Drawing text with OpenGL
OpenGL is a graphics library and it can draw anything you like, even characters. But OpenGL is a very low level library and leaves drawing characters as an exercise to the programmer. There are a number of approaches you can use to draw text:
- make a "stick font" in which all characters are made up out of lines. This looks really crappy but might be OK for an eighties style 3D vector game.
- make an outline font in which all the outline of characters are drawn as lines. This looks fun but again, for an eighties style 3D vector game. Not only that, it also takes a lot of work to define the vertices for all characters.
- load a bitmap font and use glBitmap() to render the characters. This is acceptable but mind that bitmap fonts do not scale well to today's high resolution displays. The characters will look pixelated and blocky when scaled up.
- use textures; every character is a rendered texture of an image of a character. This works well but it takes a lot of effort to correctly create the textures for every character. Again, mind the scale. If you scale too high, it will look pixelated and blocky.
Pitfall #1: Getting FTGL to work
To use FTGL, you should #include "FTGL/ftgl.h". If that produces an error about ft2build.h, you should also install the Freetype development package. Point your include path (gcc -I) and linker path (gcc -L) at the right places.
Pitfall #2: Using orthogonal mode correctlyFTGL can render text on a plane in 3D space, but in general you switch to orthogonal mode using glOrtho() before rendering text. The origin should be set to the lower left or you may get strange results like text appearing upside down. Also, set the current pen color before drawing. That's easy.
Pitfall #3: Using glTranslate*() with raster fonts
FTGL supports two "raster" fonts: GLBitmapFont and GLPixmapFont. GLBitmapFont looks terrible and I would never want to use it, but GLPixmapFont looks nice. One reason to prefer GLPixmapFont over GLTextureFont is performance, another reason might be that it doesn't use texture memory. However, since it is a raster font, you can not scale nor rotate it. You must position using glRasterPos*(). The fact that you can't scale the font makes it less useful because it doesn't give nice results at small sizes. Which brings us to the next point.
Pitfall #4: Font sizesYou might be inclined to think that with ftglSetFontSize() you could set a font's size to 12 points and then get a good result on screen. If only it were that simple. In practice, you might see a blurry mess or even nothing at all. Why is this?
Fonts are rendered using dots per inch. OpenGL, however, has its own coordinate system. You initialized it by calling glOrtho(). Personally, I tend to set glOrtho() to pixel coordinates. Pixel coordinates have no relation to dots per inch, so it doesn't fit. [In theory, you should be able to set OpenGL's coordinate system to dots per inch and get good results right away, but haven't tried this. My guess is that this won't work either because of the following.]
When loading a texture font, FTGL creates textures for every character (or glyph) using the size and resolution parameters passed to ftglSetFontSize(). If you choose the parameters too small, the texture will be small and the result will be ugly. The key is to use fairly high values like 72 or simply one hundred. This may well cause the displayed text to appear huge; scale the result down again with glScale*() one tenth times or whatever works for you.
Since OpenGL is very good at scaling textured images, the end result will be good looking. Isn't it kind of dumb to use a large font size and then scale it down again? Yes, but if you don't, chances are that it won't be good looking.
Pitfall #5: Font scalingThis is pitfall is a consequence of scaling. When you scale the FTGL font, you must take the scale into account when working with bounding boxes and string widths.
FTGL is a very nice OpenGL font rendering library with good performance. It has an easy to use C++ API and good standard C interface. The documentation is a bit lacking though. For example, to get the string width in standard C, use ftglGetFontAdvance() * scale.
Let me end with a link into the FTGL User Guide at SourceForge.