|
glDisable(GL_LIGHTING);
glEnable(GL_LIGHTING);
glColor3f();
glGenLists();
glDeleteLists();
glBindTexture();
glNewList();
glBegin();
glEnd();
glTexCoord2f();
glVertex2i();
glTranslated();
glEnable(GL_BLEND);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glPopMatrix();
glLoadIdentity();
glOrtho();
glListBase();
glScalef();
glCallLists();
|
|
|
Zdrojový kód bitmap fontů a část popisů funkcí vytvořil kolega
Jiří Studnička (Well). Jirko děkuju.
Abychom mohli vytvořit bitmap fonty, budeme k tomu potřebovat obrázek s fontama.
Ten vypadá takto:
Z tohoto obrázku pomocí texturových koordinací vyřízneme znak po znaku a pro každý
znak vytvoříme čtverec s texturou znaku. Pak čtverce poskládáme za sebou, podle zvoleného
textu. To je základní princip. Teď mrknem, jak to udělat.
Nejdříve si v konstruktoru třídy K_CBMPFont vytvoříme 256 Display Listů.
Každý Display List bude později obsahovat jeden znak.
|
|
// Konstruktor
K_CBMPFont::K_CBMPFont()
{
iBase = glGenLists(256); // Vytvoř 256 Display Listů
}
|
A budeme volat funkci InitBMP()
|
|
// Inicializuj font
K_CBMPFont::InitBMP()
{
if(!LoadFont()) // Jestliže nepude načíst font, tak
return FALSE; // Ukonči funkci
float f_coord_x; // X texturová koordinace
float f_coord_y; // Y texturová koordinace
glBindTexture(GL_TEXTURE_2D, iFontTexture); // Nastav texturu fontu
for (int loop = 0; loop <
256; loop++) // Cykluj podle počtu 256 Display Listů
{
f_coord_x = float(loop % 16) / 16.0f; // Vypočítej X texturovou koordinaci aktuálního znaku
f_coord_y = float(loop / 16) / 16.0f; // Vypočítej Y texturovou koordinaci aktuálního znaku
glNewList(iBase + loop, GL_COMPILE); // Vytvoř Display List pro aktuální znak Start Building A List
glBegin(GL_QUADS); // Začni vykreslovat čtverec s aktuálním znakem
glTexCoord2f(f_coord_x,1 - f_coord_y - 0.0625f); // Nastav texturovou koordinace pro levý dolní vrchol
glVertex2i(0,0); // Vykresli levý dolní vrchol
glTexCoord2f(f_coord_x + 0.0625f, 1 - f_coord_y - 0.0625f); // Nastav texturovou koordinace pro pravý dolní vrchol
glVertex2i(16,0); // Vykresli pravý dolní vrchol
glTexCoord2f(f_coord_x + 0.0625f, 1 - f_coord_y); // Nastav texturovou koordinace pro pravý horní vrchol
glVertex2i(16,16); // Vykresli pravý horní vrchol
glTexCoord2f(f_coord_x, 1 - f_coord_y); // Nastav texturovou koordinace pro levý horní vrchol
glVertex2i(0,16); // Vykresli levý horní vrchol
glEnd(); // Konec vykreslování čtverce s aktuálním znakem
glTranslated(10,0,0); // Posuň aktuální znak o 10 vpravo
glEndList(); // Konec definice Display Listu
}
return TRUE; // Pokud dojdeš až sem, tak vrať funkci true
}
|
Která do všech Display Listů uloží hodnoty pro vykreslování znaků. Než však začne
hodnoty ukládat, tak se snaží otevřít obrázek voláním funkce
LoadFont()
|
|
// Načti bitmap font
K_CBMPFont::LoadFont()
{
iFontTexture = texture.LoadGLTexture("textures/bmpfont/font.bmp"); // Načti bitmap font
if(!iFontTexture) // Pokud se nepodařilo načíst font, tak
return FALSE; // Vrať funkci false
return TRUE; // Jinak vrať funkci true
}
|
Funkce InitBMP() se volá jen jednou při inicializaci scény.
|
|
K_CBMPFont *pbmpfont; // Bitmap font
//----------------------------------------------------------------------------------------------------//
// Načti scénu
void K_CScene::InitScene( void )
{
...
...
...
pbmpfont = new K_CBMPFont(); // Alokuj paměť pro bitmap font
pbmpfont->InitBMP(); // Nastav bitmap font
...
...
...
}
|
Nakonec funkce OutText()
|
|
// Vykresli bitmap font
void K_CBMPFont::OutText(int i_x, int i_y, int i_width, int i_height, char *pc_string)
{
float f_width, f_height; // Pomocné proměnné pro výšku a šířku textu
f_width = (float) (i_width * 0.01); // Šířku textu převeď na procenta
f_height = (float) (i_height * 0.01); // Výšku textu převeď na procenta
glEnable(GL_BLEND); // Zapni průhlednost
glBlendFunc(GL_ONE, GL_ONE); // Vše, co je černé je průhledné
glBindTexture(GL_TEXTURE_2D, iFontTexture); // Nastav texturu fontu
glDisable(GL_DEPTH_TEST); // Vypni testování Depth Bufferu
glMatrixMode(GL_PROJECTION); // Nastav projekční matici
glPushMatrix(); // Ulož do zásobníku projekční matici
glLoadIdentity(); // Resetuj projekční matici
glOrtho(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT, -100, 100); // Nastav pozici textu podle velikosti zobrazovací plochy
glMatrixMode(GL_MODELVIEW); // Nastav modelovou matici
glPushMatrix(); // Ulož do zásobníku modelovou matici
glLoadIdentity(); // Resetuj modelovou matici
glTranslated(i_x, i_y, 0); // Nastav pozici textu
glListBase(iBase - 32 + (128)); // Nastav počáteční znak (0, nebo 1)
glScalef(f_width, f_height, 0); // Zmenši, nebo zvětši text podle hodnot šířky a výšky
glCallLists(strlen(pc_string), GL_BYTE, pc_string); // Vykresli výsledný text
glMatrixMode(GL_PROJECTION); // Nastav projekční matici
glPopMatrix(); // Obnov předešlou modelovou matici
glMatrixMode(GL_MODELVIEW); // Nastav modelovou matici
glPopMatrix(); // Obnov předešlou projekční matici
glEnable(GL_DEPTH_TEST); // Zapni testování Depth Bufferu
glDisable(GL_BLEND); // Vypni průhlednost
}
|
Vykreslí text.
Parametry: i_x, i_y je pozice v okně (dle nastavení SCREEN_WIDTH, SCREEN_HEIGHT (640, 480)),
i_width, i_height jsem přidal pro možnost výpisu textu v libovolné velikosti.
Udává se v procentech. Může překračovat i 100 takže když u obou parametrů
i_width i i_height zadáme 200, tak text bude 2x větší než ve skutečnosti je BMP font a
to v obou osách (i_x, i_y). No a char *pc_string je asi jasný
Funkce OutText() se volá v nekonečné smyčce při vykreslování scény
|
|
K_CBMPFont *pbmpfont; // Bitmap font
K_CTimer timer; // Časovač
//----------------------------------------------------------------------------------------------------//
// Vykresli scénu
void K_CScene::DrawScene( void )
{
...
...
...
// Výpočet hodnot velikosti pro text dle časovače
static bool b = false; // Nastav při startu aplikace proměnnou přepínače na false
static int i_width = 100, i_height = 100; // Nastav při startu aplikace proměnné velikosti textu
if(timer.GetTime() >=5.0) // Prováděj výpočty každých 5 milisekund
{
if(!b) // Jesliže je hodnota přepínače false, tak
{
i_width += 1; // Zvětši šířku textu
i_height += 1; // Zvětši výšku textu
}
else // Pokud je hodnota přepinače true, tak
{
i_width -= 1; // Zmenši šířku textu
i_height -= 1; // Zmenši výšku textu
}
if(i_width == 150) // Jestliže je šířka rovna 150, tak
b = !b; // Přepni přepínač
if(i_width == 100) // Jestliže je šířka rovna 100, tak
b = !b; // Přepni přepínač
timer.Reset(); // Resetuj časovač
}
glDisable(GL_LIGHTING); // Vypni světlo
glColor3f(0.0f, 1.0f, 0); // Nastav barvu textu
pbmpfont->OutText(20, 20, i_width, i_height, "Developers: Jiri Studnicka & Jan Koci"); // Vykresli text
glColor3f(1.0f, 1.0f, 1.0f); // Nastav barvu na bílou
glEnable(GL_LIGHTING); // Zapni světlo
}
|
Jak vidíte, tak před samotným vykreslováním textu tu máme jednoduchý výpočet
změny velikosti textu, který se zvětšuje a zmenšuje. Výpočet se volá každých 5
milisekund, nezávisle na aktuálním FPS.
Příště zkusíme načíst QuakeIII scénu, ze
souboru BSP.
|
|
Home