Hirdetés

Alkalmazásfejlesztés badára: OpenGL alapozás

A fejlesztői blogban mostantól a grafikus szoftverfejlesztésről is olvashattok. Mivel a bada az OpenGL ES szabványt használja, célszerű az ismerkedést az OpenGL-lel kezdeni.

Mi is az az OpenGL?

Az OpenGL egy szabványos szoftveres interfész a grafikus hardverhez. Ez azt jelenti, hogy olyan utasításkészlet van benne definiálva, amely segítségével "működésre bírhatjuk" a videokártyát. A játékok grafikája egyre komplexebb, ez a tendencia megállíthatatlannak tűnik, a képernyőn megjelenő objektumok is egyre összetettebbek és nagyobb számítási teljesítményt igényelnek. Ezért célszerű ezekkel a számításokkal a GPU-t terhelni a processzor helyett: az OpenGL ehhez biztosít egy API-t (Application Program Interface), mely segítségével kihasználhatjuk a videokártyánkban szunnyadó erőt. Ez egy szabvány, minden videokártyával használható, így a kódunk ugyanúgy lefut egy ATI, egy nVidia, vagy egy más grafikus processzorral rendelkező kártyán is. Vagy épp a Samsung Wave-en.

Hogyan kezdődött az egész?

A számítógép megjelenése óta létezik igény a számítógépes játékokra és egyéb grafikus alkalmazásokra, melyek a hardverek fejlődésével és méginkább a videókártyák széleskörű elterjedésével egyre jobban néznek ki. Viszont ezekre fejleszteni régebben nem volt éppen leányálom: a 90-es évek elején már rengeteg eltérő típusú GPU volt a piacon, melyek azonban nem voltak szabványosítva. Ez azt jelentette, hogy mindegyikre más és más módszerrel kellett fejleszteni, a programozóknak ez rengeteg plusz munkát jelentett (mindegyikre saját driver és interfész írása). Ekkor lett igény egy szabványos grafikus könyvtárra. Ekkoriban a Silicon Graphics volt a legnagyobb gyártó, így a szabványuk, az IRIS GL vált a legelterjedtebbé, a nagy probléma azonban a nyílt forráskód hiányában rejlett. A rivális gyártók (Sun, IBM, HP) is kijöttek a saját interfészükkel, amely a PHIGS névre hallgatott, de nyíltsága ellenére vakvágánynak bizonyult a nehézkes használat és az elavult funkcionalitás miatt. A Silicon Graphics üzleti megfontolásból nyílt szabvánnyá akarta tenni az IRIS-t, azonban ez különböző buktatók miatt nem valósulhatott meg, így 1992 januárjában megszületett az OpenGL 1.0. Ez szabványosította a grafikus hardver elérését, miközben a "kód lefordítását a videokártya nyelvére" részt a gyártókra bízta, akik a videókártyák meghajtóiban (drivereiben) implementálták az OpenGL standard-et. Mondanom sem kell, ennek a hatása meglátszott a játékfejlesztésen is: a programozóknak nem kellett a sokfajta videokártyával külön-külön foglalkozniuk, ami rengeteg időt takarított meg nekik. A szabvány a kezdetek kezdetén az IRIS GL finomítása volt, később azonban a fejlődés hatására teljesen átírták. Pár évre rá megalakult az OpenGL Architectural Review Board, amely a szabvány fejlesztését tűzte ki célul. Azóta több "upgrade" is napvilágot látott, jelenleg a 4.0-ás verziónál tartunk, ez idén márciusban jelent meg. A verziók természetesen visszafele kompatibilisak, egy 4.0-t támogató kártya simán megbirkózik az alsóbb verziókkal is.

Teáskanna, az epikus objektum: egy paranccsal ki lehet rajzolni OpenGL-ben
Teáskanna, az epikus objektum: egy paranccsal ki lehet rajzolni

Érdekesség: a nagy grafikus szabványőrületet a Microsoft sem tudta figyelem nélkül hagyni (különben lőttek volna a világuralomról szóló terveiknek), így megalkották a sajátjukat, a Direct3D-t és a DirectX-et, amely az OpenGL vetélytársává nőtte ki magát, jelenleg a 11. verziónál tart, azonban csak Windows alatt használható, míg az OpenGL Windowson, Linuxon és OS X-en is, sőt a PlayStation 3-ban is megjelent.

És ami számunkra fontos: megjelent az OpenGL ES, ami beágyazott rendszerekre "portolja át" az OpenGL-t. Beágyazott rendszereken azokat a készülékeket értjük, amelyek kevésbé rugalmasak, csak bizonyos feladatokat képesek ellátni, például a PDA-k, MP3 lejátszók, játékkonzolok és a mobiltelefonok. A szabványt a Khronos Group tartja karban, erről bővebben olvashattok majd a következő posztban.

A motorháztető alatt

Mivel a következőkben konkrét fejlesztési feladatokkal fogunk foglalkozni, muszáj tisztába jönnünk az alapfogalmakkal és a belső működéssel. Ezek következnek, a teljesség igénye nélkül.

A grafikus hardver működésébe nem szeretnék nagyon mélyen belemenni, a titok elsősorban a pipeline-os felépítésben rejlik. Ezt úgy lehet a legegyszerűbben elképzelni, mint egy gyártósort, amin egy pixel megy végig, és a sor minden "állomásán" valamilyen művelet hatására finomodik a kiindulási színe. Ennek nagy előnye a párhuzamosíthatóság, egy GPU több pipeline-t tartalmaz, ergo egyszerre több pixel színén dolgozik. Szerencsére ez el van fedve programozók elől. (Zárójelben tesszük hozzá, hogy a Prohardveren rengeteg cikket lehet olvasni a témában, itt most nem célunk azoknak konkurenciát állítani, ezért az egyszerűsített leírás.)

Az OpenGL alacsony szintű API, az objektumok felépítését úgynevezett primitívekből kell megoldanunk. Ilyenek a pont (vertex), a háromszög és a poligon (legalább három csúcsot tartalmazó sokszög), ezen kívül még fényforrásokat és egy kamerát is használhatunk. Az ezekből felépített objektumhalmazt jelenetnek (scene) nevezik. Összetettebb 3D-s tárgyakat tesszellálással állíthatunk elő, ami azt jelenti, hogy az objektumot háromszög-, illetve poligonhálóval közelítjük. Ha megfelelő mennyiségű primitívet használunk, szabad szemmel nem lehet észrevenni speciális felépítés adta "hibákat" - OpenGL-ben például egy gömböt is háromszögekből lehet kirakni, a "hibák" alatt az ebből fakadó dolgokra kell gondolnunk. A primitívekből álló háló felépítése általában az objektum matematikai modelljén alapul, ritkább esetben az egyes pontok koordinátáit kell megadni. Léteznek előre megírt függvénykönyvtárak, melyek nagyban leegyszerűsíthetik a fejlesztést, legelterjedtebb talán a GLUT, azaz az OpenGL Utility Toolkit. Ez tartalmaz magasabb szintű beépített metódusokat, így komplexebb objektumokat és effekteket is használhatunk azok implementálása nélkül.

Gömb tesszelláció ikozaéderből kiindulva
Gömb tesszelláció ikozaéderből kiindulva

Egy OpenGL-ben felépített jelenet egyik legfontosabb eleme a kamera, azaz a nézőpont, ahonnan szemléljük az eseményeket. A 3D-ben felépített jelenet a kamerabeállításoknak megfelelően képződik le a 2D-s képernyőre. Ezt legegyszerűbben egy vektorként képzelhetjük el. Ha például szeretnénk 360°-ban körbenézni a jelenetünk körül, elég a kamerát körbemozgatni a középpont körül.

Lehetőségünk van az objektumainkat módosítani is, például eltolni, kicsinyíteni és nagyítani, forgatni. Mi történik a háttérben? A koordinátákat egy 4 x 4-es mátrix (4 oszlopot és sort tartalmazó táblázat) kezel. Affin transzformációkkal operálunk, melyekek olyan műveletek, amelyekben az új koordinátákat a régiekből lineáris függvényekkel állítjuk elő. Szemléletesen, a párhuzamos egyenesek módosítás után is párhuzamosak maradnak. Ezeket matematikailag nagyon egyszerűen lehet kezelni, egy mátrix-szorzással és egy eltolással megadhatók, ezért az OpenGL a transzformálásra és a modellünk 2D-be való leképezésére (modellview és projection) is ilyen mátrixokat használ. Nekünk, programozóknak szerencsére nem kell hozzányúlnunk a mátrixok tartalmához, ezeket is elfedi előlünk a keretrendszer.

Ezzel nagyjából le is fedtük az elméleti alapokat. Aki bővebben érdeklődik a téma iránt, a Red Book nevű, interneten is elérhető könyvet javaslom, kezdőként nagyon sok hasznos információt tartalmaz.

holdmester

Azóta történt

Előzmények