2009-01-28 13 views
11

Esto es algo que he estado buscando mientras, pero todavía tengo que encontrar información concreta o buenos ejemplos. Tengo, por ejemplo, un grupo de objetos no conectados (triángulos, por ejemplo). ¿Cuál es la forma eficiente de renderizar estos?OpenGL: ¿forma eficiente de renderizar un lote de geometría?

He oído sobre poner varios objetos en un VBO para reducir las llamadas de OpenGL, pero no he visto un ejemplo adecuado de cómo hacerlo. También he visto publicaciones que contradicen esta idea. Así que ahora mismo, estoy confundido.

+0

Acabo de implementar un método descrito en http://craiggiles.wordpress.com/2009/08/03/opengl-es-batch-rendering-on-the-iphone/ y funciona bien. – RandomEtc

Respuesta

15

En primer lugar, probablemente debería utilizar VBO todo el tiempo. Para objetos pequeños y grandes.

Luego, el segundo problema es "¿cómo combinar varios objetos separados en un objeto grande?" - para reducir el número de llamadas OpenGL que deben realizarse. Generalmente, los objetos que usan la misma textura (s), configuraciones de materiales y sombreadores se pueden combinar. P.ej. Si tiene toneladas de cajas idénticas por ahí, podría tener sentido combinarlas en varias "cajas de cajas" más grandes.

Si un objeto es una lista triangular, entonces la combinación es fácil; solo crea una lista triangular grande fuera de las listas fuente. Si un objeto es una tira de triángulo, entonces tienes que usar "triángulos degenerados" para unir las tiras (esta es una optimización muy útil para un solo objeto también, si no se puede representar como una sola tira).

Un "triángulo degenerado" es un triángulo que tiene dos o tres índices de vértices idénticos. El hardware de gráficos puede reconocerlos y omitirlos muy rápido.

Así que si tiene, por ejemplo, dos tiras con un triángulo cada una, para un total de seis vértices.

Los índices triángulo original de las bandas serían:

1) 0, 1, 2 
2) 0, 1, 2 

Ahora se unen a todos los vértices juntos, por lo que terminan con 6 vértices.

1) 0, 1, 2 (unchanged) 
2) 3, 4, 5 

Ahora tiene una matriz de vértices, pero todavía dos tiras separadas. Tiene que unirse a ellos mediante la inserción de triángulos degenerados:

1) 0, 1, 2, 2, 2, 3, 4, 5 

(Creo que lo anterior es correcto, pero en realidad no han verificado)

La idea es la siguiente: con la tira anterior, la tarjeta gráfica sería dibujar triángulos de estos vértices:

0, 1, 2 
1, 2, 2 <- degenerate! won't be drawn 
2, 2, 2 <- degenerate! won't be drawn 
2, 2, 3 <- degenerate! won't be drawn 
3, 4, 5 

en caso general, ya sea que usted tiene que insertar dos o tres triángulos degenerados basados ​​en la longitud de la banda original, por lo sinuoso que el triángulo sigue siendo correcta.

+0

¿Por qué no puede simplemente compilar una lista de visualización que usa GL_TRIANGLE_STRIP? – aib

+1

@aib: porque nunca se puede estar seguro de * qué * compilar una lista de visualización. Las listas de presentación están en desuso en OpenGL 3.0 y no existen en la mayoría de las demás plataformas (D3D, OpenGL ES, API de la consola, ...). Simplemente no se asignan bien al hardware. – NeARAZ

+1

¿No debería ser 0 1 2 [2 2 3] 3 4 5? Dibujado como 0 1 2, [2 1 2, 2 2 2, 2 2 3, 3 2 3, 3 3 4,] 3 4 5? – eplawless

1

Mire en glDrawElements(), es una buena manera de lograr lo que quiere. Tenga en cuenta que el rendimiento puede disminuir si sus datos cambian cada fotograma, ya que luego debe actualizar las partes relevantes de los datos, lo que significa copiarlos en la memoria de la tarjeta gráfica. Para datos estáticos, esto es muy rápido.

+0

o incluso mejor; puede usar glMultiDrawIndirect() ahora :) – MattMatt

Cuestiones relacionadas