GLUT

A Graphics Library Utility Toolkit(GLUT)

    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.

Példa GLUT programra

    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

.