Po vysv∞tlenφ bitmapov²ch a 3D font∙ v p°edchozφch dvou lekcφch jsem se rozhodl napsat lekci o mapovßnφ textur na fonty. Jednß se o tzv. automatickΘ generovßnφ koordinßt∙ textur. Po doΦtenφ tΘto lekce budete um∞t namapovat texturu opravdu na cokoli - zcela snadno a jednoduÜe.
Stejn∞ jako v minulΘ a p°edminulΘ lekci je k≤d specifick² pro Windows. Pokud by m∞l n∞kdo na platform∞ nezßvisl² k≤d sem s nφm a jß napφÜu nov² tutorißl o fontech.
#include <windows.h>// HlaviΦkov² soubor pro Windows
#include <math.h>// HlaviΦkov² soubor pro matematickou knihovnu
#include <stdio.h>// HlaviΦkov² soubor pro standardnφ vstup/v²stup
#include <gl\gl.h>// HlaviΦkov² soubor pro OpenGL32 knihovnu
#include <gl\glu.h>// HlaviΦkov² soubor pro Glu32 knihovnu
#include <gl\glaux.h>// HlaviΦkov² soubor pro Glaux knihovnu
HDC hDC = NULL;// Privßtnφ GDI Device Context
HGLRC hRC = NULL;// Trval² Rendering Context
HWND hWnd = NULL;// Obsahuje Handle naÜeho okna
HINSTANCE hInstance;// Obsahuje instanci aplikace
bool keys[256];// Pole pro uklßdßnφ vstupu z klßvesnice
bool active = TRUE;// Ponese informaci o tom, zda je okno aktivnφ
bool fullscreen = TRUE;// Ponese informaci o tom, zda je program ve fullscreenu
GLuint base;// Ukazatel na prvnφ z display list∙ pro font
GLuint texture[1];// Uklßdß texturu
GLuint rot;// Pro pohyb, rotaci a barvu textu
P°i psanφ funkce nahrßvajφcφ font jsem ud∞lal malou zm∞nu. Pokud jste si spustili program, asi jste na prvnφ pohled nenaÜli ten font - ale byl tam. VÜimli jste si poletujφcφ pirßtskΘ lebky se zk°φ₧en²mi kostmi. Prßv∞ ona je jeden znak z pφsma Wingdings, kterΘ pat°φ mezi tzv. symbolovΘ fonty.
GLvoid BuildFont(GLvoid)// Vytvo°enφ fontu
{
GLYPHMETRICSFLOAT gmf[256];// Uklßdß informace o fontu
HFONT font;// Prom∞nnß fontu
base = glGenLists(256);// 256 znak∙
font = CreateFont(-12,// V²Üka
0,// èφ°ka
0,// ┌hel escapement
0,// ┌hel orientace
FW_BOLD,// TuΦnost
FALSE,// Kurzφva
FALSE,// Podtr₧enφ
FALSE,// P°eÜkrtnutφ
Mφsto ANSI_CHARSET podle stylu lekce 14, pou₧ijeme SYMBOL_CHARSET. Tφm °ekneme Windows∙m, ₧e vytvß°en² font nenφ typick²m pφsmem tvo°en²m znaky, ale ₧e obsahuje malΘ obrßzky (symboly). Pokud byste zapomn∞li zm∞nit tuto °ßdku, pφsma typu Wingdings, webdings a dalÜφ, kterß zkouÜφte pou₧φt, nebudou vykreslovat symboly (lebka ...), ale normßlnφ znaky (A, B ...).
SYMBOL_CHARSET,// Znakovß sada
OUT_TT_PRECIS,// P°esnost v²stupu (TrueType)
CLIP_DEFAULT_PRECIS,// P°esnost o°ezßnφ
ANTIALIASED_QUALITY,// V²stupnφ kvalita
FF_DONTCARE|DEFAULT_PITCH,// Rodina a pitch
"Wingdings");// JmΘno fontu
SelectObject(hDC, font);// V²b∞r fontu do DC
wglUseFontOutlines(hDC,// Vybere DC
0,// PoΦßteΦnφ znak
255,// Koncov² znak
base,// Adresa prvnφho znaku
PoΦφtßm s v∞tÜφ hranatostφ. To znamenß, ₧e se OpenGL nebude dr₧et obrys∙ fontu tak t∞sn∞. Pokud zde p°edßte 0.0f, vÜimnete si problΘm∙ spojen²ch s mapovßnφm textur na zak°ivenΘ roviny. Povolφte-li jistou hranatost, v∞tÜina problΘm∙ zmizφ. (Jß (p°ekladatel) jsem ₧ßdnΘ problΘmy s 0.0f nem∞l, dokonce to vypadalo o dost lΘpe.)
0.1f,// Hranatost
0.2f,// Hloubka v ose z
WGL_FONT_POLYGONS,// Polygony ne drßt∞n² model
gmf);// Adresa bufferu pro ulo₧enφ informacφ.
}
K nahrßnφ textur p°idßme k≤d, kter² u₧ znßte z p°edchozφch tutorißl∙. Vytvo°φme mipmapovanou texturu, proto₧e vypadß lΘpe.
int LoadGLTextures()// Vytvo°φ texturu
{
int Status=FALSE;// Indikuje chyby
AUX_RGBImageRec *TextureImage[1];// Mφsto pro obrßzek
memset(TextureImage,0,sizeof(void *)*1);// Nastavφ ukazatel na NULL
if (TextureImage[0]=LoadBMP("Data/Lights.bmp"))// Nahraje bitmapu
{
Status=TRUE;
glGenTextures(1, &texture[0]);// Generuje texturu
// Vytvo°φ lineßrn∞ mipmapovanou texturu
glBindTexture(GL_TEXTURE_2D, texture[0]);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
DalÜφ °ßdky umo₧≥ujφ pou₧φt automatickΘ generovßnφ koordinßt∙ textur na jakΘkoli zobrazovanΘ objekty. P°φkaz glTexGen je velmi siln² a komplexnφ. Popsat vÜechny vlastnosti, kterΘ zahrnuje, by byl tutorißl sßm o sob∞. NicmΘn∞, vÜe, co pot°ebujete v∞d∞t, je ₧e, GL_S a GL_T jsou texturovΘ koordinßty. Implicitn∞ jsou nastaveny tak, aby vzaly pozice x a y na obrazovce a p°iÜly s bodem textury. VÜimn∞te si, ₧e objekty nejsou texturovßny na ose z. P°ednφ i zadnφ Φßst ploch je otexturovanß a to je to, na Φem zßle₧φ. x (GL_S) mapuje textury zleva doprava a y (GL_T) nahoru a dol∙. GL_TEXTURE_GEN_MODE pou₧ijeme p°i v²b∞ru texturovΘho mapovßnφ S i T. Jsou celkem t°i mo₧nosti v dalÜφm parametru:
GL_EYE_LINEAR - textura je namapovanß na vÜechny st∞ny stejn∞
GL_OBJECT_LINEAR - textura je fixovanß na p°ednφ st∞nu, do hloubky se protßhne
GL_SPHERE_MAP - textura kovov∞ odrß₧ejφcφ sv∞tlo
Je d∙le₧itΘ poznamenat, ₧e jsem vypustil spoustu k≤du. Sprßvn∞ bychom m∞li urΦit takΘ GL_OBJECT_PLANE, ale implicitnφ nastavenφ nßm staΦφ. Pokud byste se cht∞li dozv∞d∞t vφce, tak si kupte n∞jakou dobrou knihu nebo zkuste nßpov∞du MSDN.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
}
if (TextureImage[0])// Pokud bitmapa existuje
{
if (TextureImage[0]->data)// Pokud existujφ data bitmapy
{
free(TextureImage[0]->data);// Sma₧e data bitmapy
}
free(TextureImage[0]);// Sma₧e strukturu bitmapy
}
return Status;
}
Ud∞lßme takΘ n∞kolik zm∞n v inicializaΦnφm k≤du. BuildFont() p°esuneme pod loading textur. Pokud byste cht∞li m∞nit barvy textur pou₧itφm glColor3f(R,G,B), p°idejte glEnable(GL_COLOR_MATERIAL).
int InitGL(GLvoid)// VÜechna nastavenφ OpenGL
{
if (!LoadGLTextures())// Nahraje texturu
{
return FALSE;
}
BuildFont();// Vytvo°φ font
glShadeModel(GL_SMOOTH);// JemnΘ stφnovßnφ
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);// ╚ernΘ pozadφ
glClearDepth(1.0f);// Nastavenφ hloubkovΘho bufferu
glEnable(GL_DEPTH_TEST);// Povolφ hloubkovΘ testovßnφ
glDepthFunc(GL_LEQUAL);// Typ hloubkovΘho testovßnφ
glEnable(GL_LIGHT0);// Zapne implicitnφ sv∞tlo
glEnable(GL_LIGHTING);// Zapne sv∞tla
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// NejlepÜφ perspektivnφ korekce
Zapneme automatickΘ mapovßnφ textur. texture[0] se te∩ namapuje na jak²koli 3D objekt kreslen² na obrazovku. Pokud byste pot°ebovali vφce kontroly m∙₧ete automatickΘ mapovßnφ p°i kreslenφ ruΦn∞ zapφnat a vypφnat.
glEnable(GL_TEXTURE_2D);// Zapne texturovΘ mapovßnφ
glBindTexture(GL_TEXTURE_2D, texture[0]);// Zvolφ texturu
return TRUE;
}
Namφsto udr₧ovßnφ objektu uprost°ed obrazovky budeme v tΘto lekci "lΘtat" dokola po celΘm monitoru. P°esuneme se o 3 jednotky dovnit°. Hodnota pro osu x se bude m∞nit od -1.1 do +1.1. Krajnφ meze na ose y jsou -0.8 a +0.8. K v²poΦtu pou₧ijeme prom∞nnou "rot". Jako v₧dy budeme rotovat okolo os.
int DrawGLScene(GLvoid)// Vykreslovßnφ
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Sma₧e obrazovku a hloubkov² bufferu
glLoadIdentity();// Reset matice
glTranslatef(1.1f*float(cos(rot/16.0f)),0.8f*float(sin(rot/20.0f)),-3.0f);
glRotatef(rot,1.0f,0.0f,0.0f);// Rotace na x
glRotatef(rot*1.2f,0.0f,1.0f,0.0f);// Rotace na y
glRotatef(rot*1.4f,0.0f,0.0f,1.0f);// Rotace na z
P°esuneme se trochu doleva, dol∙ a dop°edu k vycentrovßnφ symbolu na ka₧dΘ ose, abychom simulovali takΘ otßΦenφ kolem vlastnφho centra (-0.35 je Φφslo, kterΘ pracuje ;) S tφmto p°esunem jsem si musel trochu pohrßt, proto₧e si nejsem jist², jak je font Üirok², ka₧dΘ pφsmeno se vφcemΘn∞ liÜφ. Nejsem si jist², proΦ se fonty nevytvß°ejφ kolem centrßlnφho bodu.
glTranslatef(-0.35f,-0.35f,0.1f);// Vycentrovßnφ
Nakonec nakreslφme lebku a zk°φ₧enΘ kosti. Nechßpete-li proΦ prßv∞ "N", tak si pus¥te MS Word vyberte pφsmo Wingdings a napiÜte "N" - odpovφdß mu tento symbol. Aby se lebka pohybovala ka₧d²m p°ekreslenφm inkrementujeme rot.
glPrint("N");// Vykreslφ lebku a zk°φ₧enΘ kosti
rot+=0.1f;// Inkrementace rotace a pohybu
return TRUE;
}
I kdy₧ jsem nepopsal probφranou lßtku do ₧ßdn²ch extrΘmnφch detail∙, m∞li byste pochopit, jak po₧ßdat OpenGL o automatickΘ generovßnφ texturov²ch koordinßt∙. Nem∞li byste mφt ₧ßdnΘ problΘmy s otexturovßnφm jak²chkoli objekt∙. Zm∞nou pouh²ch dvou °ßdk∙ k≤du (viz. GL_SPHERE_MAP u vytvß°enφ textur), dosßhnete perfektnφho efektu sfΘrickΘho mapovßnφ (kovovΘ odlesky sv∞tla).
napsal: Jeff Molofee - NeHe
p°elo₧il: Michal Turek - Woq