Texture Fonts
Home -->
Programming Projects -->
FPS Game Code -->
Texture Fonts
Simple Solution
Suppose we want to render text in a computer game with
doing as little work as possible.
A nice solution is to have a texture
that contains all the ascii characters from 32 to 126
inclusive, and to draw quads with appropriately selected
texture coordinates for verticies.
For example, we could use the following texture:
Well, we don't actually want to use that picture because
it is a .jpg, so we should use the
.tga
version instead.
Notice that this .tga file has an alpha component.
In order to render a string of text, we should first call
this command to get OpenGL ready for rendering flat stuff:
void PrepForFlatDrawing() {
glDisable(GL_CULL_FACE);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
Next, we should call the following function:
void DrawScreenText(
float x, float y,
float w, float h,
const string & text)
{
if( text.size() > 0 ) {
glBegin(GL_QUADS);
}
for (int i = 0; i < (int)text.length(); ++i) {
unsigned char c = text[i];
if ( c == 32 )
c = 128;
if (c < 33 || c > 128 )
c = 127;
float s = (1+32*((int)((c-33)%16))) / 512.0f;
float t = (1+47*((int)((c-33)/16))) / 512.0f;
glTexCoord2f(s, t+0.091f);
glVertex3f(x, y, 0);
glTexCoord2f(s, t);
glVertex3f(x, y+h, 0);
glTexCoord2f(s+0.0625f, t);
glVertex3f(x+w, y+h, 0);
glTexCoord2f(s+0.0625f, t+0.091f);
glVertex3f(x+w, y, 0);
x += w;
}
if( text.size() > 0 ) {
glEnd();
}
}
The texture and the DrawScreenText function are
both due to Zach Barth,
originally intended for Infinifrag 2.
More General Solution
The texture in the above section was created
using photoshop.
Suppose we want to modify this texture.
We would have to make sure that all
the important characters are in the
same location, otherwise the function
DrawScreenText will not work correctly.
Hence, we would have to be very careful.
There are programs that can
generate these "font textures".
I personally like
Bitmap Font Builder,
however I am told that the program
Bitmap Font Generator
is excellent
(it outputs Kerning Pairs).
When using such a program, the output texture will
not necessarily have characters in the same
positions as the above texture.
For example,
this
font texture which is used in version 1.0 of
Block Arena.
What we need is a more general function
than DrawScreenText that can use
texture coordinates specified by a file.
We can specify the appropriate texture coordinates
in a text file with the following format:
each line is of the form
"ascii_char min_u min_v max_u max_v"
The convention is that
u = 0 is the left side of the texture,
and v = 0 is the bottom of the texture.
Here
is an example such file to be used with
this texture:
32 0.012 0.812 0.050 0.875
33 0.075 0.812 0.113 0.875
34 0.137 0.812 0.175 0.875
35 0.200 0.812 0.238 0.875
36 0.262 0.812 0.300 0.875
37 0.325 0.812 0.363 0.875
38 0.387 0.812 0.425 0.875
39 0.450 0.812 0.488 0.875
40 0.512 0.812 0.550 0.875
41 0.575 0.812 0.613 0.875
42 0.637 0.812 0.675 0.875
43 0.700 0.812 0.738 0.875
44 0.762 0.812 0.800 0.875
45 0.825 0.812 0.863 0.875
46 0.887 0.812 0.925 0.875
47 0.950 0.812 0.988 0.875
48 0.012 0.750 0.050 0.812
49 0.075 0.750 0.113 0.812
50 0.137 0.750 0.175 0.812
51 0.200 0.750 0.238 0.812
52 0.262 0.750 0.300 0.812
53 0.325 0.750 0.363 0.812
54 0.387 0.750 0.425 0.812
55 0.450 0.750 0.488 0.812
56 0.512 0.750 0.550 0.812
57 0.575 0.750 0.613 0.812
58 0.637 0.750 0.675 0.812
59 0.700 0.750 0.738 0.812
60 0.762 0.750 0.800 0.812
61 0.825 0.750 0.863 0.812
62 0.887 0.750 0.925 0.812
63 0.950 0.750 0.988 0.812
64 0.012 0.688 0.050 0.750
65 0.075 0.688 0.113 0.750
66 0.137 0.688 0.175 0.750
67 0.200 0.688 0.238 0.750
68 0.262 0.688 0.300 0.750
69 0.325 0.688 0.363 0.750
70 0.387 0.688 0.425 0.750
71 0.450 0.688 0.488 0.750
72 0.512 0.688 0.550 0.750
73 0.575 0.688 0.613 0.750
74 0.637 0.688 0.675 0.750
75 0.700 0.688 0.738 0.750
76 0.762 0.688 0.800 0.750
77 0.825 0.688 0.863 0.750
78 0.887 0.688 0.925 0.750
79 0.950 0.688 0.988 0.750
80 0.012 0.625 0.050 0.688
81 0.075 0.625 0.113 0.688
82 0.137 0.625 0.175 0.688
83 0.200 0.625 0.238 0.688
84 0.262 0.625 0.300 0.688
85 0.325 0.625 0.363 0.688
86 0.387 0.625 0.425 0.688
87 0.450 0.625 0.488 0.688
88 0.512 0.625 0.550 0.688
89 0.575 0.625 0.613 0.688
90 0.637 0.625 0.675 0.688
91 0.700 0.625 0.738 0.688
92 0.762 0.625 0.800 0.688
93 0.825 0.625 0.863 0.688
94 0.887 0.625 0.925 0.688
95 0.950 0.625 0.988 0.688
96 0.012 0.562 0.050 0.625
97 0.075 0.562 0.113 0.625
98 0.137 0.562 0.175 0.625
99 0.200 0.562 0.238 0.625
100 0.262 0.562 0.300 0.625
101 0.325 0.562 0.363 0.625
102 0.387 0.562 0.425 0.625
103 0.450 0.562 0.488 0.625
104 0.512 0.562 0.550 0.625
105 0.575 0.562 0.613 0.625
106 0.637 0.562 0.675 0.625
107 0.700 0.562 0.738 0.625
108 0.762 0.562 0.800 0.625
109 0.825 0.562 0.863 0.625
110 0.887 0.562 0.925 0.625
111 0.950 0.562 0.988 0.625
112 0.012 0.500 0.050 0.562
113 0.075 0.500 0.113 0.562
114 0.137 0.500 0.175 0.562
115 0.200 0.500 0.238 0.562
116 0.262 0.500 0.300 0.562
117 0.325 0.500 0.363 0.562
118 0.387 0.500 0.425 0.562
119 0.450 0.500 0.488 0.562
120 0.512 0.500 0.550 0.562
121 0.575 0.500 0.613 0.562
122 0.637 0.500 0.675 0.562
123 0.700 0.500 0.738 0.562
124 0.762 0.500 0.800 0.562
125 0.825 0.500 0.863 0.562
126 0.887 0.500 0.925 0.562
The above file was generated
by this
python script.
It is easy to write a class
that reads in the above file
on construction and uses this
information for drawing text.
Here is
the header file and
here is
the source file to accomplish this.
A nice advantage of this more general
solution is it allows the end user to
completely customize the texture
font that is being used
(without recompiling)!