2011-01-17 7 views
21

¿Cuál es la mejor manera? ¿Si uso drawarrays, o si uso drawelements? ¿Alguna diferencia?Android glblrawArrays OpenGL ES o GlDrawElements?

+0

La respuesta aceptada está desactualizada. Siguiendo el enlace del documento en la respuesta de Jorn Horstmann, Apple describe ** cómo usar el truco de "triángulos degenerados" con DrawElements **, obteniendo así lo mejor de ambos mundos. El ahorro menor de unos pocos índices al usar DrawArrays no compensa los ahorros que obtiene al combinar *** todos *** sus datos en una sola llamada GL, DrawElements. (Podría combinar todo usando DrawArrays, pero luego cualquier "elemento desperdiciado" estaría desperdiciando vértices, que son mucho más grandes que los índices, y requieren más tiempo de renderizado también). MEJOR: Una sola llamada DrawElements con GL_TRIANGLE_STRIP. – ToolmakerSteve

Respuesta

31

Para ambos, pasa OpenGL algunos búferes que contienen datos de vértice.

glDrawArrays es básicamente "dibujar este rango contiguo de vértices, utilizando los datos que te di antes". bueno:

  • No es necesario construir un búfer de índice

malo:

  • Si organiza los datos en GL_TRIANGLES, tendrá los datos de vértice duplicado para los triángulos adyacentes . Esto es obviamente un desperdicio.
  • Si usa GL_TRIANGLE_STRIP y GL_TRIANGLE_FAN para intentar evitar la duplicación de datos: no es demasiado eficaz y tendría que realizar una llamada de representación por cada tira y abanico. Las llamadas OpenGL son caras y deben evitarse siempre que sea posible

Con glDrawElements, debe pasar el búfer que contiene los índices de los vértices que desea dibujar.

Buena

  • Sin datos vértice duplicado - que acaba de indexar los mismos datos para diferentes triángulos
  • Usted sólo puede usar GL_TRIANGLES y se basan en la memoria caché de vértice para evitar el procesamiento de los mismos datos dos veces - no hay necesidad de re-organizar los datos de la geometría o dividir la representación a través de múltiples llamadas

Bad

  • Sobrecarga de la memoria de búfer de índice

Mi recomendación es usar glDrawElements

+0

No estoy seguro de lo bueno que sería para algo con toneladas de vértices estáticos, como el terreno, la sobrecarga de los índices parece demasiado grande. El beneficio de los elementos de rango de vuelo parece ideal para el terreno, aunque en términos de flexibilidad de renderizado, y parece que superaría cualquier inconveniente. Solo un pensamiento. – scape

+0

@scape - En mi humilde opinión, incluso si los vértices son estáticos, porque un índice es mucho más pequeño que los datos de los vértices en sí, no es un gran problema enviar todos los índices. Yo digo que se adhieren a DrawElements por la flexibilidad. (O con vbos, haga el equivalente incluyendo un buffer de índice). – ToolmakerSteve

+0

@ryanm - FWIW, si alguien tiene una razón para usar DrawArrays, existe un truco ampliamente descripto para combinar tiras con el fin de enviarlas todas en una sola llamada: duplicar el último vértice de una tira y el primer vértice de la siguiente tira. El resultado es dos triángulos degenerados, que tienen área cero. Solo menciono esto, para detener la información errónea de que DrawArrays es inevitablemente ineficiente. Pero personalmente es demasiado doloroso para obtener una ganancia mínima, en comparación con tener índices ... * ACTUALIZACIÓN * Acabo de ver que Jorn Horstmann menciona esto en su respuesta. – ToolmakerSteve

6

Las implicaciones de rendimiento son probablemente similares en el iPhone, el OpenGL ES Programming Guide for iOS recomienda el uso de tiras de triángulos y unirse a través de múltiples tiras triángulos degenerados.

El enlace tiene una bonita ilustración del concepto. De esta forma, podría reutilizar algunos vértices y seguir haciendo todo el dibujo en un solo paso.

Para un mejor rendimiento, sus modelos deben enviarse como una única tira de triángulo sin indexar utilizando glDrawArrays con el menor número posible de vértices duplicados. Si sus modelos requieren muchos vértices para duplicarse (debido a que muchos vértices son compartidos por triángulos que no aparecen secuencialmente en la franja triangular o porque su aplicación fusionó muchas tiras triangulares más pequeñas), puede obtener un mejor rendimiento usando un buffer de índice separado y llamando a glDrawElements en lugar. Existe una compensación: una tira de triángulo no indexado debe duplicar periódicamente vértices enteros, mientras que una lista de triángulos indexados requiere memoria adicional para los índices y agrega sobrecarga para buscar vértices. Para obtener los mejores resultados, pruebe sus modelos utilizando bandas triangulares indexadas y sin indexar, y use la que sea más rápida.

Siempre que sea posible, ordene los datos de vértice e índice para que los triángulos que comparten vértices comunes se dibujen razonablemente cerca uno del otro en la franja triangular. El hardware de gráficos a menudo guarda en caché los cálculos de vértices recientes, por lo que la ubicación de referencia puede permitir que el hardware evite calcular un vértice varias veces.

Lo malo es que probablemente necesite un paso de preproceso que ordene su malla para obtener las tiras lo suficientemente largas. No he podido encontrar un buen algoritmo para esto todavía, así que no puedo dar ningún rendimiento o números de espacio en comparación con GL_TRIANGLES. Por supuesto, esto también depende mucho de las mallas que quieras dibujar.

+0

NOTA: La versión actual de ese documento ya no menciona DrawArrays. En su lugar, muestran DrawElements y usan el triángulo degenerado truco con eso. Esto ofrece lo mejor de ambos enfoques: puede manejar modelos arbitrarios (con una ligera sobrecarga, pero la sobrecarga es de índices adicionales, no de datos de vértices adicionales, por lo que es menor), y obtiene la optimización de minimizar los datos cuando los triángulos están en franjas. – ToolmakerSteve

1

En realidad, puede degenerar la franja triangular para crear franjas continuas para que no tenga que dividirla mientras usa glDrawArray.

He estado usando glDrawElements y GL_TRIANGLES pero pensando en usar glDrawArray en su lugar con GL_TRIANGLE_STRIP. De esta forma no hay necesidad de crear vectores de inidices.

¿Alguien que sabe más sobre el caché de vértices que se mencionó anteriormente en una de las publicaciones? Pensando en el rendimiento entre glDrawElements/GL_TRIANGLE vs glDrawArray/GL_TRIANGLE_STRIP.

+0

Ver el enlace de documento en la respuesta de Jorn Horstmann, y mi comentario al respecto. No intente eliminar el buffer del índice. Utilice la técnica triángulo-tira-más-degeneración-triángulos con DrawElements. El costo adicional de tener un buffer de índice es menor, y esto le permite combinar *** toda *** su geometría en una sola llamada. Sin vértices desperdiciados, que son costosos. No es necesario sopesar el equilibrio entre la geometría bien despojada y los modelos arbitrarios que no forman buenas franjas. – ToolmakerSteve

1

La respuesta aceptada está ligeramente desactualizada. Siguiendo el enlace del documento en la respuesta de Jorn Horstmann, OpenGL ES Programming Guide for iOS, Apple describe cómo usar el truco de "triángulos degenerados" con DrawElements, obteniendo así lo mejor de ambos mundos.

El ahorro menor de unos pocos índices mediante el uso de DrawArrays no compensa los ahorros que obtiene combinando todos sus datos en una sola llamada GL, DrawElements. (Podría combinar todo usando DrawArrays, pero luego cualquier "elemento desperdiciado" estaría desperdiciando vértices, que son mucho más grandes que los índices, y requieren más tiempo de procesamiento también).

Esto también significa que no necesita considerar cuidadosamente todos sus modelos, en cuanto a si la mayoría de ellos se pueden representar como un número mínimo de tiras, o si son demasiado complejas. Una solución uniforme que maneja todo. (Pero tratar de organizar en tiras cuando sea posible, para minimizar enviados los datos, y maximizar la verosimilitud de la GPU de reutilizar los cálculos de vértices recientemente en caché.)

MEJOR: Un solo drawElements llamada con GL_TRIANGLE_STRIP, que contiene todo su datos (eso está cambiando en cada cuadro).

Cuestiones relacionadas