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