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 :-))
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