FontPack Main Page

About gamefontgl

gamefontgl is the companion library to FontPack. It provides facilities for loading font metrics files and rendering them using OpenGL.

Since most games/opengl applications provide their own texture management subsystem, gamefontgl does not try to reimplement that. This way, your font texture can be treated just like any other texture in your game.

This is great, as long as you have a texture management system. If you don't, you could use DevIL's image support for openGL. Eventually, there will be another higher-level layer to gamefontgl that will provide texture loading and advanced formatting but it isn't implemented yet.


This tutorial

This tutorial provides a simple demonstration of using gamefontgl. It serves as an introduction and a tour of its features.

1. Preparation

First, you need a font to use. You can use fontpack to generate one, there is a tutorial on the main page.

Now, presently, gamefontgl expects RGBA textures, but fontpack outputs RGB textues with a "key color" for transparency. You can use something like photoshop or gimp to convert it and add the alpha channel.

Fortunately, it's pretty easy. For example, in Photoshop:
  1. Load the RGB font image.
  2. Select->Color Range, Click on the background
  3. Select->Invert Selection
  4. Edit->Copy, Edit Paste
  5. In the "Layers" palette, delete the background layer
  6. Save it as something that supports transparency, such as PNG or TIFF.
Or just skip all this and use the "fatmarker512.png" that comes with the gamefontgl example.

2. The Code

Now I'm going to take apart a simplified version of the testfontgl.cpp example program.

#include <stdio.h>
#include <string.h>
#include "gamefontgl.h"

#include <GL/gl.h>
#include <GL/glut.h>

#include <il/il.h>
#include <il/ilu.h>
#include <il/ilut.h>

const int c_Width = 800, c_Height = 600;
const char *c_displayMode = "800x600:16@60";

int main( int argc, char **argv ) 
{
    
    glutInitWindowPosition ( 0, 0 ) ;
    glutInitWindowSize( c_Width, c_Height );
    
    glutInit( &argc, argv ) ;
    glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
    
    if ((argc==2) && (!strcmp(argv[1], "-fullscreen"))) {    
		glutGameModeString( c_displayMode );
		glutEnterGameMode();
    } else {  
		glutCreateWindow( "Font Test/Demo"  ) ;
    }

    // initilize IL
    ilInit();

    glClearColor( 0.5, 0.5, 1, 1.0 );
    
    glutDisplayFunc( cbDisplay ) ;

    glDisable(GL_DEPTH_TEST );
    glutMainLoop () ;

    return 0;
}
Ok, so far this is all pretty standard for a glut program. The only things worth noticing are that we included 'gamefontgl.h', and since we're using DevIL's ilutGL library for texture management, we've initialized it when we initialize the glut stuff.

3. Using the font

This is the cbDisplay function that will do our drawing. Because it's a simple program, we'll do all the initialization in here, too.

void cbDisplay()
{
    static bool initialized = false;
    static unsigned int fontId, texFont;
    static int count = 0;

    if (!initialized) {
        ilutRenderer( ILUT_OPENGL );
		
	// Load the font image
	ilGenImages( 1, &ilutFontId );
	ilBindImage( ilutFontId );
	
	if (!ilLoadImage( "fatmarker512.png" )) {
	    printf("Loading image failed\n");
	}
		
	texFont = ilutGLBindTexImage();

Ok, so if this is the first time this function has been called, we need to load our textures and stuff. This is how ilut loads textures. In the end, it doesn't matter, you just need an openGL texture ID.
					
 		
	// Create a font by passing in an opengl texture id
	fontId = gfCreateFont( texFont );

Ok, here's the good part. First, we need to create a font. All you do is call gfCreateFont with the texture ID. It returns a fontID that you can use whenever you want to use that font.
					
		
	// A .finfo file contains the metrics for a font. These
	// are generated by the Fontpack utility.
	gfLoadFontMetrics( fontId, "fatmarker512.finfo");

	printf("font has %d chars\n", 
			gfGetFontMetric( fontId, GF_FONT_NUMCHARS ) );

Now that the font is created and assigned a texture, it needs to know where the characters are located on that texture. This is stored in the .finfo file generated by fontpack. gfLoadFontMetrics will load this file.
You can query the font with gfGetFontMetric.
		
	gfEnableFont( fontId, 64 );
	
	initialized = true;
    }

You can enable the font by passing in the pixel size that you want. You must have created the point size in fontpack.
And now we're done initializing and can draw something.

    // Clear the screen    	
    glClear( GL_COLOR_BUFFER_BIT );

Now draw something. The preceding code just clears the screen. Yay.

Replacing this with an exciting game engine is left as an exercise to the reader.

    // Now draw some text on top.

    // Use gfBeginText(), gfDrawString() and gfEndText() to draw text.
    glColor3f( 1.0, 1.0, 1.0 );
    gfEnableFont( fontId, 64 );

    gfBeginText();
    glTranslated( 300, 100, 0 );
    gfDrawString("Hello World!\nWhats up?" );
    gfEndText();

Now the fun can begin. And by "fun" I simply mean the drawing of text.
This is the simplest way to use gamefontgl, just gfBeginText(), then glTranslate to where you want the text to go (in screen coordinates), and then gfEndText()when you're done.

    glutSwapBuffers();
}

And that's it!

The complete testfontgl.cpp program contains some more example of usage, including using glScale to make smaller characters, using gfDrawStringFmt which acts like printf, and using gfGetStringWidth and gfGetStringHeight to draw a box around the "Hello World". It also draws a spinning quad to prove that text can coexist peacefully alongside your 3d game engine.
Back to Main Page