Check out my
new game!

jlongster

The painful state of fonts with OpenGL(ES)

February 8, 2010

Fonts. Ugh. I knew it would be a pain to integrate text rendering in my OpenGLES-based graphics framework. I was able to avoid it for long while using textures, but now that I'm about to publish an iPhone game, there's really no avoiding it any longer.

I begrudgingly opened up google and typed in "opengl font rendering". The first result was A Survey Of OpenGL Font Technology straight from opengl.org.

"There is no native font support in OpenGL. The ARB has rarely ever even discussed fonts." Yes, I knew that, so what options do I have? That page lists a smattering of font rendering libraries, most of them completely unusable due to some major restriction. The only one with potential was FTGL.

Searching for a solution

FTGL turned out to be my best bet, but the only problem was that it targeted OpenGL and I'm working with OpenGLES, which lacks many features of OpenGL. Luckily, it looks like David Petrie ported FTGL to OpenGLES with the cleverly-named project FTGLES.

I'm very thankful for David's work on the port, but I was disappointed to find that I simply couldn't get the library to work. Another minor gripe is that FTGLES only comes with an Xcode project and not autoconf/automake scripts.

So I forked the damn thing and got to work.

At this point, I was frustrated. With all of the games being made on mobile devices in OpenGLES, you would think there would be more options or at least a clear and straightforward solution to text rendering. What are all of you guys doing? And why aren't you releasing or documenting it? Am I missing something? There are a couple good articles on this such as Adding Font support in OpenGL - Acorn Heroes, but that's far from a good reusable library.

FTGL itself could use better documentation. I only found an FTGL User Guide which only contains a tutorial for the basic functionality. There are also a few API reference docs out there, but there really should be readable, helpful, and thorough documentation for a library that seems to be so critical for OpenGL applications (it really seems to be one of the few solutions for font rendering).

We aren't even talking about smart textual layout yet. Writing an OpenGL backend for Pango is really interesting but there's only a proof of concept finished at this point. Supposedly Pango might be too slow for OpenGL applications, so I'll digress. Do games even integrate a textual layout system or do developers do everything manually?

FTGLES

Back to my fork of FTGLES.

I integrated the FTGLES source code with the original FTGL autoconf/automake build system so you can do the standard ./configure && make install. I also fixed a few bugs in the source which make it behave more predictably. I plan to contact David to see where he wants to take it from here, as I don't really like maintaining a separate fork of a project.

FreeType 2 and compiling for iPhone

FTGLES uses FreeType 2 to load TrueType font files, so we need to compile FreeType 2 for the iPhone. At this point I realized that people might need to compile many libraries for the iPhone (requiring cross-compilation to ARM), and it's really annoying to always remember how to configure the project to build correctly for the iPhone.

I created the configure-iphone project to help with this. It is basically a single shell script which wraps around your ./configure call and appends the correct arguments to link with the right iPhone SDK and possibly cross-compile. Please see the project README for more info.

With the configure-iphone utility script, I was able to compile FreeType 2 like so:

By default, configure-iphone installs libraries in /usr/local/iphone, but you can override that with the -d <dir> options. Our libraries would end up in /usr/local/iphone/iPhoneOS3.1.2.

Please note that there are articles such as this one which describe tweaking parts of FreeType 2 in order for it to compile; you do NOT have to do this anymore as far as I'm concerned. Maybe they fixed that in that last couple minor versions, but the above commands compiles FreeType 2 for the iPhone just fine.

Compiling FTGLES

Compiling and installing FTGLES uses similar commands as compiling FreeType 2. You must tell FTGLES where your FreeType 2 library is located. Here is how it would look:

Now just make sure you link with the ftgl library and add /usr/local/iphone/iPhoneOS3.1.2/include and /usr/local/iphone/iPhoneOS3.1.2/lib to your header and library paths. The version and target may change, of course (target being either OS or Simulator).

Using FTGLES

For general information about using FTGL, read through this FTGL User Guide.

The only thing specific to FTGLES is that you must call ftglInitImmediateModeGL to setup the vertex buffers correctly every frame before rendering any of the fonts. It took me a while to figure that out.

Extruded, pixmap, and polygon fonts are not yet supported in the FTGLES port.

The following is some pseudo C code which assumes init is called at the beginning of the program and render is called every frame. It renders the text "Hello, World" with the Batang TrueType font at the screen position (10, 0).

#include "FTGL/ftgles.h"

FTGLFont *font;

void init() {
    font = ftglCreateTextureFont("Batang.ttf");
}

void render() {
    // ... draw stuff ...

    ftglInitImmediateModeGL();

    glMatrixMode(GL_PROJECTION);
    glOrthof(0.0f, width, 0.0f, height, -10.0f, 10.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(10.0f, 0.0f, 0.0f);
    ftglSetFontFaceSize(font, 72);
    ftglRenderFont(font, "Hello, World");
}

Scheme bindings

I have also writting some Scheme bindings, of course, if anyone is interested. Finally, I have OpenGL fonts in Scheme! And of course, my tweening functionality works just fine with fonts.

Roll over, boy!

Woohoo!

Comments are not implemented yet. In the meanwhile, send me an email.