OpenGL ES 2.0 tapasztalatok – I. rész

Posted by | · · · | Cégélet · Webstar Works | Nincs hozzászólás a(z) OpenGL ES 2.0 tapasztalatok – I. rész bejegyzéshez

A Sprinkfield fejlesztésekor az OpenGL-lel csak néha találkoztam, a Cocos2D sikeresen kiszolgálta az igényeinket. Azonban az új, készülő játékunknál már nem elég néhány sprite-ot „egymásra hányni”, ezért kénytelen voltam jobban beleásni magam az OpenGL lelki világába. Szintaktikailag semmi extra, de a futószalag-programozás elsajátítása, a mátrixok, vertexek, textúrák, shaderek és puffer objektumok kapcsolatának megértése nem pár órás, hanem inkább pár hetes feladat volt. Elmondhatom, hogy ugyan sok dolog egyértelművé vált már számomra, de könnyelmű dolog lenne azt mondani, hogy OpenGL guru vagyok.

Ebből adódóan folyamatosan szívok problémákba ütközöm, olyanokba, amiket valamelyik dokumentáció mélyén biztosan megírtak, illetve mások már megoldottak.

Háromszögek, textúrák

A készülő játékban egy nagyon hosszú, folyamatosan ismétlődő textúrájú tájelemet kell megjeleníteni. Erre az OpenGL-ben az az egyik megoldás – a részleteket kihagyva, csak a problémára koncentrálva –, hogy egy háromszögekből álló sávot (GL_TRIANGLE_STRIP) ismételve lefedünk egy képpel (GL_TEXTURE_WRAP_S ésvagy GL_TEXTURE_WRAP_T értéket GL_REPEAT-re állítjuk).

road

kép/textúra

trianglestrip

háromszögsávval definiált terület

merged

összefésült nézet, a textúra “ráfeszül” a sávra, és ismétlődik

result

várt végeredmény

Az OpenGL a háromszögeket – ezzel a beállítással – így rajzolja ki: (1, 2, 3), (2, 3, 4), (3, 4, 5)…

A probléma

Ez az iOS Simulator-ban tökéletesen működött… mivel ez csak egy szimulátor, ezért az OpenGL-t is szoftveresen oldja meg, kihagyva a videókártyát. Amint azonban készüléken teszteltem, azt vettem észre, hogy a 127. ismétlődés után elkezdett szétesni a textúra.

notsobad
bad
worse
worst

Nem kísérleteztem ki, hogy mi van akkor, ha a textúra alapjául szolgáló képet a kétszeresére vagy a felére növelem, mivel ezzel csak ideiglenesen oldottam volna meg a problémát, előbb-utóbb ugyanúgy szétesett volna a kép. A netet bogarászva a legfontosabb segítséget itt találtam: http://stackoverflow.com/q/8787483/89364

Röviden: a videókártyának bizonyos méret fölött olyan kerekítési hibái vannak, amik láthatóvá válnak az alkalmazásban.

A megoldás

A textúrát több rövidebb háromszögsávra illesztem: a fenti képen az 1-8 és a 7-14 közötti szakasz két, 6 darab háromszögből álló sávra válik szét. A textúra pontosan lefedi a szakaszt, az egyes szakaszok pedig mindig pontosan a teljes textúrát használják. Ennek az az előnye, viszonylag kis redundanciával (a 7. és 8. vertexkoordinátát kétszer kell felhasználni) ugyanazt tudjuk megjeleníteni. Valójában továbbra is csak egy háromszögsáv kerül kirajzolásra.

trianglestrip2

háromszögsáv a módosítás után

Ebben az esetben így módosul a kirajzolás:  …(6, 7, 8), (7, 8, 9), (8, 9, 10), (9, 10, 11)… Kérdés, hogy mi történik a középső két „háromszöggel”? Ezek degenerált háromszögek, csak szoftveresen léteznek, a hardver okosan figyelmen kívül hagyja.

Ennek az egész megoldásnak az előnye – azon kívül, hogy nem esik szét a kép – az volt, hogy minimális helyen kellett módosítani a programot. Egyrészt – nálunk – minden 16. vertex után még kettőt kellett beilleszteni, másrészt kirajzoláskor ugyanezt a két vertexet kellett továbbadni az OpenGL-nek. A plusz háromszögek száma kb. 10%-kal nőtt. Mivel viszont csak néhány 100 háromszögről van szó, ez nem jelent különösebben nagy plusz terhelést a grafikus kártyának.

Share on FacebookShare on Google+Email this to someoneTweet about this on TwitterShare on RedditShare on LinkedIn

No Comments

Leave a comment