Pensa che sia una buona idea evitare l'astrazione assoluta e scriverlo direttamente in OpenGL ES 2.0?
Le vostre principali difficoltà con questo si occuperanno di quelle parti delle specifiche ES 2.0 che in realtà non sono le stesse di OpenGL 2.1.
Ad esempio, non è possibile spingere gli shader ES 2.0 tramite un compilatore desktop GLSL 1.20. In ES 2.0, usi cose come specificare la precisione; quelli sono costrutti illegali in GLSL 1.20.
È possibile tuttavia #define
intorno a loro, ma questo richiede un po 'di intervento manuale. Dovrai inserire uno #ifdef
nel file sorgente dello shader. Ci sono trucchi di compilazione degli shader che puoi fare per rendere questo un po 'più facile.
Infatti, poiché GL ES utilizza un set di estensioni completamente diverso (sebbene alcuni siano mirror e sottoinsiemi di estensioni GL desktop), è possibile che si desideri effettuare questa operazione.
Ogni shader GLSL (desktop o ES) deve avere un "preambolo". La prima cosa senza commento in uno shader deve essere una dichiarazione #version
. Fortunatamente per te, la versione è la stessa tra desktop GL 2.1 e GL ES 2.0: #version 1.20
. Il problema è ciò che viene dopo: l'elenco #extension
(se presente). Questo abilita le estensioni necessarie allo shader.
Poiché GL ES utilizza estensioni diverse da desktop GL, è necessario modificare questa lista di estensioni. E poiché le probabilità sono buone, avrai bisogno di più estensioni GLSL ES rispetto alle estensioni desktop GL 2.1, questi elenchi non saranno solo mappatura 1: 1, ma elenchi completamente diversi.
Il mio suggerimento è quello di impiegare la capacità di dare stringhe multiple a GLSL. Cioè, i tuoi file shader effettivi non hanno roba da preambolo. Loro solo hanno le definizioni e le funzioni effettive. Il corpo principale dello shader.
Durante l'esecuzione su GL ES, si dispone di un preambolo globale che verrà applicato all'inizio dello shader. Avrai un preambolo globale diverso nel desktop GL. Il codice sarebbe simile a questa:
GLuint shader = glCreateShader(/*shader type*/);
const char *shaderList[2];
shaderList[0] = GetGlobalPreambleString(); //Gets preamble for the right platform
shaderList[1] = LoadShaderFile(); //Get the actual shader file
glShaderSource(shader, 2, shaderList, NULL);
Il preambolo può anche includere un #define
specifico per la piattaforma. Ovviamente definito dall'utente. In questo modo, è possibile il codice #ifdef
per diverse piattaforme.
Ci sono altre differenze tra i due. Ad esempio, mentre la funzione di caricamento delle texture ES 2.0 valida chiama , funzionerà correttamente in desktop GL 2.1, non sarà necessariamente ottimale. Le cose che si caricheranno bene su macchine big-endian come tutti i sistemi mobili richiederanno un po 'di twittling dal driver in macchine desktop little-endian. Quindi potresti voler avere un modo per specificare diversi parametri di trasferimento dei pixel su GL ES e desktop GL.
Inoltre, ci sono diversi set di estensioni in ES 2.0 e desktop GL 2.1 che si desidera sfruttare. Mentre molti di loro cercano di eseguire il mirroring l'uno con l'altro (OES_framebuffer_object è un sottoinsieme di EXT_framebuffer_object), è possibile eseguire afoul di problemi simili "non proprio un sottoinsieme" come quelli sopra menzionati.
Hai sentito Kivy? È un linguaggio di programmazione multipiattaforma open source per Linux, Windows, MacOSX, Android e IOS che esegue il rendering di tutte le visualizzazioni in OpenGL (http://kivy.org). La lingua include anche il proprio widget di widget. Ho solo pensato di buttarlo lì perché c'è la possibilità che tu non voglia re-inventare la ruota se esiste già una soluzione e forse non l'hai ancora scoperta. – trusktr
Se hai Android o iOS, prova a cercare "Kivy" nel Play Store o nell'App Store per vedere alcuni esempi in uso. – trusktr