www.pudn.com > Gimcrack-v0.0051-Source.zip > font.cpp


#include  
#include  
#include  
#include "../global.h" 
#include "../loader/loader.h" 
#include "../loader/bitmap.h" 
#include "../loader/targa.h" 
#include "font.h" 
 
 
/////////////////////////////////////////////////////////////////////////////////////// 
 
GcFont::GcFont(): 
scale(0.5f), 
texWidth(0), 
texHeight(0) 
{ 
	// Constructing the font object 
} 
 
/////////////////////////////////////////////////////////////////////////////////////// 
 
GcFont::~GcFont() 
{ 
	// Destructing the font object 
} 
 
/////////////////////////////////////////////////////////////////////////////////////// 
 
bool GcFont::Build(char *fontFile, int sCols, int sRows, int sWidth, int sHeight, int sSpacing) 
{ 
	// Save the settings 
	colums = sCols; 
	rows = sRows; 
	width = sWidth; 
	height = sHeight; 
	spacing = sSpacing; 
 
	// Create the texture 
	if(!LoadTexture(fontFile)) { 
		return false; 
	} 
 
	// Character coords 
	float cx, cy; 
	 
	// Char width in tex coords 
	float cwx, cwy; 
 
	cwx = (1.0f / texWidth) * width; 
	cwy = (1.0f / texHeight) * height; 
 
	// Generate a display list 
	base = glGenLists(colums * rows);		 
 
	// Bind the texture 
	glBindTexture(GL_TEXTURE_2D, fontID); 
 
	// Loop thorught all characters 
	for(int i = 0; i < (colums * rows); i++) 
	{ 
		// Get the x and y coord for current char 
		cx = float(i % colums) * cwx; 
		cy = float(i / rows) * cwy; 
 
		// Start bulding the list 
		glNewList(base + i, GL_COMPILE); 
 
			glBegin(GL_QUADS); 
 
				glTexCoord2f(cx, 1 - cy - cwy); 
				glVertex2i(0,0); 
 
				glTexCoord2f(cx + cwx, 1 - cy - cwy); 
				glVertex2i(width, 0); 
 
				glTexCoord2f(cx + cwx, 1 - cy); 
				glVertex2i(width, height); 
 
				glTexCoord2f(cx, 1 - cy); 
				glVertex2i(0, height); 
 
			glEnd(); 
 
			// Move to the right of the character 
			glTranslatef((float)spacing, 0.0f, 0.0f); 
 
		glEndList(); 
	} 
 
	return true; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////// 
 
void GcFont::Print(char *str, int x, int y) 
{ 
	glPushMatrix(); 
		 
		// Enable blending 
		glEnable(GL_BLEND); 
		glBlendFunc(GL_ONE, GL_SRC_COLOR); 
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
 
		// Use the font texture 
		glBindTexture(GL_TEXTURE_2D, fontID); 
 
		// Translate the the correct position 
		glTranslated(x, y + height, 0); 
 
		// Scale the font 
		glScalef(scale, scale, 0); 
 
		// Set the correct starting position 
		glListBase(base - 32); 
 
		// Print the text 
		glCallLists(strlen(str), GL_BYTE, str); 
 
		// Disable dlending 
		glDisable(GL_BLEND); 
 
	glPopMatrix(); 
} 
 
/////////////////////////////////////////////////////////////////////////////////////// 
 
bool GcFont::LoadTexture(char *fileName) 
{ 
	// Looping vars 
	int x, y, j = 0; 
 
	// Create the bitmap to use for loading the texture 
	GcLoader *bitmap; 
 
	// Find out which file format to use 
	if((fileName[strlen(fileName)-3] == 'b') &&  
	   (fileName[strlen(fileName)-2] == 'm') &&  
	   (fileName[strlen(fileName)-1] == 'p')) 
	{ 
		bitmap = new GcBitmap; 
	} 
	else if((fileName[strlen(fileName)-3] == 't') &&  
			(fileName[strlen(fileName)-2] == 'g') &&  
			(fileName[strlen(fileName)-1] == 'a')) 
	{ 
		bitmap = new GcTarga; 
	} 
	else 
	{ 
		MessageBox(NULL, "Wrong font file format", "Error", MB_OK); 
		return false; 
	} 
 
	// Load the image 
	if(!bitmap->Load(fileName))	{ 
		MessageBox(NULL, "Can't load sprite", "Error", MB_OK); 
		return false; 
	} 
 
	// Save the widht and height 
	texWidth = bitmap->Width(); 
	texHeight = bitmap->Height(); 
 
	 
	if(bitmap->Bpp() != 32) 
	{ 
		/* This bitmap don't have a alpha chanel, so create one */ 
 
		// The frame 
		byte *frame = new byte[texWidth * texHeight * 4]; 
 
 
		// Extract the frame 
		for(y = 0; y < bitmap->Height(); y++) 
		{ 
			for(x = 0; x < bitmap->Width() * 3; x += 3) 
			{ 
				frame[j] = bitmap->Image((bitmap->Width() * 3 * y) + (3 + x)); 
				frame[j+1] = bitmap->Image((bitmap->Width() * 3 * y) + (3 + x) + 1); 
				frame[j+2] = bitmap->Image((bitmap->Width() * 3 * y) + (3 + x) + 2); 
				 
				// Check if it's the color key (if so sett to completely transparent) 
				if((frame[j] == COLORKEY_RED) && (frame[j+1] == COLORKEY_GREEN)  
					&& (frame[j+2] == COLORKEY_BLUE))  
				{ 
					// Alpha set to 0 
					frame[j+3] = 0; 
				} 
				else  
				{ 
					// Alpah set to full 
					frame[j+3] = 255; 
				} 
 
				j += 4; 
			} 
		} 
 
		// Generate the texuture 
		glGenTextures(1, &fontID); 
		glBindTexture(GL_TEXTURE_2D, fontID); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight,  
					 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->Image()); 
 
		// Free the memory 
		bitmap->Destroy(); 
		delete bitmap; 
		delete [] frame; 
 
		return true; 
	} 
	else 
	{ 
		/* Already has a alpha chanel */ 
 
		// Generate the texuture 
		glGenTextures(1, &fontID); 
		glBindTexture(GL_TEXTURE_2D, fontID); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight,  
					 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->Image()); 
 
		// Free the memory 
		bitmap->Destroy(); 
		delete bitmap; 
 
		return true; 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////////////////