OpenGL - 1.díl Nastavení a jednoduché kreslení - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



C/C++

OpenGL - 1.díl Nastavení a jednoduché kreslení

28. června 2001, 00.00 | První díl seriálu o programování v OpenGL. Úvodem si na jednoduché aplikaci ukážeme, co že to OpenGL vlastně je..

Vítám vás u prvního dílu seriálu o tvorbě v OpenGL. Jistě vás již omrzelo (jako mě) dělat hry v DirectX.
Věděl bych o jedné knihovně, ba přímo o rozhraní, které není z dílny Microsoftu a nabízí velmi dobrou alternativu DirectX na poli 3D grafiky.

Je tedy čas skončit s líbeznými omalovánkami a pusťme se do drsné reality 3D prostoru.

OpenGL je pro programátora velmi komfortní nástroj pro rýsování. Dovolím si ještě jedno malé srovnání DirectX a OpenGL z hlediska programování aplikací. Teď jistě potěším ortodoxní céčkaře, OpenGL je knihovna C funkcí. Jedním slovem "ráj " pro céčkaře. Žádné třídy a složité struktury, vše je čisté a uhlazené.

Možná to bude znít jako věta z reklamy, ale programování s OpenGL je opravdu jednodušší.

Nastavení OpenGL ve Windows98

Pro práci s OpenGL je potřeba mít tuto knihovnu v počítači nainstalovánu, což myslím je dnes již samozřejmostí. Ovšem některé grafické karty mají s OpenGL veliké problémy. Nebudu jmenovat, konkrétně karty Voodo si s OpenGL moc nerozumějí. Je proto potřeba si u výrobce grafické karty stáhnout potřebný ovladač.

Další potřebnou věcí pro úspěšnou práci s OpenGL jsou příslušné hlavičkové soubory: gl.h, glu.h a glaux.h.

Poznámka: U některých překladačů možná budete potřebovat do projektu přidat soubory: OpenGL32.lib GLu32.lib a GLaux.lib.


Dost řečí, pusťme se do našeho prvního OpenGL programu. Co bude cílem našeho jednoduchého výtvoru? Pro začátek bych se nepouštěl do žádných větších akcí, spokojíme se z trojúhelníkem, který vidíte na obrázku:

Nic světoborného.

Budeme programovat v C++ Builderu. Vytvořme si nový projekt a podívejme se na jeho odlišnosti a specifika od jiných aplikací. Za zmínku stojí

void __fastcall TForm1::FormCreate(TObject *Sender) {
bSetupPixelFormat(Canvas->Handle);
hRC = wglCreateContext(Canvas->Handle);

if (hRC == NULL) {
   MessageBox(0,"wglCreateContext se nepodařilo rozběhnout!","Form Create", MB_OK);
   return;
   }
}

Ve Windows probíhá vykreslování přes rozhraní GDI pro 2D grafiku, které jak víme je velmi pomalé. Funkce GDI vykreslují do HDC (resp. jenom DC) - do příslušného zařízení Device Context. Device Context získáme z Canvas->Handle. Abychom mohli pracovat s OpenGL musíme přemostit vykreslování na rozhraní OpenGL tím, že nastavíme tzv. PixelFormatDescriptor, který slouží jako komunikátor mezi výstupními rutinami windowsu a výstupními rutinami knihovny OpenGL. Poukazuje na to, jaké rozdíly jsou v zobrazování barev atd. Toto nastavení najdete ve funkci bSetupPixelFormat. Pokud vás zajímají jednotlivé položky ve struktuře PIXELFORMATDESCRIPTOR, najdete to v helpu. SetPixelFormat nastaví daný pixelformat danému DC. Po nastavení PixelFormatu vytvoříme Context pro OpenGL funkcí wglCreateContext opět s parametrem HDC, tedy Canvas->Handle.

wglMakeCurrent(Canvas->Handle, hRC);
DrawScene();
wglMakeCurrent(NULL, NULL);

Nastaví hRC - OpenGL Rendering Context jako aktuální, Po té zavolá uživatelskou funkci DrawScene, která nám slouží pro rýsování a nakonec zruší aktuální Rendering Context.

Nyní musíme ošetřit metodu FormResize, aby se nám scéna správně překreslila při změně velikosti okna.

wglDeleteContext(hRC);
bSetupPixelFormat(Canvas->Handle);
hRC = wglCreateContext(Canvas->Handle);
wglMakeCurrent(Canvas->Handle, hRC);
gldAspect = ClientWidth / ClientHeight;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0,gldAspect, 1.0, 10.0);
glViewport(0, 0, ClientWidth, ClientHeight);
DrawScene();
wglMakeCurrent(NULL, NULL);
Invalidate();

Nejdřív zrušíme Rendering Context a nastavíme nový PixelFomat. To už je nám stará známá písnička, takže následně opět vytvoříme nový aktualizovaný Rendering Context. glLoadIdentity() - resetuje projekční plátno, a posune souřadnici 0,0 do středu.

gluPerspective - nastavuje perspektivu kamery, jak bude vypadat prostor pohledem kamery. První parametr s hodnotou 30.0, určuje zorný úhel kamery. gldAspect je poměr výšky a šířky formuláře (projekčního plátna). Další hodnota (1.0) zadává nejmenší vzdálenost, od které je vidět vykreslovaný objekt. No a 10.0 naopak udává největší vzdálenost od které již objekt není viditelný.

glViewport - tato funkce nastavuje velikost zobrazované plochy.

Nakonec zavoláme naši uživatelskou rýsovací funkci DrawScene();. Výsledek je jednoduchý, RGB trojúhelník.

Začínáme rýsovat

Jaký je základní princip rýsování do rozhraní OpenGL? Kreslení v OpenGL se dá připodobnit k rýsování jako například v AutoCadu. Vše se rýsuje posloupností příkazů - bod, čára trojúhelník.

Takže obdobně jako při rýsování máme určený nějaký počátek souřadnicového systému. Ten je dán jako obyčejně souřadnicí 0,0,0 na osách x,y,z. Počátek je umístěn uprostřed plátna.

glLoadIdentity() - zresetuje pohled a souřadnice 0,0,0 se nachází uprostřed obrazovky. Přitom nalevo od 0,0,0 se nachází záporný směr osy X, napravo kladný. Nahoru směřuje kladný směr osy Y, a dolů záporný. Osa Z má záporné hodnoty dovnitř a kladné ven.

Kreslení bodů, čar nebo vektorů, je analogické kreslení do souřadného systému x,y,z. Z obrázku je patrné, že pokud chceme používat jen souřadnou rovinu XY, zadáváme hodnoty tak, že Z souřadnice je 0. Dostaneme 2D zobrazení.

Mě ale nevyhovuje, zadávat hodnoty jen od -1 do 1. Potřebuji často daleko větší rozmezí hodnot. Pro OpenGL to není problém, stačí jen posunout počátek.

glTranslatef(x, y, z) ;

Funkce přesune počátek souřadnicové sítě o zadanou hodnotu např. glTranslatef(-0.5f,0.5f, 0.0f); posune počátek o 0.5 na ose x a y.

Chceme-li tedy mít k dispozici větší rozmezí, stačí posunout počátek na ose Z o -20.

Teď už můžeme narýsovat jednoduché geometrické útvary. Jak už jsem říkal, vše rýsujeme pomocí posloupnosti příkazů. Tuto posloupnost uzavíráme do bloku glBegin() a glEnd(). Tím řekneme rozhraní OpenGL, že hodláme rýsovat, ale hlavně co chceme rýsovat.

GL_POINTS

Budeme rýsovat jednotlivé body

GL_LINES

Budeme rýsovat úsečky ve tvaru počáteční, konečný bod. Konečný bod je zároveň počátečním bodem následující úsečky.

GL_TRIANGLES

Rýsuje trojúhelníky ze tří bodů (A,B, C)

GL_QUADS

Rýsuje čtyřúhelník

GL_POLYGON

Rýsuje polygon (n - úhelník)

Trojúhelník:

glBegin(GL_TRIANGLES); // kreslíme trojúhelnik

glVertex3f( 0.0f, 1.0f, 0.0f); // horní bod
glVertex3f(-1.0f,-1.0f, 0.0f); // levý
glVertex3f( 1.0f,-1.0f, 0.0f); // pravý

glEnd();

Čtverec se rýsuje obdobným způsobem.

glBegin(GL_QUADS);

glVertex3f(-1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);

glEnd();

Rectanlge - čtyřúhelník

Obdelník lze narýsovat dvěma způsoby. Klasicky jako polygon pomocí vertexů nebo jako tzv. rectangle.

glBegin(GL_POLYGON);

glVertex2(x1, y1);
glVertex2(x2, y1);
glVertex2(x2, y2);
glVertex2(x1, y2);

glEnd( );

Rectangle se rýsuje do roviny XY

void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);

Trojúhelník a čtverec v barvách

Další dovednost v OpenGL je použití barev. V této části se pokusíme vytvořit trojúhelník a čtverec v barvách. Nastavíme pro každý vrchol trojúhelníka barvu a zvolíme nastavení pro zobrazení polygonu na vyplněný polygon.

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

potom zkuste změnit druhý parametr na GL_LINE

První bod projekce bude červený
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);

druhý modrý
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);

a třetí zelený
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);

Zkuste najít řádek:
glShadeModel(GL_SMOOTH);
přepište na GL_LINE

 

Pokud máme nastaveno stínování GL_SMOOTH a umístíme do každého bodu jinou barvu, vznikne efekt, kde v jednotlivých rozích barvy přecházejí v druhou, prolínají se.

To by pro tentokrát stačilo. Ještě se podívejte na názorný příklad a nemějte mi za zlé, že dnes dělám samé trojúhelníky. Příště určitě přitvrdíme. Podíváme se na rotace objektů.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: