• Nem Talált Eredményt

Az OpenGL Használata

In document 3D megjelenítési technikák (Pldal 134-139)

technikák optikai és interferometriai háttere

2. Az OpenGL Használata

Az Open GL rendszert használhatjuk klasszikus módon, illetve az egy a felhasználást könnyítő könyvtárral.

2.1. Az OpenGL klasszikus inicializálása

Az OpenGL rendszer API függvényeit az OpenGL32.lib, a glu32.lib, a gdi32.lib és a User32.lib könyvtárak tartalmazzák. A könyvtárakat be kell építeni programunkba (Project Properties/ Configuration Properties/ Linker/ Input/ Additional Dependencies = openGL32.lib glu32.lib gdi32.lib User32.lib $(NoInherit)) eléréséhez be kell építenünk program stdafx.h-ba a kapcsolódó deklarációs állományokat:

#include <windows.h>

Az OpenGL pixeles eszközökön működik. Első lépésben definiálnunk kell, hogy mely lehetőségeit szeretnénk használni a raszteres eszköznek. Ha ezt megtettük, informálódni kell arról, hogy az aktuális konfiguráció mit

támogat az igényeink közül. Az így meghatározott lehetőségek alapján OpenGL-eszközkapcsolatot építhetünk, és kezdhetjük a geometriai modellezést. Ha már nincs szükségünk az OpenGL-eszközkapcsolatra, töröljük annak adatait.

2.1.2. A használni kívánt megjelenítési kapcsolat meghatározása

A Windows API (Application Programming Interface) függvényei az objektumokat számokkal azonosítják.

Ezeket a számokat leírónak (handle) hívjuk. Az ablakok leírója a HWND típus (Handle of WiNdoW). Hasonlóan a grafikus eszközök rajzlapjainak objektumát egy számmal azonosíthatjuk HDC típus (Handle of Device Context).

Az API rajzoló függvényeket is használhatjuk ezekkel az azonosítókkal. A .NET rendszerben az objektumok Handle tulajdonsága tartalmazza a leírókat.

Az alábbi példa a HWND típusú hwnd változóba lekéri az ablakleírót, majd a GetDC() API függvénnyel lekéri az ablak rajzlapjának leíróját, és a HDC típusú m_hDC változóba helyezi.

HWND hwnd=(HWND)this->Handle.ToInt32();

HDC m_hDC = GetDC(hwnd);

PictureBox-ba is rajzolhatunk, csak akkor a PictureBox ablakleírójával kell dolgoznunk.

hwnd=(HWND)pictureBox1->Handle.ToInt32();

m_hDC = GetDC(hwnd);

2.1.3. A pixelformátum meghatározása

Az OpenGL használatához meg kell határozzuk, hogyan használjuk a pixeleket. A pixelformátum megadásához a PIXELFORMATDESCRIPTOR struktúrát alkalmazhatjuk. A struktúra adattagjaival előírhatjuk, miként szeretnénk használni a grafikus hardver lehetőségeit. Beállíthatjuk a takartvonalas ábrázolásra, a színezésre, a pufferek használatára vonatkozó igényeinket. A pixelformátum struktúra definíciója:

typedef struct tagPIXELFORMATDESCRIPTOR { // pfd WORD nSize;

A struktúra egyes adattagjait a Windows nem használja, a támogatott adattagok az alábbiak:

nSize A struktúra mérete sizeof(PIXELFORMATDESCRIPTOR)

OpenGL

nVersion Ennek értéke 1 kell legyen.

dwFlags A megadott konstansokat bitenkénti vagy (|) művelettel adjuk meg.

Néhány jól használható beállítás:

PFD_DRAW_TO_WINDOW Akkor használjuk a konstanst, ha azt szeretnénk, hogy ablakban jelenjen meg a rajz. Alkalmazhatjuk még a PFD_DRAW_TO_BITMAP konstanst is.

PFD_SUPPORT_OPENGL Az OpenGL lehetőségeit használjuk, egyébként PFD_SUPPORT_GDI. PFD_DOUBLEBUFFER Több puffert alkalmazva a képeket

cserélgethetjük (pl. animáció).

iPixelType PFD_TYPE_RGBA RGBA színmegadás

PFD_TYPE_COLORINDEX Színmegadás palettaindexszel

cColorBits Színdefiniáló bitek száma.

cAcumBits A speciális tárolópuffer színdefiniáló bitjeinek száma.

cDepthBits A Z-puffer bitjeinek száma.

cStencilBits A stencilpuffer bitjeinek száma.

iLayerType PFD_MAIN_PLANE Rajzolás az alap fóliára.

PFD_OVERLAY_PLANE Rajzolás a felső fóliára PFD_UNDERLAY_PLANE Rajzolás az alsó fóliára

Ha az adatokat a struktúrában rögzítettük, akkor a ChoosePixelFormat() függvény hívásával lekérdezhetjük a sorszámát annak a pixelformátumnak, amelyet OpenGL-eszközkapcsolatunk a igényeinkhez legjobban illeszkedőnek talál, és támogat. Ezt a sorszámot használjuk majd az OpenGL eszközkapcsolat megteremtéséhez:

int ChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR * ppfd );

A hdc paraméter az eszközkapcsolat-leíró, a ppfd a formátumdefiniáló struktúrára mutató pointer. A függvény sikeres választás esetén 0-tól különböző értékkel tér vissza.

A kiválasztott pixelformátum tényleges adatai lekérdezhetők a DescribePixelFormat() függvénnyel.

int WINAPI DescribePixelFormat( HDC hdc, int iPixelFormat, UINT nBytes,

LPPIXELFORMATDESCRIPTOR ppfd);

a hdc az eszközkapcsolat leíró, megadhatjuk a kiválasztott pixelformátumot iPixelFormat, az nBytes a ppfd által mutatott struktúra mérete. A visszatérési érték az adott eszközkapcsolaton használható formátumok száma.

Ha megvan a legközelebbi pixelformátum, akkor azt a

bool SetPixelFormat(HDC hdc, int iPixelFormat, PIXELFORMATDESCRIPTOR * ppfd)

függvénnyel állíthatjuk be egy hDC-re. A hdc az eszközkapcsolat leíró, az iPixelFormat egész a meghatározott legközelebbi pixelformátum, a ppfdPIXELFORMATDESCRIPTOR-ra mutató pointer.

2.1.4. A megjelenítési kapcsolat létrehozása, kiválasztása és törlése

A

HGLRC wglCreateContext(HDC hdc);

függvény segítségével, az eszközkapcsolat-leírót felhasználva létrehozhatunk OpenGL megjelenítési kapcsolatokat (HGLRC típusú Handle of GLRendering Context):

A

BOOL wglMakeCurrent( HDC hdc, HGLRC hglrc);

függvénnyel, melynek paraméterei az eszköz- és megjelenítési kapcsolat, beállíthatjuk azt, hogy az esetlegesen több megjelenítési kapcsolat közül melyik legyen az aktuális. Ha sikerrel jártunk, a visszatérési érték igaz.

Az aktuális beállítások lekérdezésére a HGLRC típusú wglGetCurrentContext() és a HDC típusú wglGetCurrentDC() függvényeket használhatjuk.

Az adott programszál megjelenítési kapcsolatának felszabadításához először meg kell szüntetnünk a kapcsolat kiválasztott állapotát, a wglMakeCurrent(0, 0); hívással, majd törölhetjük azt a

BOOL wglDeleteContext ( HGLRC hglrc);

függvénnyel, melynek visszatérési értéke a törlés sikerességét jelzi.

Az alábbi példa MySetPixelFormat() függvénye a hdc eszközkapcsolattal beállítja az m_hglrc megjelenítési kapcsolatot.

if((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0) { MessageBox::Show("ChoosePixelFormat nem OK");

return 0;

}

OpenGL

if(SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE) { MessageBox::Show("SetPixelFormat nem OK ");

return 0;

}

if((m_hglrc = wglCreateContext(m_hDC)) == NULL) { MessageBox::Show("wglCreateContext nem OK ");

return 0;

}

if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL) { MessageBox::Show("wglMakeCurrent nem OK ");

return 0;

}

return 1;

}

A megjelenítési kapcsolat felépítése a Load eseményben:

private: System::Void Form1_Load(System::Object^ sender,

A megjelenítési kapcsolat megszüntetése a FormClosing eseményben:

private: System::Void Form1_FormClosing(System::Object^ sender,

Az OpenGL ablakozó rendszer független, azaz ablak létrehozását, a felhasználói események kezelését mindig az adott platform szerint kell megvalósítani. Az OpenGL-t inicializálni kell egy létrehozott ablakban, hogy OpenGL-lel lehessen rá rajzolni. A szabvány erről nem mond semmit, hanem ablakozó-rendszer-függő kiterjesztésekkel kell ezt megtenni. Például Windows-on a Win32 API-val létrehozott ablakokon a WGL kiterjesztéssel lehet OpenGL-t inicializálni. UNIX-on, vagy Linuxon X11 felett az XGL, Mac OS X-en Carbon felett az AGL, vagy Cocoa felett az NSOpenGL API-kkal tehető ez meg.

Azonban ehhez az ablakozó rendszerek működésének bővebb ismerete szükséges. Szerencsére erre nincs szükség, mert a GLUT (OpenGL Utility Toolkit) a platformfüggő részeket elfedi, és egy egységes API-n keresztül elérhetővé teszi a szükséges funkciókat. Hátránya, hogy a GLUT tudása limitált, bonyolultabb felhasználói felületet nem lehet vele könnyen létrehozni, azonban példaprogramokhoz, animációkhoz, játékokhoz tökéletes.

4.3. ábra - OpenGL, GLUT, és az alkalmazás helye a szoftveres veremben

Az elkészítendő alkalmazások közvetlenül használják majd a GLUT-ot, amely az adott platformon elérhető API-val létrehozza az ablakot, kezeli a felhasználói eseményeket. Emellett az alkalmazások használják a GLU, és a GL könyvtárak függvényeit is. Ezek az operációs rendszeren keresztül eljutnak az eszköz illesztőprogramjához, amely megszólítja a grafikus hardvert (4.3. ábra - OpenGL, GLUT, és az alkalmazás helye a szoftveres veremben). Látszik, hogy csak platform független könyvtárakat fognak használni az alkalmazások, így ugyanazt a kódot le lehet fordítani Windows-on, Linux-on, és Mac OS X-en is.

3.1. GLUT telepítés Windows rendszerben

A http://user.xmission.com/~nate/glut.html címről le kell tölteni a glut-3.7.6-bin.zip fájlt. A zip fájlban lévő glut32.dll-t vagy közvetlenül a GLUT-ot használó .exe fájl mellé kell rakni, vagy a c:\ Windows\

System32\ könyvtárba, így minden program meg fogja találni.

A .h és .lib fájlokat vagy egy külön könyvtárban kell elhelyezni, és így a fejlesztő környezetben külön be kell állítani a könyvtár helyét, vagy Visual Studio verziótól függően a következő helyre kell másolni:

• Visual Studio 2005

glut.h -> C:\ Program Files\ Microsoft Visual Studio 8\ VC\ PlatformSDK\ Include\ gl glut.lib -> C:\ Program Files\ Microsoft Visual Studio 8\ VC\ PlatformSDK\ Lib

• Visual Studio 2008

glut.h -> C:\ Program Files\ Microsoft SDKs\ Windows\ v6.0A\ Include\ gl glut.lib -> C:\ Program Files\ Microsoft SDKs\ Windows\ v6.0A\ Lib

• Visual Studio 2010

glut.h -> C:\ Program Files\ Microsoft SDKs\ Windows\ v7.0A\ Include\ gl glut.lib -> C:\ Program Files\ Microsoft SDKs\ Windows\ v7.0A\ Lib

4. Adatok, konstansok és függvények az OpenGL

In document 3D megjelenítési technikák (Pldal 134-139)