2010-10-02 9 views
11

Nella mia applicazione disegno un sacco di cubi tramite OpenGL ES Api. Tutti i cubi sono delle stesse dimensioni, solo che si trovano in diverse coordinate nello spazio. Posso pensare a due modi di disegnarli, ma non sono sicuro di quale sia il più efficiente. Non sono un esperto di OpenGL, quindi ho deciso di chiedere qui.Modalità di disegno efficiente in OpenGL ES

Metodo 1, che è quello che uso ora: Poiché tutti i cubi sono di dimensioni identiche, a calcolare vertex buffer, index buffer, tampone normale e buffer di colore sola volta. Durante un aggiornamento della scena, analizzo tutti i cubi, eseguo bufferData() per lo stesso set di buffer e quindi disegno la mesh triangolare del cubo usando la chiamata drawElements(). Poiché ogni cubo si trova in una posizione diversa, traduco la mvMatrix prima di disegnare. bufferData() e drawElements() viene eseguito per ogni cubo. Con questo metodo, probabilmente risparmio molta memoria, non calcolando i buffer ogni volta. Ma sto facendo molte chiamate a drawElements().

Metodo 2 sarebbe: trattare tutti i cubi come insieme di poligoni sparsi in tutto lo scena. Calcola vertici, indici, colori, buffer normali per ciascun poligono (in realtà triangoli all'interno dei poligoni) e trasferiscili nella memoria della scheda grafica nella singola chiamata a bufferData(). Quindi disegnali con una sola chiamata a drawElements(). Il vantaggio di questo approccio è che faccio una sola chiamata bindingBuffer e drawElements. Lo svantaggio è che uso molta memoria per creare i buffer.

La mia esperienza con OpenGL è abbastanza limitata, per non si sa quale uno dei metodi di cui sopra è meglio dal punto di vista delle prestazioni.

Sto usando questo in un'applicazione WebGL, ma è una generica domanda di OpenGL ES.

+0

Non so la risposta, ma dopo 2 giorni w/o risposte I sus Il tuo approccio migliore è provare a implementare il metodo 2 ed eseguire alcuni test delle prestazioni. – LarsH

+0

sì, lo immagino anche io. posterò quello che trovo. – Jayesh

risposta

14

ho implementato il metodo 2 e vince da una frana. Il presunto svantaggio di un'alta quantità di memoria sembrava essere solo la mia immaginazione. Infatti il ​​garbage collector è stato invocato nel metodo 2 solo una volta, mentre è stato invocato per 4-5 volte nel metodo 1.

Lo scenario OpenGL potrebbe essere diverso dal mio, ma se si è arrivati ​​qui alla ricerca di suggerimenti sulle prestazioni, la lezione da questa domanda è: identifica le parti nella scena che non cambiano frequentemente. Non importa quanto siano grandi, mettili in un singolo buffer set (VBO) e caricali nella memoria grafica per un numero minimo di volte. Ecco come devono essere usati i VBO. La larghezza di banda della memoria tra il client (ad esempio la tua app) e la scheda grafica è preziosa e non vuoi consumarla spesso senza motivo.

Leggere la sezione "Oggetti del buffer di vertice" nel cap. 6 della "Guida alla programmazione OpenGL ES 2.0" per capire come dovrebbero essere usati. http://opengles-book.com/

+0

Come regola generale in WebGL: Less Draw Calls === Più veloce. Se i tuoi cubi sono statici o si muovono raramente (come, ad esempio, un paesaggio di Minecraft) allora sì, un unico buffer statico è la strada da percorrere. Non sottolineerei troppo l'utilizzo della memoria. I cubi sono piuttosto leggeri. – Toji

+0

Come hai inviato alla tua GPU tutti i tuoi dati cubi in modo che tu possa disegnare in una singola chiamata drawElements? – AlvinfromDiaspar

-1

propongo seguente approccio:

On carico:

  1. generare coordinate tampone (per un cubo) e si carica in VBO (gl.glGenBuffers, gl.glBindBuffer)

On pareggio:

  1. tampone Bind (gl.glBindBuffer)

  2. Draw ciascuna cella (loop)

    2,1. Spostare posizione corrente al centro del cubo corrente (gl.glTranslatef(position.x, position.y, position.z)

    2,2.Draw current cube (gl.glDrawArrays)

    2.3. posizione di movimento di nuovo (gl.glTranslatef(-position.x, -position.y, -position.z))

+0

Per uno, non è necessario ripetere il "gl". Ad esempio, sono gl.drawArrays. Due, OpenGL ES non ha glTranslate o nessuna delle altre funzioni della matrice. Tre, hai sostanzialmente descritto i poster "Metodo 1", che in realtà è il più lento dei due metodi. (Ma se il metodo migliore dipende effettivamente dalle esigenze del programma) – Toji

5

so che questa domanda è già una risposta, ma penso che la pena sottolineare la presentazione di Google IO di ottimizzazione WebGL:

http://www.youtube.com/watch?v=rfQ8rKGTVlg

che coprono, in sostanza, , questo stesso identico problema (molti di forme identiche con diversi colori/posizioni) e parlare di alcuni ottimi modi per ottimizzare una scena del genere (e anche la loro è dinamica!)

+0

"Dinamico" è un po 'troppo lungo - le posizioni dell'oggetto sono predeterminate ('x = sin (tempo)' ecc. Quindi tutto può essere calcolato sulla GPU. Non c'è un grafico di scena e le mesh non cambiano mai. È stato comunque un discorso utile. – Timmmm