Ugrás a tartalomhoz

3D megjelenítési technikák

Dr. Fekete Róbert Tamás, Dr. Tamás Péter, Dr. Antal Ákos, Décsei-Paróczi Annamária (2014)

BME-MOGI

4. fejezet - OpenGL

4. fejezet - OpenGL

Az OpenGL (Open Graphics Library) egy platformfüggetlen API (Application Programming Interface), amellyel a grafikus hardvert szabványos felületen keresztül lehet elérni. Az OpenGL használatával valós idejű 2D és 3D grafikát lehet létrehozni. OpenGL-t széles körben alkalmaznak, például CAD alkalmazásokban, virtuális valóság megjelenítésénél, tudományos vizualizációkban, és a videó játékokban.

Az 1981-ben alapított Silicon Graphics (SGI) 3D számítógépes grafikához gyártott hardvert, és softvert. Az általuk gyártott grafikus hardvereket az IrisGL-t (Integrated Raster Imaging System Graphical Library) nevű API-n keresztül lehetett elérni, amellyel 2D és 3D grafikát lehetett létrehozni az SGI munkaállomásain. A 90-es évek elejére az SGI lett a piacvezető a 3D grafika terén, és az IrisGL de facto szabvánnyá vált.

A többi gyártó (Sun Microsystem, Hewlett-Packard, IBM) is kezdte behozni a lemaradását a 3D grafika terén, ezért az SGI szabványosította az IrisGL-t, a grafikához nem kötődő részeket kidobta belőle, és 1992-ben kiadta az OpenGL specifikációt, amely alapján a gyártók elkészítették az OpenGL implementációjukat. A hardvergyártók eszközmeghajtókat írtak (device drivers), amellyel a saját hardverüket lehetett elérni az OpenGL API-n keresztül. A szoftvergyártók kiegészítették az operációs rendszerüket az OpenGL specifikus részekkel.

Microsoft a Windows NT 3.5-ös verzióban implementálta először az OpenGL-t, amely 1994-ben jelent meg. Az implementáció teljesen szoftveres volt, mert akkoriban még nem volt dedikált 3D grafikát számoló hardver PC-re. Ezután a Microsoft 1995-ben kiadta a saját 3D programozásra, főleg játék programozásra szánt API-ját a DirectX-et, amely csak Windows operációs rendszeren fut. A DirectX több játékprogramozással kapcsolatos API-ból áll (pl. beviteli eszköz, joystick-kezelés, hangkezelés, 2D grafika), 3D grafikát a Direct3D-n keresztül lehet programozni. A Direct3D kezdetben nehézkesen használható volt, de a Microsoft folyamatosan fejlesztett rajta, és az 5.0-s verziótól kezdve vált felhasználóbaráttá. A Microsoft úgy tartotta, hogy a komoly, „professzionális” alkalmazásokra (például CAD) való az OpenGL, ezért kezdetben csak a Windows NT vonal támogatta, a Windows 95 nem.

1996-ban adta ki az idSoftware a Quake nevű 3D-s FPS játékát, amelynek 1997-ben jelent meg egy módosított változata GLQuake néven. A GLQuake a 3D megjelenítéshez a 3D grafikus hardvert használta az OpenGL API-n keresztül. Később OpenGL alapon még több PC-s játék jelent meg, például Quake 2, Unreal, Half-Life.

Ebben az időben jelentek meg az első dedikált 3D grafikus hardverek is. Az elsők között volt a 3Dfx Interactive által gyártott Voodoo Graphics kártya. A piacon lévő többi kártyát tudásban, és teljesítményben is felülmúlta, nagy siker volt. Programozása a 3Dfx saját Glide nevű API-ján keresztül történt. Az API gyártóspecifikus volt, ezért néhány év múlva veszített a népszerűségéből. Az Nvidia 1999-ben jelentette meg a GeForce 256 kártyát, amelyet GPU-nak (Graphics Processing Unit) nevezett el. Újdonsága a T&L (Transform & Lighting) technológia volt, amely a csúcspont (vertex) transzformációk számítását a kártyán valósította meg a CPU helyett. 3Dfx sose implementálta a hardveres T&L-t, a cég hanyatlani kezdett, végül 2002-ben csődbe ment, és megvette az Nvidia. A 2000-es évekre a két fő GPU gyártó az Nvidia, és az ATI lett. Mindkét gyártó GPU-i egyaránt támogatták az OpenGL-t és a Direct3D-t is.

Az OpenGL szabványban rögzített funkciók mellett lehetőség van gyártó specifikus kiterjesztéseket (extension) is használni. Az OpenGL szabványt 1992-től az OpenGL ARB (OpenGL Architectural Review Board) nevű csoport fejlesztette az SGI vezetésével. A csoport több OpenGL érdekelt gyártóból állt, és szavazással döntöttek a fejlesztés irányáról. Például az eddig csak kiterjesztésként létező funkciókat szabványosítják, és az OpenGL egy új verziójában specifikálják. A 2006-os SIGGRAPH konferencián jelentették be, hogy az OpenGL ARB helyett a Khronos konzorcium veszi át a szabvány fejlesztését és karbantartását.

A Grafikus csővezeték

Az OpenGL segítségével egyszerű, térben elhelyezkedő 3D-s grafikus primitíveket jeleníthetünk meg a képernyőn. Ennek során megválaszthatjuk a térből síkba való leképezés módját, az objektumok színét, megvilágítását és mintázatát. A síkbeli képen többféle módon is figyelembe vehetjük azt, hogy az elemek a térbeli elhelyezkedésből következően takarják egymást.

Ha az OpenGL-t használjuk, akkor az előírt grafikus megjelenítés nem kerül azonnal a képernyőre (a képernyőkártya memóriájába), hanem bekerül egy feldolgozási sorba, a „megjelenítési csőbe”. A megjelenítési cső egyes műveleteit a 4.1. ábra - Az Open GL megjelenítési csővezeték szemlélteti.

4.1. ábra - Az Open GL megjelenítési csővezeték

Az Open GL megjelenítési csővezeték


A GPU-k csak primitíveket, azaz pontokat, vonalakat és háromszögeket tudnak nagy sebességgel megjeleníteni. A primitívek a kirajzoláshoz a grafikus csővezeték (4.1. ábra - Az Open GL megjelenítési csővezeték) különböző fázisain mennek keresztül az alkalmazás rajzolás kérésétől egészen a képernyőig.

Az OpenGL 2.0 egyik újdonsága volt, hogy a szabványban rögzítették a csővezeték programozhatóságát. Korábban a vertex shader és a fragment shader előre meghatározott műveleteket végzett el hardverből (fix-function pipeline), amelyek paraméterezhetőek voltak. Az egyre gyorsabb GPU-kal lehetővé váltak számításigényesebb feladatok valósidejű elvégzése is. Így egyéni árnyalás modellek és effektek is megvalósíthatóak, amelyeket a gyártók nem tudnak előre implementálni hardverben. A testreszabhatóságot a csővezeték programozhatóságával érték el.

Alkalmazás

A első ábrát (4.1. ábra - Az Open GL megjelenítési csővezeték) tanulmányozva végigkövethetjük az OpenGL képalkotási folyamatának lehetőségeit és lépéseit. Első lépésként az alkalmazás összeállítja a kirajzolandó primitív csúcspontjait (vertex), amelyek a rajzoláshoz szükséges attribútumokat tartalmazzák. Ilyen attribútum a pozíció, a szín, a textúra-koordináta vagy -koordináták, a normál vektor. Lehetőségünk van arra, hogy térbeli objektumokat leíró csúcspontjaikkal (vertex) jellemezve adjunk át megjelenítésre. Szükség esetén azonban magunk is definiálhatjuk a pixeleken megjeleníteni kívánt információt. Érdemes már itt megemlíteni, hogy az alapobjektumok sorozatát listába szervezhetjük (display lista), amelyet ezek után egyetlen rajzelemként kezel a rendszer.

Vertex Shader

Az alkalmazástól érkező vertexek mindegyikén lefut egy program, a vertex árnyaló (vertex shader), amelynek a feladata a vertexek képernyőre vetítése. Ez 3D grafikában rendszerint perspektivikus vetítéssel történik. A vertex shader kimenete a transzformált vertex pozíciója homogén koordinátákban kifejezve. Emellett még egyéb számításokat is végezhet, például a fényforrások alapján meghatározhatja a vertex árnyalt színét is.

Raszterizálás

A raszterizálás során a topológia figyelembe vételével megtörténik a vágás, azaz a képernyőből kilógó háromszögeket, vagy azok kilógó részét eldobja a rendszer. Ezután a raszterizáló a háromszöget felosztja pixel méretű fragmensekre (fragment). Egy fragmens tartalmazza a pixel framebuffer-beli címét, illetve a vertexek egyéb paramétereit, amelyet a hardver lineárisan interpolál (4.2. ábra - Háromszög raszterizálás, interpolálás).

4.2. ábra - Háromszög raszterizálás, interpolálás

Háromszög raszterizálás, interpolálás


Fragment Shader

A raszterizálás során előálló fragmensek mindegyikére vonatkozóan lefut egy program, a fragmens árnyaló (fragment shader), amelynek feladata a fragmens színének meghatározása. Ehhez a fragmensben lévő interpolált paramétereket is használhatja, amely alapján például textúrát mintavételezhet, vagy csak szimplán kiírja a színt. A fragmens shader kimenete az adott fragmens színe.

Raszterműveletek

A raszterműveletek (raster operations, ROP) feladata fragment shader-ből előálló fragmensek egyesítése a framebuffer-ben lévő pixelekkel. Ez lehet szimpla felülírás is, vagy részben átlátszó fragmensek esetén az új pixel színéhez figyelembe kell venni a framebuffer-ben lévő pixel színét is (blending). 3D esetén a takarási feladat is itt kerül megoldásra.

Framebuffer

A raszterműveletek kimenete a framebuffer-be kerül, amely több puffer együttese. Minimum kell egy színpuffer, amely az összes pixelt tartalmazza tipikusan RGB színtérben. Emellett lehetnek egyéb pufferek is, például mélységpuffer a takarási problémák megoldásához, vagy alkalmazástól függően akár több szín pufferbe is lehet írni egyszerre. Például a sztereó 3D megjelenítésnél külön szín- és mélységpuffere van a bal és a jobb szemnek.

Az alapértelmezett framebuffer a képernyő, azonban lehetőség van saját framebuffer-t létrehozni. Ilyenkor a pixelek nem jelennek meg a képernyőn, hanem a memóriába kerülnek, amelyet textúraként később fel lehet használni. Ezzel érdekes effekteket lehet létrehozni.