Lekce 17

Lekce 17 - 2D fonty z textur

V tΘto lekci se nauΦφte, jak vykreslit font pomocφ texturou omapovanΘho obdΘlnφku. Dozvφte se takΘ, jak pou₧φvat pixely mφsto jednotek. I kdy₧ nemßte rßdi mapovßnφ 2D znak∙, najdete zde spoustu nov²ch informacφ o OpenGL.

TuÜφm, ₧e u₧ vßs asi fonty unavujφ. TextovΘ lekce vßs, nicmΘn∞ nenauΦili jenom "n∞co vypsat na monitor", nauΦili jste se takΘ 3D fonty, mapovßnφ textur na cokoli a spoustu dalÜφch v∞cφ. NicmΘn∞, co se stane pokud budete kompilovat projekt pro platformu, kterß nepodporuje fonty? Podφvßte se do lekce 17... Pokud si pamatujete na prvnφ lekci o fontech (13), tak jsem tam vysv∞tloval pou₧φvßnφ textur pro vykreslovßnφ znak∙ na obrazovku. ObyΦejn∞, kdy₧ pou₧φvßte textury ke kreslenφ textu na obrazovku, spustφte grafick² program, zvolφte font, napφÜete znaky, ulo₧φte bitmapu a "loadujete" ji do svΘho programu. Tento postup nenφ zrovna efektivnφ pro program, ve kterΘm pou₧φvßte hodn∞ text∙ nebo texty, kterΘ se neustßle m∞nφ. Ale jak to ud∞lat lΘpe? Program v tΘto lekci pou₧φvß pouze JEDNU! texturu. Ka₧d² znak na tomto obrßzku bude zabφrat 16x16 pixel∙. Bitmapa tedy celkem zabφrß Φtverec o stran∞ 256 bod∙ (16*16=256) - standardnφ velikost. Tak₧e... poj∩me vytvo°it 2D font z textury. Jako obyΦejn∞, i tentokrßt rozvφjφme prvnφ lekci.

#include <windows.h>// HlaviΦkov² soubor pro Windows

#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[2];// Uklßdß textury

GLuint loop;// Pomocnß pro cykly

GLfloat cnt1;// ╚φtaΦ 1 pro pohyb a barvu textu

GLfloat cnt2;// ╚φtaΦ 2 pro pohyb a barvu textu

Nßsledujφcφ k≤d je trochu odliÜn², od toho z p°edchozφch lekcφ. VÜimn∞te si, ₧e TextureImage[] uklßdß dva zßznamy o obrßzcφch. Je velmi d∙le₧itΘ zdvojit pam∞¥ovΘ mφsto a loading. Jedno ÜpatnΘ Φφslo by mohlo zplodφ p°eteΦenφ pam∞ti nebo totßlnφ error.

int LoadGLTextures()// Nahraje bitmapu a konvertuje na texturu

{

int Status=FALSE;// Indikuje chyby

AUX_RGBImageRec *TextureImage[2];// Alokuje mφsto pro bitmapy

Pokud byste zam∞nili Φφslo 2 za jakΘkoli jinΘ, budou se dφt v∞ci. V₧dy se musφ rovnat Φφslu z p°edchozφ °ßdky (tedy v TextureImage[] ). Textury, kterΘ chceme nahrßt se jmenujφ font.bmp a bumps.bmp. Tu druhou m∙₧ete zam∞nit - nenφ a₧ tak podstatnß.

memset(TextureImage,0,sizeof(void *)*2);// Nastavφ ukazatel na NULL

if ((TextureImage[0]=LoadBMP("Data/Font.bmp")) && (TextureImage[1]=LoadBMP("Data/Bumps.bmp")))

{

Status=TRUE;// Nastavφ status na TRUE

Nebudu vßm ani °φkat kolik email∙ jsem obdr₧el od lidφ ptajφcφch se: "ProΦ vidφm jenom jednu texturu?" nebo "ProΦ jsou vÜechny moje textury bφlΘ!?!". V∞tÜinou b²vß problΘm v tomto °ßdku. Op∞t pokud p°epφÜete 2 na 1, bude vid∞t jenom jedna textura (druhß bude bφlß). A naopak, zam∞nφte-li 2 za 3, program se zhroutφ. P°φkaz glGenTextures() by se m∞l volat jenom jednou a tφmto jednφm volßnφm vytvo°it najednou vÜechny textury, kterΘ hodlßte pou₧φt. U₧ jsem vid∞l lidi, kte°φ tvo°ili ka₧dou texturu zvlßÜ¥. Je dobrΘ, si v₧dy na zaΦßtku rozmyslet, kolik jich budete pou₧φvat.

glGenTextures(2, &texture[0]);// 2 textury

for (loop=0; loop<2; loop++)

{

glBindTexture(GL_TEXTURE_2D, texture[loop]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);

}

}

Na konci funkce uvolnφme vÜechnu pam∞¥, kterou jsme alokovali pro vytvo°enφ textur. I zde si vÜimn∞te uvol≥ovßnφ dvou zßznam∙.

for (loop=0; loop<2; loop++)

{

if (TextureImage[loop])// Pokud obrßzek existuje

{

if (TextureImage[loop]->data)// Pokud existujφ data obrßzku

{

free(TextureImage[loop]->data);// Uvolnφ pam∞¥ obrßzku

}

free(TextureImage[loop]);// Uvolnφ strukturu obrßzku

}

}

return Status;

}

Te∩ vytvo°φme font. Proto₧e pou₧ijeme trochu matematiky, zab∞hneme trochu do detail∙.

GLvoid BuildFont(GLvoid)// Vytvo°enφ display list∙ fontu

{

Jak u₧ plyne z nßzvu, budou prom∞nnΘ pou₧ity k urΦenφ pozice, ka₧dΘho znaku na textu°e fontu.

float cx;// Koordinßty x

float cy;// Koordinßty y

Dßle °ekneme OpenGL, ₧e chceme vytvo°it 256 display list∙. "base" ukazuje na prvnφ display list. Potom vybereme texturu.

base=glGenLists(256);// 256 display list∙

glBindTexture(GL_TEXTURE_2D, texture[0]);// V²b∞r textury

ZaΦneme cyklus generujφcφ vÜech 256 znak∙.

for (loop=0; loop<256; loop++)// Vytvß°φ 256 display list∙

{

Prvnφ °ßdka m∙₧e vypadat trochu nejasn∞. Symbol % vyjad°uje celoΦφseln² zbytek po d∞lenφ 16. Pomocφ cx se budeme p°esunovat na textu°e po °ßdcφch (zleva doprava), cy zajiÜ¥uje pohyb ve sloupcφch (od shora dol∙). DalÜφch operace "/16.0f" konvertuje v²sledek do koordinßt∙ textury. Pokud bude loop rovno 16 - cx bude rovno zbytku z 16/16 tedy nule (16/16=1 zbytek 0). Ale cy bude v²sledkem "normßlnφho" d∞lenφ - 16/16=1. Dßle bychom se tedy m∞li na textu°e p°esunout na dalÜφch °ßdek, dol∙ o v²Üku jednoho znaku a p°esunovat se op∞t zleva doprava. loop se tedy rovnß 17, cx=17/16=1,0625. Desetinnß Φßst (0,0625) je vlastn∞ rovna jednΘ Üestnßctin∞. Z toho plyne, ₧e jsme se p°esunuly o jeden znak doprava. cy je stßle jedna (viz. dßle). 18/16 udßvß posun o 2 znaky doprava a jeden znak dol∙. Analogicky se dostaneme k loop=32. cx bude rovno 0 (32/16=2 zbytek 0). cy=2, tφm se na textu°e posuneme o dva znaky dol∙. Dßvß to smysl? (Pozn. p°ekladatele: Jß bych asi pou₧il vno°en² cyklus - vn∞jÜφm jφt po sloupcφch a vnit°nφm po °ßdcφch. Bylo by to pochopiteln∞jÜφ (...a snadn∞jÜφ na p°eklad :-))

Textura fontu

cx=float(loop%16)/16.0f;// X pozice aktußlnφho znaku

cy=float(loop/16)/16.0f;// Y pozice aktußlnφho znaku

Te∩, po troÜe matematickΘho vysv∞tlovßnφ, zaΦneme vytvß°et 2D font. Pomocφ cx a cy vyjmeme ka₧d² znak z textury fontu. P°iΦteme loop k hodnot∞ base - aby se znaky nep°episovaly uklßdßnφm v₧dy do prvnφho. Ka₧d² znak se ulo₧φ do vlastnφho display listu.

glNewList(base+loop,GL_COMPILE);// Vytvo°enφ display listu

Po zvolenφ display listu do n∞j nakreslφme obdΘlnφk otexturovan² znakem.

glBegin(GL_QUADS);// Pro ka₧d² znak jeden obdΘlnφk

Cx a cy jsou schopny ulo₧it velmi malou desetinnou hodnotu. Pokud cx a zßrove≥ cy budou 0, tak bude p°φkaz vypadat takto: glTexCoord2f(0.0f,1-0.0f-0.0625f); Pamatujte si, ₧e 0,0625 je p°esn∞ 1/16 naÜφ textury nebo Üφ°ka/v²Üka jednoho znaku. Koordinßty mohou ukazovat na lev² dolnφ roh naÜφ textury. VÜimn∞te si, ₧e pou₧φvßme glVertex2i(x,y) namφsto glVertex3f(x,y,z). Nebudeme pot°ebovat hodnotu z, proto₧e pracujeme s 2D fontem. Proto₧e pou₧φvßme kolnou projekci (ortho), nemusφme se p°esunout do hloubky - staΦφ tedy pouze x, y. Okno mß velikost 0-639 a 0-479 (640x480) pixel∙, tudφ₧ nemusφme pou₧φvat desetinnΘ nebo dokonce zßpornΘ hodnoty. Cesta jak nastavit ortho obraz je urΦit 0, 0 jako lev² dolnφ roh a 640, 480 jako prav² hornφ roh. ZjednoduÜen∞ °eΦeno: zbavili jsme se zßporn²ch koordinßt∙. U₧iteΦnß v∞c, pro lidi, kte°φ se necht∞jφ starat o perspektivu, a kte°φ vφce preferujφ prßci s pixely ne₧ s jednotkami :)

glTexCoord2f(cx,1-cy-0.0625f); glVertex2i(0,0);// Lev² dolnφ

Druh² koordinßt je te∩ posunut o 1/16 doprava (Üφ°ka znaku) - p°iΦteme k x-ovΘ hodnot∞ 0,0625f.

glTexCoord2f(cx+0.0625f,1-cy-0.0625f); glVertex2i(16,0);// Prav² dolnφ

T°etφ koordinßt z∙stßvß vpravo, ale p°esunul se nahoru (o v²Üku znaku).

glTexCoord2f(cx+0.0625f,1-cy); glVertex2i(16,16);// Prav² hornφ

UrΦφme lev² hornφ roh znaku.

glTexCoord2f(cx,1-cy); glVertex2i(0,16);// Lev² hornφ

glEnd();// Konec znaku

P°esuneme se o 10 pixel∙ doprava, tφm se umφstφme doprava od prßv∞ nakreslenΘ textury. Pokud bychom se nep°esunuli, vÜechny znaky by se nakupily na jedno mφsto. Proto₧e je font troÜku "huben∞jÜφ" (u₧Üφ), nep°esuneme se o cel²ch 16 pixel∙ (Üφ°ku znaku), ale pouze o 10. Mezi jednotliv²mi pφsmeny by byly velkΘ mezery.

glTranslated(10,0,0);// P°esun na pravou stranu znaku

glEndList();// Konec kreslenφ display listu

}// Cyklus pokraΦuje dokud se nevytvo°φ vÜech 256 znak∙

}

Op∞t p°idßme k≤d pro uvoln∞nφ vÜech 256 display list∙ znaku. Provede se p°i ukonΦovßnφ programu.

GLvoid KillFont(GLvoid)// Uvolnφ pam∞¥ fontu

{

glDeleteLists(base,256);// Sma₧e 256 display list∙

}

V nßsledujφcφ funkci se provßdφ v²stup textu. VÜechno je pro vßs novΘ, tudφ₧ vysv∞tlφm ka₧dou °ßdku hodn∞ podrobn∞. Do tohoto k≤du by mohla b²t p°idßna spousta dalÜφch funkcφ, jako je podpora prom∞nn²ch, zv∞tÜovßnφ znak∙, rozestupy ap. Funkci glPrint() p°edßvßme t°i parametry. Prvnφ a druh² je pozice textu v okn∞ (u Y je nula dole!), t°etφ je ₧ßdan² °et∞zec a poslednφ je znakovß sada. Podφvejte se na bitmapu fontu. Jsou tam dv∞ rozdφlenΘ znakovΘ sady (v tomto p°φpad∞ je prvnφ obyΦejnß - 0, druhß kurzφvou - cokoli jinΘho).

GLvoid glPrint(GLint x, GLint y, char *string, int set)// Provßdφ v²pis textu

{

Nap°ed se ujistφme, zda je set bu∩ 1 nebo 0. Pokud je v∞tÜφ ne₧ 1, p°i°adφme jφ 0. (Pozn. p°ekladatele: Autor asi zapomn∞l na Φastou obranu u₧ivatel∙ p°i zhroucenφ programu: "Ne urΦit∞ jsem tam nezadal zßpornΘ Φφslo!" :-)

if (set>1)

{

set=1;

}

Proto₧e je mo₧nΘ, ₧e mßme p°ed spuÜt∞nφm funkce vybranou (na tomto mφst∞) "randomovou" texturu, zvolφme tu "fontovou".

glBindTexture(GL_TEXTURE_2D, texture[0]);// V²b∞r textury

Vypneme hloubkovΘ textovßnφ - blending vypadß lΘpe (text by mohl skonΦit za n∞jak²m objektem, nemusφ vypadat sprßvn∞...). Okolφ textu vßm nemusφ vadit, kdy₧ pou₧φvßte ΦernΘ pozadφ.

glDisable(GL_DEPTH_TEST);// Vypne hloubkovΘ testovßnφ

Hodn∞ d∙le₧itß v∞c! Zvolφme projekΦnφ matici (Projection Matrix) a p°φkazem glPushMatrix() ji ulo₧φme (n∞co jako pam∞¥ na kalkulaΦce). Do p∙vodnφho stavu ji m∙₧eme obnovit volßnφm glPopMatrix() (viz. dßle).

glMatrixMode(GL_PROJECTION);// Vybere projekΦnφ matici

glPushMatrix();// Ulo₧φ projekΦnφ matici

PotΘ, co byla projekΦnφ matice ulo₧ena, resetujeme matici a nastavφme ji pro kolmou projekci (Ortho screen). Parametry majφ v²znam o°ezßvacφch rovin (v po°adφ): levß, pravß, dolnφ, hornφ, nejbli₧Üφ, nejvzdßlen∞jÜφ. Levou stranu bychom mohli urΦit na -640, ale proΦ pracovat se zßporn²mi Φφsly? Je moudrΘ nastavit tyto hodnoty, abyste si zvolili meze (rozliÜenφ), ve kter²ch prßv∞ pracujete.

glLoadIdentity();// Reset matice

glOrtho(0,640,0,480,-1,1);// Nastavenφ kolmΘ projekce

Te∩ urΦφme matici modelview a op∞t volßnφm glPushMatrix() ulo₧φme stßvajφcφ nastavenφ. PotΘ resetujeme matici modelview, tak₧e budeme moci pracovat s kolmou projekcφ.

glMatrixMode(GL_MODELVIEW);// V²b∞r matice

glPushMatrix();// Ulo₧enφ matice

glLoadIdentity();// Reset matice

S ulo₧en²mi nastavenφmi pro perspektivu a kolmou projekci, m∙₧eme zaΦφt vykreslovat text. ZaΦneme translacφ na mφsto, kam ho chceme vykreslit. Mφsto glTranslatef() pou₧ijeme glTranslated(), proto₧e nenφ d∙le₧itß desetinnß hodnota. Nelze urΦit p∙lku pixelu :-) (Pozn. p°ekladatele: Tady bude asi jeden totßln∞ velk² error, jeliko₧ glTranslated() pracuje v p°esnosti double, tedy jeÜt∞ ve v∞tÜφ - nicmΘn∞ stane se. (Alespo≥, ₧e vφme o co jde :-). Jo, ten smajlφk u p∙lky pixelu byl i v p∙vodnφ verzi.)

glTranslated(x,y,0);// Pozice textu (0,0 - levß dolnφ)

╪ßdek nφ₧e urΦφ znakovou sadu. P°i pou₧itφ druhΘ p°iΦteme 128 k display listu base (128 je polovina z 256 znak∙). P°iΦtenφm 128 "p°eskoΦφme" prvnφch 128 znak∙.

glListBase(base-32+(128*set));// Zvolφ znakovou sadu (0 nebo 1)

Zb²vß vykreslenφ. Jako poka₧dΘ v minul²ch lekcφch to provedeme i zde volßnφm glCallLists(). strlen(string) je dΘlka °et∞zce (ve znacφch), GL_BYTE znamenß, ₧e ka₧d² znak je reprezentovßn bytem (hodnoty 0 a₧ 255). Nakonec, ve string p°edßvßme konkrΘtnφ text pro vykreslenφ.

glCallLists(strlen(string),GL_BYTE,string);// Vykreslenφ textu na obrazovku

Obnovφme perspektivnφ pohled. Zvolφme projekΦnφ matici a pou₧ijeme glPopMatrix() k odvolßnφ se na d°φve ulo₧enß (glPushMatrix()) nastavenφ.

glMatrixMode(GL_PROJECTION);// V²b∞r projekΦnφ matice

glPopMatrix();// Obnovenφ ulo₧enΘ projekΦnφ matice

Zvolφme matice modelview a ud∞lßme to samΘ jako p°ed chvφlφ.

glMatrixMode(GL_MODELVIEW);// V²b∞r matice modelview

glPopMatrix();// Obnovenφ ulo₧enΘ modelview matice

Povolφme hloubkovΘ testovßnφ. Pokud jste ho na zaΦßtku nevypφnali, tak tuto °ßdku nepot°ebujete.

glEnable(GL_DEPTH_TEST);// Zapne hloubkovΘ testovßnφ

}

Vytvo°φme textury a display listy. Pokud se n∞co nepovede vrßtφme false. Tφm program zjistφ, ₧e vznikl error a ukonΦφ se.

int InitGL(GLvoid)// VÜechno nastavenφ OpenGL

{

if (!LoadGLTextures())// Nahraje textury

{

return FALSE;

}

BuildFont();// Vytvo°φ font

Nßsledujφ obvyklΘ nastavenφ OpenGL.

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// ╚ernΘ pozadφ

glClearDepth(1.0);// Nastavenφ hloubkovΘho bufferu

glDepthFunc(GL_LEQUAL);// Typ hloubkovΘho testovßnφ

glBlendFunc(GL_SRC_ALPHA,GL_ONE);// Vybere typ blendingu

glShadeModel(GL_SMOOTH);// Povolφ jemnΘ stφnovßnφ

glEnable(GL_TEXTURE_2D);// Zapne mapovßnφ 2D textur

return TRUE;

}

ZaΦneme kreslit scΘnu - na zaΦßtku stvo°φme 3D objekt a a₧ potom text. D∙vod proΦ jsem se rozhodl p°idat 3D objekt je prost²: chci demonstrovat souΦasnΘ pou₧itφ perspektivnφ i kolmΘ projekce v jednom programu.

int DrawGLScene(GLvoid)// Vykreslovßnφ

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Sma₧e obrazovku a hloubkov² buffer

glLoadIdentity();// Reset matice

Zvolφme texturu vytvo°enou z bumps.bmp, p°esuneme se o p∞t jednotek dovnit° a provedeme rotaci o 45░ na ose Z. Toto pootoΦenφ po sm∞ru hodinov²ch ruΦiΦek vyvolß dojem diamantu a ne dvou Φtverc∙.

glBindTexture(GL_TEXTURE_2D, texture[1]);// V²b∞r textury

glTranslatef(0.0f,0.0f,-5.0f);// P°esun o p∞t do obrazovky

glRotatef(45.0f, 0.0f,0.0f,1.0f);// Rotace o 45░ po sm∞ru hodinov²ch ruΦiΦek na ose z

Provedeme dalÜφ rotaci na osßch X a Y, kterß je zßvislß na prom∞nnΘ cnt1*30. Mß za nßsledek otßΦenφ objektu dokola, stejn∞ jako se otßΦφ diamant na jednom mφst∞.

glRotatef(cnt1*30.0f,1.0f,1.0f,0.0f);// Rotace na osßch x a y

Proto₧e chceme aby se jevil jako pevn², vypneme blending a nastavφme bφlou barvu. Vykreslφme texturou namapovan² Φty°·helnφk.

glDisable(GL_BLEND);// Vypnutφ blendingu

glColor3f(1.0f,1.0f,1.0f);// Bφlß barva

glBegin(GL_QUADS);// Kreslenφ obdΘlnφku

glTexCoord2d(0.0f,0.0f);

glVertex2f(-1.0f, 1.0f);

glTexCoord2d(1.0f,0.0f);

glVertex2f( 1.0f, 1.0f);

glTexCoord2d(1.0f,1.0f);

glVertex2f( 1.0f,-1.0f);

glTexCoord2d(0.0f,1.0f);

glVertex2f(-1.0f,-1.0f);

glEnd();// Konec obdΘlnφku

Dßle provedeme rotaci o 90░ na osßch X a Y. Op∞t vykreslφme Φty°·helnφk. Tento nov² uprost°ed protφnß prvn∞ kreslen² a je na n∞j kolm² (90░). Hezk² soum∞rn² tvar.

glRotatef(90.0f,1.0f,1.0f,0.0f);// Rotace na osßch X a Y o 90░

glBegin(GL_QUADS);// Kreslenφ obdΘlnφku

glTexCoord2d(0.0f,0.0f);

glVertex2f(-1.0f, 1.0f);

glTexCoord2d(1.0f,0.0f);

glVertex2f( 1.0f, 1.0f);

glTexCoord2d(1.0f,1.0f);

glVertex2f( 1.0f,-1.0f);

glTexCoord2d(0.0f,1.0f);

glVertex2f(-1.0f,-1.0f);

glEnd();// Konec obdΘlnφku

Zapneme blending a zaΦneme vypisovat text. Pou₧ijeme stejnΘ pulzovßnφ barev jako v n∞kter²ch minul²ch lekcφch.

glEnable(GL_BLEND);// Zapnutφ blendingu

glLoadIdentity();// Reset matice

// Zm∞na barvy zalo₧enß na pozici textu

glColor3f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)));

Pro vykreslenφ stßle vyu₧φvßme funkci glPrint(). Prvnφmi parametry jsou x-ovß a Y-ovß sou°adnice, t°etφ atribut, "NeHe", bude v²stupem a poslednφ urΦuje znakovou sadu (0-normßlnφ, 1-kurzφva). Asi jste si domysleli, ₧e textem pohybujeme pomocφ sin∙ a kosin∙. Pokud jste tak trochu "v pasti", vra¥te se do minul²ch lekcφ, ale nenφ podmφnkou tomu a₧ tak rozum∞t.

glPrint(int((280+250*cos(cnt1))),int(235+200*sin(cnt2)),"NeHe",0);// VypφÜe text

glColor3f(1.0f*float(sin(cnt2)),1.0f-0.5f*float(cos(cnt1+cnt2)),1.0f*float(cos(cnt1)));

glPrint(int((280+230*cos(cnt2))),int(235+200*sin(cnt1)),"OpenGL",1);// VypφÜe text

Nastavφme barvu na modrou a na spodnφ Φßst okna napφÜeme jmΘno autora tΘto lekce. CelΘ to zopakujeme s bφlou barvou a posunutφm o dva pixely doprava - jednoduch² stφn (nenφ-li zapnut² blending nebude to fungovat).

glColor3f(0.0f,0.0f,1.0f);// Modrß barva

glPrint(int(240+200*cos((cnt2+cnt1)/5)),2,"Giuseppe D'Agata",0);// VypφÜe text

glColor3f(1.0f,1.0f,1.0f);// Bφlß barva

glPrint(int(242+200*cos((cnt2+cnt1)/5)),2,"Giuseppe D'Agata",0);// VypφÜe text

Inkrementujeme ΦφtaΦe - text se bude pohybovat a objekt rotovat.

cnt1+=0.01f;

cnt2+=0.0081f;

return TRUE;

}

Myslφm, ₧e te∩ mohu oficißln∞ prohlßsit, ₧e moje tutorißly nynφ vysv∞tlujφ vÜechny mo₧nΘ cesty k vykreslenφ textu. K≤d z tΘto lekce m∙₧e b²t pou₧it na jakΘkoli platform∞, na kterΘ funguje OpenGL, je snadn² k pou₧φvßnφ. Vykreslovßnφ tφmto zp∙sobem "u₧φrß" velmi mßlo procesorovΘho Φasu. Rßd bych pod∞koval Guiseppu D'Agatovi za originßlnφ verzi tΘto lekce. Hodn∞ jsem ji upravil a konvertoval na nov² zßkladnφ k≤d, ale bez n∞j bych to asi nesvedl. Jeho verze mß trochu vφce mo₧nostφ, jako vzdßlenost znak∙ apod., ale jß jsem zase stvo°il "extrΘmn∞ skv∞l² 3D objekt".

napsal: Giuseppe D'Agata & Jeff Molofee - NeHe
p°elo₧il: Michal Turek - Woq

ZdrojovΘ k≤dy

Lekce 17

<<< Lekce 16 | Lekce 18 >>>