This page provides a simple source code that
draws a string of characters using OpenGL with an (ugly) vector fonts.
The font size and text location are controlled by OpenGL's
transformation matrix, or typically glScale (glScaled or glScalef) for
font size, and glTranslate (glTranslated or glTranslatef) for text
location. Although the fonts don't look good, you don't need to
rely on the operating system in drawing a text with this source code.
Although OpenGL is a very powerful graphics
toolkit, it is not good at drawing a string of characters. If
you need to draw a string of characters using OpenGL, you typically
need to use wglUseFontBitmap in Windows or glXUseXFont in X-Window
environment. Both functions are platform dependent functions,
and thus you lose portability as soon as you use such functions.
You can use #ifdef, #else, and #endif to absorb the portability
problem, but you may not be able to use same fonts in a different
platform. Also you cannot control the font size precisely
because it is controlled by the platform. Sometimes it is
necessary to draw a string in an exact size, but it is often
impossible because the platform controls it. In summary, not
having a standard (and sufficiently sophisticated) way of drawing a
string of characters is a big disadvantage of OpenGL.
I could not avoid this problem when I tried to
implement instrument panels in YSFLIGHT. So I excavated ugly fonts
I've made couple of years ago, and made it usable from OpenGL. I
suppose this small code is useful for someone who has a similar
problem as mine. So I decided to make it open to everyone.
What you need are a source code (uglyfont.cpp),
and a header (uglyfont.h). Put them in
your project, and add #include "uglyfont.h" at the top of your source
file in which you want to draw a string of characters using OpenGL.
You can also download a sample code (sample.cpp)
that shows some usages of the function.
(Screenshot of sample.cpp)
I keep the copyright of uglyfont.cpp, uglyfont.h,
and sample.cpp, but you can use them regardless of the purpose, i.e.,
commercial or non-commercial, open source or proprietary. You do
not need to ask me for the permission. But, I do not take any
responsibilities on the consequences of using these files.
Please use them on your own risks.
Explanation of the Function
The definition of the function that draws a
string of characters is as follows.
void YsDrawUglyFont(const char str,int
|const char str
||String to be drawn.
||If 1, the string will be
centered (explained below)
||If 1 (default), the function
uses OpenGL's display list. Display lists 1400 through
1655 will be used by this function. If it conflicts with
your program, plsase modify const int YsUglyFontBase=1400;
in uglyfont.cpp. Using the display lists will reduce the
transaction between the CPU and the graphics hardware, and thus
improves the performance.
The size of the fonts drawn by this function can
be controlled by glScale (glScalef or glScaled). Without
scaling, the font size is 1.0x1.0x0.0. The bottom left corner of
the rectangular area take by a character is (0,0,0), and the top right
corner is (1,1,0) in the coordinate frame of each character as shown
Hence, the string consists of N letters, the
rectangle that encloses the string can be defined as (0,0,0)-(N,1,0).
If glScalef(0.5,0.5,0.5); is applied before
drawing calling this function, the result will look like:
The following two pictures compare the effect of
centering (the second parameter of this function). If centering
is 0, the origin is left bottom corner of the first letter shown
If centering is 1, the origin is the center of
the string as follows.
When you want to draw a string in 2D, after
setting up the projection matrix, and the modelview matrix (see also
sample.cpp), you can draw a string by writing:
where (x,y) is the origin in the screen
coordinate, and font Wid and fontHei are the size of a letter in
pixels. Note that the second parameter of glScalef is minus.
If you take the top left corner of the screen as the origin, and the
vector (0,1) points downward in the screen coordinate, Y coordinate
must be inverted to make the letters upright.
If you take the bottom left corner of the screen
as the origin, and the vector (0,1) points upward in the screen
coordinate (it's a bit unnatural to me though), you don't need to put
a minus sign in front of fontHei.