www.pudn.com > QuadTreeLOD4cs.rar > Text.cpp, change:2003-06-12,size:19576b


// Text.cpp: implementation of the CText class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include <stdio.h> 
#include "Text.h" 
#include "gamehead.h" 
#include "gamewnd.h" 
#define MAX_CHARS	256									 
 
// This defines how high we want our font to be 
#define FONT_HEIGHT	32 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
CText::CText() 
{ 
/*	FrameTime0=0; 
	FrameTime1=0; 
	FrameCount0=0; 
	FrameCount1=0; 
	FrameRate=0;*/ 
	m_nInfo = 0; 
} 
bool CText::makeRasterFont() 
{ 
GLubyte rasters[][13] = { 
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36},  
{0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00},  
{0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18},  
{0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70},  
{0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e},  
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c},  
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30},  
{0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00},  
{0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00},  
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03},  
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c},  
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18},  
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e},  
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e},  
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c},  
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},  
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},  
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff},  
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},  
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e},  
{0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06},  
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60},  
{0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e},  
{0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18},  
{0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},  
{0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},  
{0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc},  
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff},  
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff},  
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e},  
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},  
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e},  
{0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06},  
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3},  
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},  
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3},  
{0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3},  
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e},  
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},  
{0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c},  
{0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe},  
{0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e},  
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff},  
{0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},  
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},  
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3},  
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},  
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3},  
{0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff},  
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c},  
{0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60},  
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18},  
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70},  
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},  
{0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03},  
{0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e},  
{0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0},  
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00},  
{0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00},  
{0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0},  
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78},  
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},  
{0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00},  
{0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00},  
{0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},  
{0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00},  
{0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f},  
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},  
{0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0},  
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00}  
}; 
 
    GLuint i; 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    fontOffset =glGenLists (128); 
	if(fontOffset!=0) 
	{ 
        for (i = 32; i  127; i++) 
		{ 
            glNewList(i+fontOffset, GL_COMPILE); 
                glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, rasters[i-32]); 
            glEndList(); 
 
		} 
	} 
	else 
		return false; 
 
    return true; 
} 
 
bool CText::InitRasterText() 
{ 
    if(!makeRasterFont()) 
		return false; 
	return true; 
} 
 
void CText::PrintString(char *string) 
{ 
    glPushAttrib (GL_LIST_BIT); 
        glListBase(fontOffset); 
        glCallLists(strlen(string), GL_UNSIGNED_BYTE,string); 
    glPopAttrib (); 
} 
 
void CText::Draw() 
{ 
	glDisable(GL_TEXTURE_2D); 
	for(int i = 0;i<m_nInfo;i++) 
	{ 
		glRasterPos3f(m_Info[i].x,m_Info[i].y,m_Info[i].z); 
		PrintString(m_Info[i].sInfo); 
	} 
	glEnable(GL_TEXTURE_2D); 
} 
 
CText::~CText() 
{ 
	glDeleteLists(fontOffset,128); 
 
} 
//extern CGameWnd::m_hWnd; 
void CText::CreateOpenGLFont(LPSTR strFontName, int height)	// Build Our Bitmap Font 
{ 
	UINT	fontListID = 0;								// This will hold the base ID for our display list 
	HFONT	hFont;										// This will store the handle to our font 
 
 
	// Here we generate the lists for each character we want to use. 
	// This function then returns the base pointer, which will be 1 because 
	// we haven't created any other lists.  If we generated another list after 
	// this, the base pointer would be at 257 since the last one used was 256 (which is MAX_CHARS) 
	fontListID = glGenLists(256);					// Generate the list for the font 
 
	// Now we actually need to create the font.  We use a windows function called: 
	// CreateFont() that returns a handle to a font (HFONT).  Our CreateOpenGLFont() 
	// function allows us to pass in a name and height.  For simplistic reasons, I left 
	// other options out, but feel free to add them to your function (like bold, italic, width..) 
 
	hFont = CreateFont(	height,							// Our desired HEIGHT of the font 
						0,								// The WIDTH (If we leave this zero it will pick the best width depending on the height) 
						0,								// The angle of escapement 
						0,								// The angle of orientation 
						FW_BOLD,						// The font's weight (We want it bold) 
						FALSE,							// Italic - We don't want italic 
						FALSE,							// Underline - We don't want it underlined 
						FALSE,							// Strikeout - We don't want it strikethrough 
						ANSI_CHARSET,					// This is the type of character set 
						OUT_TT_PRECIS,					// The Output Precision 
						CLIP_DEFAULT_PRECIS,			// The Clipping Precision 
						ANTIALIASED_QUALITY,			// The quality of the font - We want anitaliased fonts 
						FF_DONTCARE|DEFAULT_PITCH,		// The family and pitch of the font.  We don't care. 
						strFontName);					// The font name (Like "Arial", "Courier", etc...) 
 
	// Now that we have created a new font, we need to select that font into our global HDC. 
	// We store the old font so we can select it back in when we are done to avoid memory leaks. 
	HFONT hOldFont = (HFONT)SelectObject(GetDC(CGameWnd::m_hWnd), hFont); 
 
	// This function does the magic.  It takes the current font selected in 
	// the hdc and makes bitmaps out of each character.  These are called glyphs. 
	// The first parameter is the HDC that holds the font to be used. 
	// The second parameters is the ASCII value to start from, which is zero in our case. 
	// The third parameters is the ASCII value to end on (255 is the last of the ASCII values so we minus 1 from MAX_CHARS) 
	// The last parameter is the base pointer for the display lists being used.  This should be 1. 
 
	wglUseFontBitmaps(GetDC(CGameWnd::m_hWnd), 0, 256 - 1, fontListID);	// Builds 255 bitmap characters 
 
	m_fontLstID =  fontListID;									// Return the ID to the display list to use later 
} 
void PositionText( int x, int y ) 
{ 
	// If you are to use this font code for your applications, 
	// you must be aware that you cannot position the font in 3D, 
	// which means you can't rotate and scale it.  That will be covered in 
	// the next font tutorial.  BUT, though that might be a drag, this code 
	// is useful because when you display the text, it will always be on top 
	// of everything else.  This is good if the camera is moving around, and you 
	// don't want the text to move.  If the text was positioned in 3D you would have 
	// to come up with a tricky way of making it always render in front of the camera. 
	// To do this, we need to set the Raster Position.  That is the position that OpenGL 
	// starts drawing at.  Since it's in floating point, it's not very intuitive, so what 
	// we do is create a new view port, and then always draw the text at (0, 0, 0) in that 
	// view port.  The weird part is that the Y is flipped, so (0, 0) is the bottom left corner. 
	// Below we do some simple math to flip it back to normal. 
 
	// Before we create a new view port, we need to save the current one we have. 
	// This saves our transform (matrix) information and our current viewport information. 
	// At the end of this function we POP it back. 
	glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT ); 
 
	// Here we use a new projection and modelview matrix to work with. 
	glMatrixMode( GL_PROJECTION );						// Set our matrix to our projection matrix 
	glPushMatrix();										// Push on a new matrix to work with 
	glLoadIdentity();									// reset the matrix 
	glMatrixMode( GL_MODELVIEW );						// Set our matrix to our model view matrix 
	glPushMatrix();										// Push on a new matrix to work with 
	glLoadIdentity();									// Reset that matrix 
 
	// Because the Y is flipped, we want 0 to be at the top, not bottom. 
	// If we subtract the font height from the screen height, that should display the 
	// font at the top of the screen (if they passed in 0 for Y), but then we subtract 
	// the Y from that to get the desired position.  Since the font's drawing point is 
	// at the base line of the font, we needed to subtract the font height to make sure 
	// if they passed in (0, 0) it wouldn't be off screen.  If you view this in window mode, 
	// the top of the window will cut off part of the font, but in full screen it works fine. 
	// You just need to add about 25 to the Y to fix that for window mode. 
 
	y = 600 - FONT_HEIGHT - y;				// Calculate the weird screen position 
 
	// Now we create another view port (that is why we saved the old one above). 
	// Since glViewPort takes the lower LEFT corner, we needed to change the Y 
	// to make it more intuitive when using PositionText().  We minus 1 from the X and Y 
	// because 0 is taken into account with the position.  The next 2 parameters are set 
	// to 0 for the width and height so it will always draw in the middle of that position. 
	// glRasterPos4f() takes (0, 0, 0) as the middle of the viewport, so if we give it a small 
	// width/height it will draw at the X and Y given.  Sounds strange, to test this, try 
	// using glRasterPos4f(0, 0, 0, 1) instead of PositionText() and you will see, everything 
	// will be drawn from the middle. 
 
	glViewport( x - 1, y - 1, 0, 0 );					// Create a new viewport to draw into 
 
	// This is the most important function in here.  This actually positions the text. 
	// The parameters are (x, y, z, w).  w should always be 1 , it's a clip coordinate. 
	// don't worry about that though.  Because we set the projection and modelview matrix 
	// back to the beginning (through LoadIdentity()), the view port is looking at (0, 0, 0). 
	// This is the middle, so if we set the drawing position to the middle, it will draw at our 
	// X and Y because the width/height of the viewport is 0, starting at X and Y. 
	// You can actually call this function (or glRasterPos2f(0, 0)) instead of PositionText(), 
	// but it is in floating point and doesn't work as nicely.  You will see why if you try. 
 
	glRasterPos4f( 0, 0, 0, 1 );						// Set the drawing position 
 
	// Now that we positioned the raster position, any text we draw afterwards will start 
	// from that position.  Now we just have to put everything else back to normal. 
 
	glPopMatrix();										// Pop the current modelview matrix off the stack 
	glMatrixMode( GL_PROJECTION );						// Go back into projection mode 
	glPopMatrix();										// Pop the projection matrix off the stack 
 
	glPopAttrib();										// This restores our TRANSFORM and VIEWPORT attributes 
} 
void CText::glDrawText(int x, int y, const char *strString, ...) 
{ 
	char		strText[256];							// This will hold our text to display 
	va_list		argumentPtr;							// This will hold the pointer to the argument list 
 
	// If you have never used a va_list, listen up.  Remember printf()? 
	// or sprintf()?  Well, you can add unlimited arguments into the text like: 
	// printf("My name is %s and I am %d years old!", strName, age); 
	// Well, that is what va_list's do.   
 
	// First we need to check if there was even a string given 
	if (strString == NULL)								// Check if a string was given 
		return;											// Don't render anything then 
 
	// First we need to parse the string for arguments given 
	// To do this we pass in a va_list variable that is a pointer to the list of arguments. 
	// Then we pass in the string that holds all of those arguments. 
	va_start(argumentPtr, strString);					// Parse the arguments out of the string 
 
	// Then we use a special version of sprintf() that takes a pointer to the argument list. 
	// This then does the normal sprintf() functionality. 
	vsprintf(strText, strString, argumentPtr);			// Now add the arguments into the full string 
 
	va_end(argumentPtr);								// This resets and frees the pointer to the argument list. 
 
	// Before we draw the text, we need to position it with our own function. 
	PositionText(x, y);									// Call our own function to position the text on screen 
 
	// Now, before we set the list base, we need to save off the current one. 
	glPushAttrib(GL_LIST_BIT);							// This saves the list base information 
 
	// Then we want to set the list base to the font's list base, which should be 1 in our case. 
	// That way when we call our display list it will start from the font's lists'. 
	glListBase(m_fontLstID);							// This sets the lists base 
 
	// Now comes the actually rendering.  We pass in the length of the string, 
	// then the data types (which are characters so its a UINT), then the actually char array. 
	// This will then take the ASCII value of each character and associate it with a bitmap. 
	glCallLists(strlen(strText), GL_UNSIGNED_BYTE, strText); 
 
	glPopAttrib();										// Return the display list back to it's previous state 
} 
 
 
 
int CText::AddText(float x, float y, float z, char *str) 
{ 
	if(m_nInfo>=MAXINFO) 
		return -1; 
	m_Info[m_nInfo].x  = x; 
	m_Info[m_nInfo].y  = y; 
	m_Info[m_nInfo].z  = z; 
	strcpy(m_Info[m_nInfo].sInfo,str); 
	m_nInfo++; 
	return m_nInfo-1; 
} 
 
void CText::EditItem(int nID, float x, float y, float z, char *str) 
{ 
	m_Info[nID].x  = x; 
	m_Info[nID].y  = y; 
	m_Info[nID].z  = z; 
	strcpy(m_Info[nID].sInfo,str); 
}