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: