⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.cpp

📁 小型的3D游戏引擎
💻 CPP
字号:
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#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;
	}
}

///////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -