Az utóbbi időben felmerült az igény arra, hogy az engineben használt shadereket valahogy rendszerezzem, ugyanis legalább két nyelven meg volt írva mindegyik (némelyik még mobilra is). Ez így kezelhetetlen ha sok shaderről van szó, ráadásul az újrafelhasználást is nehéz megoldani mert sok GLSL compiler nem tud pl. #include-ot...
Első gondolatom a CG volt, de az sokszor túlságosan megengedő, illetve vannak olyan dolgok (pl. struct) amit egyes androidos tabletek nem tudnak lefordítani. Akadályokat meg nem akarok magam elé állítani, mert naponta tapasztalom a hátrányait...
Ezért a scriptes tutoriálban ismertetett fordítót kezdtem el átalakítani/bővíteni. A különbség lényeges, mert nem assemblyre fordítom a kódot, hanem egy másik magas szintű nyelvre. Amíg a fogalmak nagyjából ekvivalensek, addig nincs is különösebb gond. Például a HLSL-es szemantika megfeleltethető a GLSL-es attribútumoknak.
A fordító fölöslegesen ugyan, de minimális kódolással kibővíthető más (magas szintű) nyelvekkel. Az outputja mindig az adott nyelvre vonatkozó kód, a fordítás során keletkező metaadatokkal (pl. uniformok kezdőértékei). Ebből következik, hogy ezt az engine oldalán értelmezni kell tudni, de megkötéseket nem tesz. Pl. ha nem implementáltál le ID3DXEffect-hez hasonló osztályt, attól még bőven be tudod tölteni.
A shader írást elősegítendő a már említett uniform kezdőérték mellett a fordító a konstans kifejezéseket fordítási időben kiértékeli, az implicit típuskonverziókat pedig elvégzi (míg a GLSL valami érthetetlen oknál fogva ezeket tiltja, de még csak nem is következetesen). A fordítás egy előfordítással kezdődik, mint a legtöbb C-szerű nyelvben. Makrók ugyanúgy használhatók, akár függvénymakrók is.
A #include direktívához kapcsolódik, hogy az uniformokat többször is lehet deklarálni, amíg pontosan megegyeznek. Ez azért kellett, mert némelyik effekt fájl egy már létezőt bővít tovább (díszítő tervminta).
A hibakezeléskor kiírt sorszámokkal volt egy kis probléma, mert inkludált fájlok esetén arra vonatkozóan kéne kiírni a hibaüzenetet. Ezért az előfordító a kódba #line direktívákat szúr be, és ez meglepő módon a fordítónak szól. Ez nem elvetemült dolog, más fordítók is így csinálják. Egy másik probléma a sorszámokkal, hogy - mint már említettem - a bison a lehető legnagyobb kifejezést illeszti, azaz ha valami hiba mondjuk a conditional szabályban derül ki, akkor a sorszám az if blokk végére fog mutatni. Ezt úgy lehet megoldani, hogy minden utasítás eltárolja a saját sorszámát (de nem csináltam meg).
A teszteléshez összeraktam egy editort is, amivel gyorsan lehet validálni az effekt fájlt.
Látható, hogy a nyelv erősen hasonlít a HLSL FX-re. A mobilra való fejlesztést szem előtt tartva bevezettem a quarterN típust, ami a lowp float-nak felel meg. Megint csak azért kell ez, mert egyes mobil GPU-k lassan, vagy hibásan kezelik a highp-t. Például ha egy átlagos textúrából olvasol, oda bőven elég ez.
Mostanra a teljes shader libraryt átírtam erre és tökéletesen működik, sőt a kódmennyiség a harmadára csökkent. Nyilván erre is igaz az on-demand jellegű fejlesztés, tehát azt tudja ami kell.