Lekce 15

Lekce 15 - Mapovßnφ textur na fonty

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

ZdrojovΘ k≤dy

Lekce 15

<<< Lekce 14 | Lekce 16 >>>