2012-01-19 13 views
6

Sto scrivendo un renderer multipiattaforma. Voglio usarlo su Windows, Linux, Android, iOS.Visualizzatore multipiattaforma in OpenGL ES

Pensi che sia una buona idea evitare l'astrazione assoluta e scriverlo direttamente in OpenGL ES 2.0?

Per quanto ne so dovrei essere in grado di compilarlo su PC contro OpenGL standard, con solo piccole modifiche nel codice che gestisce il contesto e la connessione al sistema di finestre.

+0

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

+0

Se hai Android o iOS, prova a cercare "Kivy" nel Play Store o nell'App Store per vedere alcuni esempi in uso. – trusktr

risposta

8

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.

+0

Grazie per la tua esaustiva risposta.Quindi pensi che sia meglio creare una sorta di astrazione del renderer OpenGL? Ad esempio, posso avere una trama rappresentata dalla classe Texture2D. Questa classe conterrebbe cose comuni a entrambe le specifiche, ma l'implementazione di alcune cose sarebbe diversa. – runnydead

+0

@hubrobin: Non ha bisogno di essere così astratto. Hai solo bisogno di un codice specifico per piattaforma in luoghi particolari. Ora, se hai come target GL 3.3 invece di 2.1, avrai bisogno di molto più di un'astrazione. –

+0

Non desidero supportare più funzionalità su PC. Quindi stai sostanzialmente dicendo che è fattibile? – runnydead

3

Nella mia umile esperienza, l'approccio migliore per questo tipo di requisiti è quello di sviluppare il motore in un sapore C puro, senza strati aggiuntivi su di esso.

Io sono lo sviluppatore principale del motore PATRIA 3D che si basa sul principio di base che hai appena menzionato in termini di portabilità e lo abbiamo raggiunto semplicemente sviluppando lo strumento su librerie standard di base.

Lo sforzo di compilare il codice sulle diverse piattaforme è molto ridotto.

Lo sforzo effettivo per trasferire l'intera soluzione può essere calcolato in base ai componenti che si desidera incorporare nel proprio motore.

Ad esempio:


standard C:

motore 3D

gioco di logica

Gioco AI

Fisica


+


interfaccia Finestra (GLUT, EGL ecc) - dipende dalla piattaforma, in ogni caso potrebbe essere GLUT per desktop e EGL per i dispositivi mobili.

Human Interface - dipende dal porting, Java per Android, OC per IOS, qualunque sia la versione desktop

Sound Manager - dipende dalle porting

servizi di mercato - dipende dal porting


In questo modo, puoi riutilizzare il 95% dei tuoi sforzi in modo trasparente.

abbiamo adottato questa soluzione per il nostro motore e finora vale davvero l'investimento iniziale.