Utilizzare buffer uniformi (ovvero buffer costanti nel gergo D3D).
Finché tutti i tuoi shader concordano sul layout e sul punto di rilegatura di ciascuno di questi buffer, l'aggiornamento diventa un gioco da ragazzi. I modelli non hanno bisogno di sapere nulla sugli shader. Devono solo aggiornare la matrice di visualizzazione del modello nel loro buffer costante e la pipeline di rendering lo utilizzerà automaticamente.
Almeno direi che dovresti avere due di questi buffer. Il primo dovrebbe memorizzare la matrice di proiezione, la matrice della videocamera, la matrice di proiezione della videocamera concatenata, le informazioni sulla vista, i dettagli frustrati e le inversioni della matrice. È necessario aggiornare questo buffer solo una volta per scena.
Quindi assegnare a ciascun modello un altro buffer per memorizzare la sua matrice vista modello, la matrice normale, le inversioni e le proprietà del materiale. Questo viene aggiornato una volta per ciascun modello e può essere eseguito in un passaggio di aggiornamento diverso (se / quando appropriato). Le informazioni sul materiale possono / devono essere spostate in un terzo buffer specifico del materiale se si ha la possibilità di condividere materiali tra più oggetti.
In una configurazione con ombreggiatura in avanti ha un certo senso mettere tutte le luci in un altro buffer e in ombre differite ha anche senso utilizzare un buffer per luce per il passaggio della luce (al posto di un buffer modello / materiale utilizzato nel passaggio della geometria).
Nota che hai bisogno di una versione moderatamente aggiornata di GL per usare tutti i buffer uniformi (3.1 o un'estensione; abbastanza comune oggi tranne che su alcuni laptop più vecchi ma ancora in servizio) e hai bisogno di una versione abbastanza recente per essere in grado di associare buffer uniformi a specifiche posizioni di associazione dall'interno del codice shader (4.2; ancora non comune ma migliorando) altrimenti devi fare più lavoro nel tuo codice lato CPU per impostare le cose (il tuo codice CPU deve conoscere il giusto legame punti comunque, quindi è più un odore di API che un problema serio). OpenGL | ES non ha aggiunto buffer uniformi fino alla 3.0, che purtroppo non è ancora supportato sulle piattaforme mobili più diffuse.
Se i buffer non sono un'opzione, sarà necessario un posto globale per memorizzare le posizioni degli indici per lo shader attivo. È possibile utilizzare glGetUniformLocation
dopo aver caricato lo shader per trovare gli indici per nomi noti (simili ModelViewMatrix
o simili), quindi archiviare questi indici. Il tuo rendering può mappare valori enum come MODEL_VIEW
passati aSetUniform
funzione wrapper per guardare nello shader associato, trovare l'indice e chiamare glUniform
correttamente. Non è un grande cambiamento nell'uso del codice client da parte dei buffer oltre alla necessità di impostare ciascuna uniforme singolarmente se si ottiene tutto ben confezionato.
Vedi GLSL Inteface Blocks e Uniform Buffer Objects .