I have created, by modifying the 3D Text tutorial, a "fonter" class that, when constructed, sets up the font display lists, and has a Print function that prints the string passed to it. The Print function also takes a horizontal and vertical size, and scales the string so that if the Print function were called and the sizes were both 1.0, the string would be constrained to a square or if the x size was 3.0 and the vertical size was 1.0, the string would be three times as long as it is high.
The problem is that my strings are appearing slightly too far to the right. This makes things look bad and means that I cannot implement rotation of the strings properly.
Here''s the constructor for the "fonter" class:
fonter::fonter(char* fontname, bool italic, bool underline, bool strikeout, HDC &hDC)
{
HFONT font; // Windows Font ID
base = glGenLists(256); //base is a private member of the fonter class
font = CreateFont( -24, // Height Of Font
0, // Width Of Font
0, // Angle Of Escapement
0, // Orientation Angle
FW_BOLD, // Font Weight
italic, // Italic
underline, // Underline
strikeout, // Strikeout
ANSI_CHARSET, // Character Set Identifier
OUT_TT_PRECIS, // Output Precision
CLIP_DEFAULT_PRECIS, // Clipping Precision
ANTIALIASED_QUALITY, // Output Quality
FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch
fontname); // Font Name
SelectObject(hDC, font); // Selects The Font We Want
wglUseFontOutlines( hDC, // Select The Current DC
0, // Starting Character
255, // Number Of Display Lists To Build
base, // Starting Display Lists
0.0f, // Deviation From The True Outlines
0.05f, // Font Thickness In The Z Direction
WGL_FONT_POLYGONS, // Use Polygons, Not Lines
gmf); // Address Of Buffer To Recieve Data - gmf is a private member of the fonter class
}
Here''s the implementation of the Print function:
GLvoid fonter::Print(GLfloat xsiz, GLfloat ysiz, const char *text)
{
GLfloat length = 0.0f; //Length of the font, before scaling
GLfloat height = 0.0f; //Height " "
GLfloat xscl = 1.0f; //Factors to scale by to get the desired size.
GLfloat yscl = 1.0f;
GLfloat thisheight; //A temp variable
if (text == NULL) // If There''s No Text
return; // Do Nothing
for (unsigned int wloop=0;wloop<(strlen(text));wloop++) // Loop To Find Text Length
{
length+=gmf[text[wloop]].gmfBlackBoxX; // Increase Length By Each Characters Width
}
for (unsigned int hloop=0;hloop<(strlen(text));hloop++)
{
thisheight = gmf[text[hloop]].gmfBlackBoxY;
if (height < thisheight) //It just bases the height off the tallest character in the string.
height = thisheight; //Later it might do something about drop characters (like "g".)
}
xscl = xsiz/length; //Finds the factor to scale by
yscl = ysiz/height;
glEnable(GL_COLOR_MATERIAL);
glScalef(xscl, 1.0f, 1.0f); //Scales
glScalef(1.0f, yscl, 1.0f);
glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits
glListBase(base); // Sets The Base Character to 32
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text
glPopAttrib(); // Pops The Display List Bits
glDisable(GL_COLOR_MATERIAL);
}
Here is a place my program creates a "fonter":
settingsfont = new fonter("Impact", 0, 0, 0, hDC);
Here is a place I call the Print function for text 2 units long and 0.4 units high:
settingsfont->Print(2.0f, 0.4f, "TANK-(P)ONG");
See if you can guess what game I am making from the string! Thanks for your help,
Tim