Skip to content


Bitmapped fonts

Due to the fact that OpenGL ES does not provide any kind of fonts, we need think a way to create the characters and display them efficiently.

In order to use fonts in OpenGL ES, we will use a widely used technique called: bitmapped fonts. That is, we store into a texture all characters of a font (there are many programs that produces this kind of textures). The texture will be black (0,0,0) in the places that we want it will be transparent (we will not render the whole quad, only the character inside), and white (1,1,1) in the places we want to see (the character itself). This will allow us, with a blend function of (GL_ONE, GL_ONE).

Because we have a white color, we can safely use glColor4x call to color our font.

Also, we need the right texture coordinates to isolate the right character in the texture, so we will precompute all texture coordinates for characters from 0 to 127 (our texture has 128 characters) in order to access directly to them in runtime, and draw a textured-blended-quad (actually, a triangle strip, because we do not have quads…).

So first we will create a suitable texture, with all characters that we will need. This texture has 8 rows and 16 columns, and each cell has 16×16 texels, and the characters are stored in the ASCII order. We need to isolate the texture coordinates of a character, so we do the next computations:

const float rows = 8.0f;
const float columns = 16.0f;
const float xoffset = 1.0f / columns;
const float yoffset = 1.0f / rows;

const float cx = (float)(c % 16) * xoffset;
const float cy = (float)(c / 16) * yoffset;

Where c is the ASCII code of the character we want to access, substracting 32, because in our texture we do not store the first 32 ASCII characters. cx and cy are the initial position, in both axis, of the character. With these two values we have the texture coordinates of the first corner of the quad.

The BitmappedFont class will encapsulate all this code:

class BitmappedFont {

public:
BitmappedFont(GLuint textureFontID, int fontWidth = 15, int fontHeight = 15);
~BitmappedFont();
static void EnableStates(); //Begin Print
void Print(int x, int y, const char *fmt, …);
static void DisableStates(); //EndPrint

private:
GLuint m_textureFontID;
int m_fontWidth,m_fontHeight;
//2 = st, 4 = vertices per character, 8 = rows, 16 = columns
static GLfixed m_textureCoordinates[2 * 4 * 8 * 16];
//boolean to compute texture coordinates only when the first instance is created
static bool m_instanced;
};

Posted in Code Samples, Windows Mobile.

Tagged with , , , .


5 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Rodrigues says

    Hahahaha! You stay happy with bit-mapped fonts lady! Tonight I’ve rendered truetype fonts in windows mobile using openGL ES APIs.
    Nobody can do that except me! I challenge you over this and I ll show you my code if u come up with yours. Else, enjoy ROMANIA! Hehehe!

  2. Rodrigues says

    I do openGL ES font rendering in Native Windows platform and avoid the use of wrappers like glut because the use of glut compromises with speed and performance.So, define glutTrueTypeString using windows API.

  3. Tomis says

    Haven’t tried it using glES, but i know it can be done. Check it out glutes.sourceforge.net .

    In my opinion it’s quite useful to use something this because you can switch fonts as you please (don’t like arial? try something else..), change size dinamically (maintaining font quality) and so on.

    I guess it depends on what you need the font for.

  4. Anca A, says

    Have you tried this for OpenGL ES or just for OpenGL?

  5. Tomis says

    I usually use TrueType fonts. Once you get the hang of it it’s not that difficult. They look better too, and it’s less of a hastle when you want to switch the font familly.
    There are a lot of TT libraries that make your life easier. Good luck.



Some HTML is OK

or, reply to this post via trackback.