Il modo più veloce per disegnare quad in OpenGL ES?


22

Sto usando OpenGL ES 2.0 Ho un sacco di quad da disegnare, mi piacerebbe poter passare solo 4 vertici per quad come se stessi usando GL_QUADS, ma fondamentalmente voglio solo sapere il modo migliore di disegnare un mazzo di quad separati.

Finora quello che ho scoperto potrei fare: -GL_TRIANGLES (6 vertici per quad) -Digenerato GL_TRIANGLE_STRIP (6 vertici per quad)

Possibilita 'che ho trovato: -GL_TRIANGLE_STRIPS con un valore di indice speciale che reimposta quad strip (ciò significherebbe 5 indici per quad, ma non penso che sia possibile OpenGL ES 2.0)

Risposte:


33

Usa solo il buffer dell'indice e GL_TRIANGLES. In questo caso hai bisogno di 4 vertici + 6 indici per quadrante (6 indici aggiuntivi possono suonare in grande sovraccarico, ma in realtà non lo è - una volta che hai costruito il tuo buffer di indice non devi toccarlo di nuovo). Vedi questa pagina per maggiori informazioni (cerca glDrawElements)

Codice di esempio semplice:

GLfloat vertices[] = {-1, -1, 0, // bottom left corner
                      -1,  1, 0, // top left corner
                       1,  1, 0, // top right corner
                       1, -1, 0}; // bottom right corner

GLubyte indices[] = {0,1,2, // first triangle (bottom left - top left - top right)
                     0,2,3}; // second triangle (bottom left - top right - bottom right)

glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);

Inoltre, se stai disegnando un solo quadrante hai bisogno di solo 4 vertici per disegnarlo con strisce triangolari ( come mostrato in Wikipedia ) ma immagino che tu lo sapessi già.


Il trucco tradizionale per fondere più strisce triangolari in una singola striscia è "triangoli degeneri": la ripetizione dell'ultimo elemento di una striscia e il primo elemento della striscia successiva creano 2 triangoli con area zero, che quindi non disegnano nulla. Considera i secondi indici quad (4, 5, 6, 7). Il buffer indice per GL_TRIANGLE_STRIP di due quadratini potrebbe essere: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. I triangoli degeneri sono 3,3,4e 3,4,4. Vale la pena farlo? No, a meno che i quadricipiti tendano a venire in coppia (o più) con bordi comuni. Se il 2 ° quad è {3, 2, 4, 5}, allora strip è {0,1,3,2,5,4}.
ToolmakerSteve

8
E per renderlo chiaro a chiunque arrivi e ha bisogno di disegnare un sacco di quad: per motivi di prestazioni, NON copiare il codice sopra e fare una chiamata glDrawElements UNA VOLTA PER OGNI QUAD . Costruisci invece UN array di vertici e UN array di indici che include TUTTI i quad che vuoi disegnare. Usando GL_TRIANGLES, due quadratini potrebbero avere indici {0,1,2, 0,2,3, 4,5,6, 4,6,7}o altrettanto buono {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Una buona lezione per aiutarlo è glText-Android / SpriteBatch
ToolmakerSteve

6

L'uso dei buffer di indice non è necessariamente più veloce, come indicato nei documenti Apple, "Per prestazioni ottimali, i tuoi modelli devono essere inviati come una singola striscia triangolare non indicizzata utilizzando glDrawArrays" .

Quindi, mentre un GL_TRIANGLE_STRIPtestamento lo farà in 4 vertici senza bisogno di un buffer di indice, e puoi usare un buffer di indice, è piuttosto zoppo cercare di "salvare" ripetendo 2 vertici . Per questo motivo, ti suggerisco di disegnare 2 separati GL_TRIANGLESe ripetere i 2 vertici sulla diagonale .


8
Uhm, no. Quello che dice quel documento è che i tuoi modelli devono essere inviati come una singola striscia triangolare INDEXED. E la frase successiva è "Per evitare di specificare più volte i dati per lo stesso vertice nel buffer dei vertici, utilizzare un buffer di indice separato e disegnare la striscia triangolare usando la funzione glDrawElements". Che è esattamente quello che hai deciso di essere "zoppo".
davidf2281

3
Dato che il paragrafo doc ora fa riferimento a glDrawElements piuttosto che a glDrawArrays, probabilmente è stato riscritto da questa risposta. Tuttavia, il punto sollevato dal documento era che, per prestazioni, fornisce una singola striscia (anziché più strisce, quindi più chiamate gl). In questa situazione, credo che la differenza tra usare gli indici o no sia insignificante ; ciò che conta è inserire tutto in un singolo array di vertici (oltre a un array di indici opzionale), in modo da poter effettuare una singola chiamata gl.
ToolmakerSteve

0

Il grande vantaggio sul desktop è quello di spostare i dati in VBO GL_STATIC_DRAW. Presumibilmente questo vale anche per la GPU MBX di iPhone.


-2

L'uso GL_TRIANGLE_FANper un quad usa 4 vertici, non 6.


Sì, ma anche così GL_TRIANGLE_STRIP, come hanno già sottolineato altre risposte.
Anko,

@Sig. Blah - Ti sei perso il punto della domanda, ovvero come fare in modo efficiente un sacco di quad. Non si dovrebbe fare una chiamata gl per ogni quad, ma piuttosto combinare molti quad in un singolo array, che può essere disegnato con una singola chiamata gl. GL_TRIANGLE_FAN non aiuta in questo, quindi è raramente utile nel rendering ad alte prestazioni.
ToolmakerSteve
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.