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; } } ///////////////////////////////////////////////////////////////////////////////////////