OpenGL v C++ Builderu (5.díl) - 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:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se koná výstava fotografií Luďka Vojtěchovského?

V dnešní soutěži hrajeme o:



C/C++

OpenGL v C++ Builderu (5.díl)

open gl

24. října 2001, 00.00 | "Za mlhou hustou tak, že by se dala krájet"..., tak takhle nějak začíná jeden večerníček o Křemílkovy a Vochomůrce, ale začíná tak i naše další pokračování seriálu o OpenGL. V dnešním díle se budeme věnovat nastavení mlhy ve scéně.

Mlha (fog)

"Za mlhou hustou tak, že by se dala krájet ...", tak takhle nějak začíná jeden večerníček o Křemílkovy a Vochomůrce, ale začíná tak i naše další pokračování seriálu o OpenGL. V dnešním díle se budeme věnovat nastavení mlhy ve scéně.

Mlha je stejně důležitá jako světla, o kterých jsme mluvili v předchozích dílech a dotváří celkové prostředí ve scéně. Minule jsme skončili příkladem rotující krychle s texturou. Dnes tento příklad obohatíme o nové možnosti. Ale nejprve si povězme, co bude cílem našeho snažení:

Naše krychle nebo spíše bedna, bude rotovat v prostoru a okolo bude přibývat mlha.

Podívejme se na hromadu proměnných, které budeme potřebovat:
GLfloat z=-7.0f;
Souřadnice z znamená posunutí krychle dozadu.
double fogdensity = 0.05;
Fogdensity je číselná hodnota hustoty mlhy (viz dále)
Dále tu máme již staré známe, o kterých se ani nemusím rozepisovat LightAmbiet, LightDiffuse, LightPosition a LightSpecular. To je definice světla.
GLuint filter = 0;
Tato proměnná bude indexovat, který použijeme filter. Budeme mít vytvořené 3 textury (z jedné bitmapy) a tyto 3 textury se budou odlišně mapovat (použijeme odlišné filtry).
Pak tu máme označení pro filtr mlhy
GLuint fogMode[]= { GL_EXP, GL_EXP2, GL_LINEAR};
GLuint fogfilter = 0;

No a poslední důležitý parametr mlhy bude barva mlhy. Mlha, jak známo, má šedivou barvu:
GLfloat fogColor[4] = {0.5f,0.5f,0.5f,1.0f};

Nyní přeskočme funkce pro načítání textur, které jsou maličko vylepšené a podívejme se na to, jak mlhu napasovat do scény. Je zvykem nastavit mlhu při inicializaci, když nám postačuje mlha pro celou scénu (nehodláme ji měnit při běhu programu). Mi potřebujeme za běhu programu měnit nastavení mlhy, proto definici mlhy umístíme do funkce DrawScene.

glFogi(GL_FOG_MODE, fogMode[fogfilter]);  // mód mlhy
glFogfv(GL_FOG_COLOR, fogColor);  // nastavit barvu mlhy
glFogf(GL_FOG_DENSITY, fogdensity+=0.0005);  // hustota mlhy
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 5.0f);  // počátek mlhy
glFogf(GL_FOG_END, 7.0f);  // konec mlhy - kde je už neprůhledná
glEnable(GL_FOG);  // aktivujeme mlhu

Nastavení provádíme přes funkci void glFogi( GLenum pname, GLint param ). Pomocí pname volíme parametr mlhy, který budeme měnit. Nejprve zvolíme GL_FOG_MODE, mód mlhy . Ten může nabývat hodnot GL_LINEAR, GL_EXP, a GL_EXP2. Jedná se o kvalitu zobrazované mlhy. GL_EXP je nejjednodušší nastavení vhodné pro pomalejší počítače (basic), mlha je jednoduchá a přes celou scénu (konstantní). O něco lepší mlhu získáme parametrem GL_EXP2. No a nejlepší , nejvěrohodnější mlhu uhněteme přes parametr GL_LINEAR. Toto nastavení bere v úvahu i viditelný přechod .... až do mlhy nejhustší. Podívejte se, jaký je rozdíl mezi nastavením GL_EXP, GL_LINEAR.

Dalším nastavením mlhy je GL_FOG_COLOR, což je barva mlhy, která je šedá. Mimo to je potřeba mít nastavený
glClearColor(0.5f,0.5f,0.5f,1.0f);
na šedou barvu, jinak scéna bude vypadat podivně. Pro demonstrační obrázky nahoře jsem použil bílou podkladovou barvu a není to ono.
GL_FOG_DENSITY je hustota mlhy. Optimální hodnoty jsou 0.05 až 0,45. Čím vyšší hodnota hustoty, tím je mlha hustší až tak, že by se dala krájet :)).
Následuje nastavení odkud mlha sahá GL_FOG_START, a GL_FOG_END je hodnota kde už není přes mlhu vidět. Vyzkoušejte si dvě kombinace hodnot pro start a stop (4.0, 7.0) a (4.0, 6.0). Ještě nesmím zapomenout, že nastavení těchto hodnot je viditelné pouze při módu mlhy GL_LINEAR.
Nyní už stačí jen mlhu aktivovat a program je hotov.

Ale aby toho nebylo málo, vyzkoušíme ještě 3 druhy mapování textur. Ty rozdíly budou viditelné především v kvalitě.
Vraťme se k načítání textur, vraťme se do funkce LoadGLTextures().
Jak již jsem zmínil na začátku způsob mapování budeme přepínat proměnou filter tím, že budeme měnit hodnoty 0, 1 nebo 2. 3 textury registrujeme polem texture[3].
Nejjednodušší způsob texturování je takový mix typu GL_NEAREST a GL_LINEAR (texture[0]). Tento způsob neoplývá příliš velkou realističností vykreslované textury. Na textuře jsou vidět jednotlivé pixely a vše je nevyhlazené, považuji to jako velkou nevýhodu. Na opak pro pomalejší počítače je to jediný způsob, jak přizpůsobit rychlost vykreslování výkonu počítače. Tento způsob texturování je definován takto:

glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

Poznámka:
Tzv. MIN_FILTER se aplikuje, je-li vykreslovaná textura menší než skutečná textura (tedy obrázek). MAG_FILTER se aplikuje, když je vykreslovaná textura větší než skutečná textura.




Druhý způsob texturování je naprosto shodný s tím, co jsme si uváděli minule. Jde o lineární texturování. Opět vhodné spíše pro pomalejší strojem, nebo vhodné pro náhledy.

glBindTexture(GL_TEXTURE_2D, texture[1]);
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[0]->sizeX, TextureImage[0]->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

A třetí způsob se jmenuje mipmaping, je to z těchto pří způsobů texturování nejlepší. Dobře vypadá, ale je náročnější na výkon počítače. Pokud je mapovaná textura větší než skutečná textura, použije se lineární mapování. Pokud je mapovaná textura menší než skutečná textura použije se MIPMAP.

glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);


A na obrázku to vypadá asi takto (MIPMAP):



LINKS
NeHe tutorials


DOWNLOAD
fog.zip (290 KB) - výsledný exe a zdroják
klávesami 1,2,3 se přepínají typy mlhy
klávesami Q,W,E se přepíná texturování

 

 

 

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: