¿La forma más rápida de dibujar quads en OpenGL ES?

22

Estoy usando OpenGL ES 2.0 Tengo un montón de quads para dibujar, me encantaría poder pasar solo 4 vértices por quad como si estuviera usando GL_QUADS, pero básicamente solo quiero saber la mejor manera de dibujar un Montón de quads separados.

Hasta ahora, lo que he encontrado podría hacer: -GL_TRIANGLES (6 vértices por quad) -Degenerar GL_TRIANGLE_STRIP (6 vértices por quad)

Posibilidades que he encontrado: -GL_TRIANGLE_STRIPS con un valor de índice especial que restablece la tira cuádruple (esto significaría 5 índices por cuádruple, pero no creo que esto sea posible es OpenGL ES 2.0)

Jonathan
fuente

Respuestas:

33

Solo use el buffer de índice y GL_TRIANGLES. En este caso, necesita 4 vértices + 6 índices por quad (6 índices adicionales pueden sonar muy elevados, pero en realidad no lo es; una vez que haya construido su búfer de índice, no tendrá que volver a tocarlo). Consulte esta página para obtener más información (busque glDrawElements)

Código de ejemplo simple:

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);

Además, si está dibujando solo un quad, solo necesita 4 vértices para dibujarlo con tiras triangulares ( como se muestra en wikipedia ), pero supongo que ya lo sabía.

usuario4241
fuente
El truco tradicional para fusionar varias tiras de triángulos en una sola tira es "triángulos degenerados": al repetir el último elemento de una tira y el primer elemento de la siguiente tira se crean 2 triángulos con área cero, que no dibujan nada. Considere los segundos índices cuádruples (4, 5, 6, 7). El búfer de índice para GL_TRIANGLE_STRIP de dos quads podría ser: {0, 1, 2, 3, 3, 4,4, 5, 6, 7}. Los triángulos degenerados son 3,3,4y 3,4,4. ¿Vale la pena hacer esto? No, a menos que tus quads tiendan a venir en pares (o más) con bordes comunes. Si el segundo quad es {3, 2, 4, 5}, entonces la tira es {0,1,3,2,5,4}.
ToolmakerSteve
8
Y para dejar esto claro a cualquiera que venga y necesite dibujar un montón de quads: Por el bien del rendimiento, NO copie el código anterior y haga una llamada a glDrawElements UNA VEZ POR CADA QUAD . En cambio, construya UNA matriz de vértices y UNA matriz de índices que incluya TODOS los quads que desea dibujar. Usando GL_TRIANGLES, dos quads podrían tener índices {0,1,2, 0,2,3, 4,5,6, 4,6,7}o es igualmente bueno {0,1,2, 2,3,0, 4,5,6, 6,7,4}. Buena clase para ayudar a esto es glText-Android / SpriteBatch
ToolmakerSteve
6

El uso de buffers de índice no es necesariamente más rápido, como se indica en los documentos de Apple, "Para un mejor rendimiento, sus modelos deben enviarse como una sola tira triangular no indexada usando glDrawArrays" .

Entonces, aunque a GL_TRIANGLE_STRIPlo hará en 4 vértices sin necesidad de un búfer de índice, y puede usar un búfer de índice, es bastante lamentable intentar "guardar" la repetición de 2 vértices . Por esta razón, te sugiero que dibujes 2 separados GL_TRIANGLESy repitas los 2 vértices en la diagonal .

bobobobo
fuente
8
Mmm no. Lo que dice ese documento es que sus modelos se enviarán como una sola tira triangular INDEXADA. Y la siguiente oración es: "Para evitar especificar datos para el mismo vértice varias veces en el búfer de vértices, use un búfer de índice separado y dibuje la franja triangular usando la función glDrawElements". Que es exactamente lo que decidiste que era 'cojo'.
davidf2281
3
Dado que el párrafo doc ahora se refiere a glDrawElements en lugar de glDrawArrays, probablemente se ha reescrito desde esta respuesta. Sin embargo, el punto que el documento estaba haciendo era que, para el rendimiento, suministre una sola tira (en lugar de varias tiras, por lo tanto, múltiples llamadas gl). En esta situación, creo que la diferencia entre usar índices o no es insignificante ; lo que importa es poner todo en una sola matriz de vértices (más una matriz de índice opcional), para que pueda hacer una sola llamada gl.
ToolmakerSteve
0

La gran ganancia en el escritorio es mover los datos a GL_STATIC_DRAW VBO. Presumiblemente, esto también es cierto en la GPU MBX de iPhone.

Será
fuente
-2

Usar GL_TRIANGLE_FANpara un quad usa 4 vértices, no 6.

Señor bla
fuente
Sí, pero también lo hace GL_TRIANGLE_STRIP, como ya han señalado otras respuestas.
Anko
@Señor. Bla: se ha perdido el punto de la pregunta, que es cómo hacer un montón de quads de manera eficiente . No se debe hacer una llamada gl para cada quad, sino combinar muchos quads en una sola matriz, que se puede dibujar con una sola llamada gl. GL_TRIANGLE_FAN no ayudará con esto, por lo tanto, rara vez es útil en la representación de alto rendimiento.
ToolmakerSteve