Fast Text in OpenGL.
By Steve Baker
Sooner or later, almost everyone finds the need to draw text using OpenGL.
There are basically only three ways to do this at the OpenGL level:
Raster Fonts.
Use glBitmap or glDrawPixels to draw a rectangular bunch of pixels onto
the screen. The disadvantages of doing this are many:
- The data describing each character is sent from your CPU to
the graphics card every frame - and for every character in the
frame. This can amount to significant bandwidth.
- The underlying OpenGL implementation will almost certainly
have to 'swizzle' the image data in some manner on it's
way between CPU and frame-buffer.
- Many 3D graphics chips are not designed to draw bitmaps
at all. In this case, the OpenGL software driver must wait
until the 3D hardware has completely finished drawing before
it can get in to splat the pixels directly into the frame
buffer. Until the software has finished doing that, the hardware
is sitting idle.
- Bitmaps and Drawpixels have to be aligned parallel to the edges of
the screen, so rotated text is not possible.
- Scaling of Bitmaps and Drawpixels is not possible.
There is one significant advantage to Raster fonts - and that is that
on Software-only OpenGL implementations, they are likely to be FASTER
than the other approaches...the reverse of the situation on 3D hardware.
Geometric Fonts.
Draw the characters of the font using geometric primitives - lines,
triangles, whatever. The disadvantages of this are:
- The number of triangles it takes to draw some characters can
be very large - especially if you want them to look good.
This can be bad for performance.
- Designing fonts is both difficult and costly.
- Doing fonts with coloured borders, drop-shadows, etc
exacerbates the other two problems significantly.
The advantages are:
- Geometric fonts can be scaled, rotated, twisted, morphed,
extruded.
- You can use fancy lighting models, environment mapping,
texturing, etc.
- If used in a 3D world, you can perform collision detection
with them.
- Geometric fonts scale nicely. They don't exhibit bad
aliasing artifacts and they don't get 'fuzzy' as they
are enlarged.
Texture-Mapped Fonts.
Typically, the entire font is stored in one or two large texture
maps and each letter is drawn as a single quadrilateral.
The disadvantages are:
- The size of the texture map you need may have to be
quite large - especially if you need both upper and
lower case - and/or if you want to make the font look
nice at large point sizes. This is especially a problem
on hardware that only supports limited texture map
sizes (eg 3Dfx Voodoo's can only render maps up to 256x256)
- If you use MIPmapping, then scaling the font makes it
look a litte fuzzy. If you don't use MIPmapping, it'll
look horribly aliasy.
The advantages are:
- Generality - you can use an arbitary full colour image for
each letter of the font.
- Texture fonts can be rotated and scaled - although they
always look 'flat'.
- It's easy to convert other kinds of fonts into texture maps.
- You can draw them in the 3D scene and they will be illuminated
correctly.
- SPEED! Textured fonts require just one quadrilateral to
be sent to the hardware for each letter. That's probably an
order of magnitude faster than either Raster or Geometric
fonts. Since low-end 3D hardware is highly optimised to
drawing simple textured polygons, speed is also enhanced
because you are 'on the fast path' through the renderer.
(CAVEAT: On software-only OpenGL's, textured fonts will
be S-L-O-W.
Links to some Free Font Libraries:
-
The GLUT package contains routines for bitmapped
and geometric fonts (made out of lines in this case).
- glTexFont
seems to be a pretty reasonable Texture-Font package.
- The 'FNT' component
of the PLIB package
does a good job of rendering textured fonts - and comes with over a
dozen fonts in 'TXF' format. FNT is highly portable.
(Since I wrote FNT, I'm a bit biassed).
-
TexFont: this is a good tutorial on OpenGL texture-mapped
text. It also uses the 'TXF' font format and contains a convertor
from X-windows fonts into TXF.
- Font3D converts
fonts into geometry which can be exported into a variety of
model formats.
- GLTT
relies on FreeType and can
dow some amazing effects with all three font rendering mechanisms.
- Standard Microsoft-based OpenGL's have a set of 'wgl'
calls for drawing raster fonts.
Conclusions.
There is no one 'best' way to do text in OpenGL - on balance, I'd go for
Texture-mapped fonts - but YMMV. Fortunately, there are some great freeware
libraries to choose from so you can experiment.