A GLUT az OpenGL kibõvítése, 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. A GLUT emellet 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 header file-ok a következõ include direktívával építhetõk be a forráskódba:
#include<GL\glut.h>
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.
megj.: a glutInit függvénynek nem kötelezõ szerepelni az ablak jellemzõit beállító függvények között, de ha szerepel, akkor az összes többi elõtt kell lennie;
void
glutInitDisplayMode(unsigned int mode);
a glutInitDisplayMode
a képernyõ módot specifikálja (egyszeresen
vagy kétszeresen pufferelt ablak, RGBA
vagy szín index mód,...)
pl.: a glutInitDisplayMode(GLUT_SINGLE
| GLUT_RGB) egy egyszeresen pufferelt, RGB módban
lévõ ablakot specifikál;
megj.: a glutInitDisplayMode-nak
meglehetõsen sok lehetséges paramétere van (GLUT_DOUBLE,
GLUT_INDEX, GLUT_STEREO, ...), 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.
megj.: leegyszerûsítve a dolgot: a func nevû eljárásban kell definiálni azokat a dolgokat, amiket meg szeretnénk jeleníteni. Lásd a példát.
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.
void
glutKeyboardFunc(void(*func)(unsigned char key, int x,
int y);
a függvényt specifikálja, melyet egy billentyû
lenyomásakor kell meghívni. 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).
megj.: tehát ha írunk pl. egy
void
keyboard(unsigned char key, int x, int y)
{
switch(key) {
case 27:
exit(0);
break;
default:
break;
}
}
függvényt, majd ezt a függvényt átadjuk paraméterként a glutKeyboardFunc eljárásnak a következõképpen:
glutKeyboardFunc(keyboard);
akkor a programunkból az esc billentyû lenyomásakor
léphetünk ki.
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).
void
glutPostRedisplay(void);
az érvényes ablak frissítését
eredményezi.
megj.: a glutPostRedisplay 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.
Hozzunk létre egy 200 pixel
széles, és 200 pixel magas ablakot a (100, 100) pozícióban.
Az ablak neve legyen firstglut.
Az ablak legyen egyszeresen pufferelt, és RGB szín módú.
Rajzoljunk fekete háttérbe egy kék szakaszt (0.2,
0.2) pontból a (0.8, 0.8) pontba. A programból esc-re
tudjunk kilépni.
#include<GL\glut.h>
#include<stdlib.h>
/*#include "stdafx.h"*/
void init(void) {
glClearColor(0.0,
0.0, 0.0, 0.0); // a háttér legyen fekete
glMatrixMode(GL_PROJECTION);
// beállítjuk a vetítési mátrixot
glLoadIdentity();
// betöltjük az egységmátrixot
glOrtho(0.0,
1.0, 0.0, 1.0, -1.0, 1.0); // vágósíkok
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
// a képernyõ törlése
glColor3f(0.0,
0.0, 1.0); // az érvényes szín kék
glBegin(GL_LINES)
{
glVertex2d(0.2, 0.2);
glVertex2d(0.8, 0.8); // az egyenes specifikálása
glEnd();
glFlush();
}
void keyboard(unsigned
char key, int x, int y) {
switch(key)
{
case
27:
exit(0);
break;
}
}
int main(void) {
/* int APIENTRY WinMain(HINSTANCE
hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
*/
glutInitDisplayMode(GLUT_SINGLE
| GLUT_RGB); // egyszeresen pufferelt, RGB szín módú
ablak
glutInitWindowSize(200,
200); // az ablak mérete
glutInitWindowPosition(100,
100); // az ablak pozíciója
glutCreateWindow("firstglut");
// az ablak neve
init();
glutDisplayFunc(display);
// a képernyõ kezelése
glutKeyboardFunc(keyboard);
// a billentyûzet kezelése
glutMainLoop();
// belépés az esemény hurokba
return
0;
}
/* ha Visual C-ben akarjuk a kódot lefordítani, akkor
így fog kinézni a program*/
<-- fõoldal
.