Többször megemlítettük már, hogy az OpenGL nem tartalmaz az ablakok létrehozását elősegítő függvényeket, ezért egy OpenGL program számára szükséges ablakot nekünk kell létrehozni az adott nyelven, ez pedig nem is olyan egyszerű feladat. Röviden arról van szó, hogy írni kell egy Windows programot, amelynek annyi a feladata, hogy az OpenGL használatához szükséges minimum követelményeket beállítsa, azaz nyisson egy ablakot, amelybe majd rajzolni lehet.
A GDI-nek szüksége van egy Device Context (DC) kontextusra, az OpenGL-nek egy Rendering Context (RC) kontextusra. Az alapvető lépések tehát:
A GDI-nek szüksége van egy Device Context (DC) kontextusra, az OpenGL-nek egy Rendering Context (RC) kontextusra. Az alapvető lépések tehát:
- Az ablak aktuális pixel formátumának beállítása.
- Az RC létrehozása.
- A létrehozott RC aktiválása, azaz a DC összekötése az RC-vel.
A részletes leírásra itt most nem térünk ki, helyette egy olyan OpenGL kibővítésről kell beszélnünk, amely már tartalmazza az OpenGL ablakok létrehozásához szükséges eljárásokat, így néhány sor megírásával létre tudunk hozni egy OpenGL renderelésre alkalmas ablakot. Ez a GLUT.
A GLUT emellett saját esemény kezelő rendszerrel is rendelkezik, sőt olyan rutinokat is tartalmaz, amelyekkel karaktereket és magasabb szintű geometriai objektumokat, mint például gömböket, kúpokat, ikozaédereket tudunk specifikálni. A GLUT úgy egyszerűsíti le az eseménykezelést, hogy callback rutinokat rendelhetünk bizonyos eseményekhez, mint például egy billentyű, vagy a bal egérgomb lenyomása. Ezután egy main loop-ba (esemény hurok) lépünk, majd ha egy esemény történik a hurokban, akkor az ezen eseményhez rendelt callback rutinok végrehajtódnak. A GLUT ablak és képernyő koordináták pixelekben vannak kifejezve. A képernyő vagy ablak bal felső koordinátája (0, 0). Az x koordináta jobbra haladva nő, az y koordináta pedig lefelé; ez nem egyezik meg az OpenGL koordináta rendszerével, ahol általában a bal alsó koordinátája (0, 0), de megegyezik a legelterjedtebb ablakozó rendszerek koordináta rendszerével. A GLUT-ban az egész azonosítók 1-gyel kezdődnek, nem pedig 0-val. pl.: az ablak és a menü azonosítók, illetve a menü item indexek.
A GLUT emellett saját esemény kezelő rendszerrel is rendelkezik, sőt olyan rutinokat is tartalmaz, amelyekkel karaktereket és magasabb szintű geometriai objektumokat, mint például gömböket, kúpokat, ikozaédereket tudunk specifikálni. A GLUT úgy egyszerűsíti le az eseménykezelést, hogy callback rutinokat rendelhetünk bizonyos eseményekhez, mint például egy billentyű, vagy a bal egérgomb lenyomása. Ezután egy main loop-ba (esemény hurok) lépünk, majd ha egy esemény történik a hurokban, akkor az ezen eseményhez rendelt callback rutinok végrehajtódnak. A GLUT ablak és képernyő koordináták pixelekben vannak kifejezve. A képernyő vagy ablak bal felső koordinátája (0, 0). Az x koordináta jobbra haladva nő, az y koordináta pedig lefelé; ez nem egyezik meg az OpenGL koordináta rendszerével, ahol általában a bal alsó koordinátája (0, 0), de megegyezik a legelterjedtebb ablakozó rendszerek koordináta rendszerével. A GLUT-ban az egész azonosítók 1-gyel kezdődnek, nem pedig 0-val. pl.: az ablak és a menü azonosítók, illetve a menü item indexek.
Egy ablak inicializálása és létrehozása
Egy ablak létrehozásához specifikálni kell annak tulajdonságait. Ehhez a következő rutinokat kell alkalmazni:
void glutInit (int argc , char **argv);
A glutInit eljárást minden más GLUT eljárás előtt kell meghívni, mert ez inicializálja a GLUT library-t. A glutInit paraméterei megegyeznek a main függvény paramétereivel.
void glutInitDisplayMode(unsigned int mode);
A képernyő módot specifikálja (egyszeresen vagy kétszeresen pufferelt ablak, RGBA vagy szín index mód stb.) pl.: a glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) egy egyszeresen pufferelt, RGB módban lévő ablakot specifikál; a glutInitDisplayMode-nak meglehetősen sok lehetséges paramétere van (GLUT_DOUBLE, GLUT_INDEX, GLUT_STEREO stb.), de egyszerűbb programok írásához nekünk ezek közül csak néhányra lesz szükségünk. Majd később látni fogjuk, hogy pl. kétszeresen pufferelt ablak (GLUT_DOUBLE) a jó minőségű animációnál lesz elengedhetetlen.
void glutInitWindowSize(int width, int height);
Az ablak méreteit specifikálja pixelekben, width - szélesség, height - magasság. pl.: a glutInitWindowSize(400, 400) egy 400x400-as ablakot specifikál.
void glutInitWindowPosition(int x, int y);
Az ablak bal felső sarkának x és y pozíciója. pl.: a glutInitWindowPosition(100, 100) az ablak bal felső koordinátái a pontban lesznek.
int glutCreateWindow(char *name);
Megnyit egy ablakot az előző rutinokban specifikált jellemzőkkel. Ha az ablakozó rendszer lehetővé teszi, akkor a name megjelenik az ablak fejlécén. A visszatérési érték egy egész, amely az ablak azonosítója. Ezt az értéket használhatjuk fel az ablak kontrollálására pl.: a glutCreateWindow("single") egy single névvel ellátott ablakot specifikál.
Ablakkezelés és input események
Miután az ablakot létrehoztuk, de még mielőtt belépünk az esemény hurokba, kijelölhetjük a callback függvényeket a következő rutinokkal:
void glutDisplayFunc (void(*func)(void));
Azt a függvényt specifikálja, amelyet akkor kell meghívni, ha az ablak tartalmát újra akarjuk rajzoltatni. Leegyszerűsítve a dolgot a func nevű eljárásban kell definiálni azokat a dolgokat, amiket meg szeretnénk jeleníteni. Ablak átméretezése:
void glutReshapeFunc (void(*func)(int width , int height));
Azt a függvényt specifikálja, amelyet akkor kell meghívni, ha az ablak mérete vagy pozíciója megváltozik. A func argumentum egy függvényre mutat, amelynek két paramétere van, az ablak új szélessége és magassága. Ha a glutReshapeFunc függvényt nem hívjuk meg vagy NULL az argumentuma, akkor egy alapértelmezett függvény hívódik meg, amely meghívja a glViewport (0, 0, width , height) függvényt. A billentyűzet kezelése:
void glutKeyboardFunc (void(*func)(unsigned char key , int x , int y);
Az a függvényt specifikálja, melyet egy billentyű lenyomásakor kell meghívni. A key egy ASCII karakter. Az x és y paraméterek az egér pozícióját jelzik a billentyű lenyomásakor (ablak relatív koordinátákban). Egérkezelés:
void glutMouseFunc (void(*func)(int button , int state , int x , int y);
A függvényt specifikálja, amely egy egér gomb lenyomásakor illetve elengedésekor hívódik meg. A button callback paraméter a GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON illetve a GLUT_RIGHT_BUTTON egyike. A state callback paraméter a GLUT_UP és a GLUT_DOWN szimbolikus konstansok egyike. Az x és y callback paraméterek az egér pozícióját jelzik az egér esemény megtörténtekor (ablak relatív koordinátákban). Ablak frissítése:
void glutPostRedisplay (void);
Az érvényes ablak frissítését eredményezi. Az eljárásra többnyire az animáció készítésnél lesz szükségünk, ugyanis ezzel az eljárással tudjuk az ablakot periodikusan frissíteni. A legfontosabb dolgok ezek lennének. Az elmélet ismerete után nincs más hátra mint a gyakorlat mezejére lépni. Ez fog következni. A bejegyzés nem jöhetett volna létre Varga Sándor és Kuba Attila - OGL Programozása című jegyzete nélkül.
0 megjegyzés :
Megjegyzés küldése