OpenGL.Hu – VI. Rész

 

Bújjunk új bőrbe...

 

            Mint ahogy a múltkori részben említettem, most a textúrázással fogjuk folytatni OpenGL „tanulmányainkat”. Nagyjából leírtam az elméletet, így most egy példával kezdeném, és közben magyaráznám el a felmerülő kérdéses dolgokat. A példánk a következő: vegyünk egy 3 dimenziós objektumot (az egyszerűség kedvéért egy kockát) és használjuk ugyanazt a bitképet arra, hogy a kocka összes oldalára helyezzük mintázatnak.

Természetesen most is van mellékelt, működő példaprogram, de biztos-ami-biztos alapon álljon itt most egy kép arról, hogy mit is akarunk csinálni.

 

 

Ez lesz tehát a programunk (Pelda07)  végeredménye. Az egyszerűség kedvéért kihagytam mindenféle hibaellenőrzést, így nem ellenőrzi a program a bitkép fájl létezését, a betöltés sikerességét, stb.

A következő pár sor Windows-specifikus, így a más operációs rendszert használók átugorhatják... A program sikeres elindításához elengedhetetlen a glut32.dll és a glaux.dll fájlok megléte. Ezeknek vagy a programunk futtatható fájljával (Pelda07.Exe) azonos könyvtárban kell lennie vagy pedig olyan könyvtárban, amelyik a PATH környezeti változóban meg van adva.

Szintén fontos fájl és a lefordításhoz elengedhetetlen, a glaux.h. Nem minden fordító OpenGL-csomagjához mellékelik, így ez is prodlémát okozhat. A DevC++ aktuális verziójából például egyszerűen kifelejtették (gondolom ezt azért, mert a hozzá tartozó tárgykódkönyvtárat viszont a csomagban hagyták, bár magában semmi haszna).

 

A GLAux library-t azért használjuk, mert ennek segítségével a legegyszerűbb megoldani, hogy egy windows bitmap (*.bmp) fájlt betöltsünk és textúraként alkalmazzunk. Nem használhatunk azonban akármilyen bitképet erre a célra! Fontos konvenció, hogy a kép méretének dimenziói a 2 hatványai legyenek. Szokásásos konvenció még, hogy ha nem muszáj, nem használ senki túl nagy textúrákat, mert feleslegesen emésztik fel az amúgy is elég szűkös textúramemóriát. A túl kis textúrák használata pedig azért kerülendő, mert közelről nagyon csúnya tud lenni, mikor egy-két pixel van széthúzva úgy, hogy a fél képernyőt elfoglalja. Miután kiválasztottuk a megfelelő bitmap fájlt, ideje, hogy rátérjünk a kódra is!

            Elsőként beillesztjük a szükséges header file-okat a programunkba. Javaslom, hogy valamelyik korábbi példaprogramot mintaként tekintve haladjunk tovább! Tehát, az #include soroknál az egyetlen új sor a következő:

 

            #include <GL/glaux.h>

 

Megjegyezném, hogy természetesen a header-ével egyező nevű library file-t most is meg kell adni paraméterként a linkernek, különben linker errorral megakad a fordítási folyamatunk.

Következő lépésként definiáljunk néhány változót a programunk számára. Mivel a demo a szokásos forgó kocka ötletre épül, legyen adott a következő három változó a forgás kontrollálására:

 

GLfloat            xrot;

GLfloat            yrot;

GLfloat            zrot;

 

Vegyünk fel még egy GLuint típusú tömböt, amelyet az OpenGL arra fog használni, hogy a betöltött textúrákra hivatkozzon rajta keresztül. Hogy hogyan, az igazából nem lesz lényeges számunkra, így nem is részletezem. Tehát a deklaráció:

 

GLuint texture[1];

 

A programunk egyetlen új és igen fontos függvénye a LoadTextures, amely a következőképpen néz ki:

 

void LoadTextures()

{

                        AUX_RGBImageRec *TextureImage[1];

                        memset(TextureImage,0,sizeof(void *)*1);

           

TextureImage[0]=auxDIBImageLoad("Textures/metal.bmp");

 

                        glGenTextures(1, &texture[0]);

                        glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,

TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,

TextureImage[0]->data);

                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,

GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,

GL_LINEAR);

            free(TextureImage[0]->data);

                        free(TextureImage[0]);

}

 

A függvény egyes utasításai a következő dolgokat csinálják sorrendben:

 

A továbbiakban tehát a textúrára a Texture[0] változóval hivatkozunk. Ha lenne második,harmadik, stb betöltve, azokra a Texture[1], Texture[2], stb változót használhatnánk. (Persze akkor nagyobb tömböt kellene deklarálni az elején.) Ha már a használatot említettem, elmondom, hogy egy adott QUAD-ra például hogyan lehetne ráhúzni a textúránkat. Ehhez a QUAD definíciója előtt használnunk kell a következő utasítást:

 

glBindTexture(GL_TEXTURE_2D, texture[0]);

 

Ez eléri azt, hogy amíg nem váltunk egy hasonló utasítással textúrát, addig az összes definiált alakzatra ezt a textúrát fogja ráfeszíteni. A példaprogramban jól látszik, hogy egyetlen ilyen utasítás után 6 db textúrázott QUADot definiálunk.

Már csak annak vezérlése van hátra, hogy melyik vertexhez a textúra melyik „sarka” kerüljön. Ezt a

 

            glTexCoord2f(0.0f, 0.0f);

 

utasítással tesszük, közvetlen a vertex definíciója előtt. A (0.0,0.0) a textúra-négyszög bal-felső sarkát, az (1.0,1.0) pedig a jobb alsót jelenti. Innentől azt hiszem egyértelmű... J

És végül, a programunk inicializáló részében engedélyeznünk kell a textúrázást. Ezt így tehetjük meg:

 

            glEnable(GL_TEXTURE_2D);

 

Mielőtt még valaki megkérdezné, a válaszom: IGEN, ENNYI... Most már ezt is tudjuk! Lassan, de biztosan elérünk majd egy olyan színvonalat, hogy kezdetleges 3d játékokat tudunk írni. Ehhez azonban még kell majd egy-két tecnika, amivel a programunk render-folyamatát felgyorsíthatjuk. De ez még a jövő meséje...

 

Ezzel le is zárnám a sorozat ezen részét. Kellemes OpenGL kódolást kívánok mindenkinek:

 

Merczel László - laszlo.merczel@mailbox.hu