2011-09-24 15 views
17

¿Qué es preferible, desde un punto de vista effiency (u otro punto de vista si es importante)?OpenGL es mejor dibujar por lotes o tener VBO estáticas

Situación aplicación
Un OpenGL que atrae a muchas líneas en diferentes posiciones cada cuadro (60 fps). Digamos que hay 10 líneas. O 100 000 líneas. ¿La respuesta sería diferente?

  • # 1 Tener un VBO estática que nunca cambia, que contiene 2 vértices de una línea

Cada cuadro tendría uno glDrawArrays llaman por línea para dibujar, y entre no habría transformaciones de matriz posicionar nuestra una línea

  • # 2 actualización de la VBO con los datos para todas las líneas de cada cuadro

Cada cuadro tendría una sola llamada sorteo

Respuesta

27

La segunda es increíblemente más eficiente.

Los estados cambiantes, particularmente la transformación y las matrices, tienden a provocar el recálculo de otros estados y, en general, más matemáticas.

La actualización de la geometría, sin embargo, simplemente implica sobrescribir un búfer.

Con hardware de video moderno en buses de ancho de banda bastante masivo, enviar algunas carrozas es trivial. Están diseñados para mover toneladas de datos rápidamente, es un efecto secundario del trabajo. La actualización de los buffers de los vértices es exactamente lo que hacen a menudo y rápido. Si asumimos puntos de 32 bytes cada uno (posición float4 y color), 100000 segmentos de línea son menos de 6 MB y creo que PCIe 2.0 x16 es de aproximadamente 8 GB/s.

En algunos casos, dependiendo de cómo el controlador o la tarjeta manejan las transformaciones, cambiar uno puede causar cierta multiplicación de matrices y volver a calcular otros valores, incluyendo transformaciones, eliminación y recorte de planos, etc. Esto no es un problema si cambia el estado, dibuje unos miles de polys, y repita, pero cuando los cambios de estado son a menudo, tendrán un costo significativo.

Un buen ejemplo de esto se resuelve previamente es el concepto de procesamiento por lotes, lo que minimiza los cambios de estado para que se pueda extraer más geometría entre ellos. Esto se usa para dibujar de manera más eficiente grandes cantidades de geometría.

Como un ejemplo muy claro, considere el mejor caso para # 1: el conjunto de transformadores desencadena ningún cálculo adicional y el controlador almacena con celo y perfectamente.Para dibujar 100000 líneas, necesita:

  • 100000 conjuntos de matriz (en la RAM del sistema) las llamadas set
  • 100000 matriz con una sobrecarga de llamada de función (a controlador de vídeo, la copia de la matriz a la memoria intermedia allí)
  • 100000 matrices de copia en la RAM de vídeo, realizadas en una sola masa
  • 100000 sorteo línea llama

La llamada sobrecarga de la función solo se va a matar rendimiento.

Por otra parte, de dosificación implica:

  • 100000 cálculos de punto y se pone, en la memoria RAM del sistema
  • 1 copia vbo a la RAM de vídeo. Esto será una gran parte, pero un solo bloque contiguo y ambos lados saben qué esperar. Se puede manejar bien
  • 1 matriz de llamada conjunto
  • 1 copia de la matriz a la RAM de vídeo
  • 1 llamada sorteo

Haces copiar más datos, pero hay una buena probabilidad de los contenidos VBO todavía no son tan caros como la copia los datos de la matriz. Además, ahorrará una gran cantidad de tiempo de CPU en llamadas a funciones (de 200000 a 2). Esto simplifica la vida para usted, el controlador (que tiene que almacenar todo y verificar llamadas redundantes y optimizar y manejar la descarga) y probablemente también la tarjeta de video (que puede haber tenido que volver a calcular). Para que sea realmente claro, visualizar código simple para ello:

1:

for (i = 0; i < 100000; ++i) 
{ 
    matrix = calcMatrix(i); 
    setMatrix(matrix); 
    drawLines(1, vbo); 
} 

(ahora desenvolver eso)

2:

matrix = calcMatrix(); 
setMatrix(matrix); 
for (i = 0; i < 100000; ++i) 
{ 
    localVBO[i] = point[i]; 
} 
setVBO(localVBO); 
drawLines(100000, vbo); 
+3

Ok, ¿eso quiere decir que sea siempre es mejor cocer en una VBO y luego dibujar, en lugar de usar matrices para transformar? ¿Qué pasa si tengo un puñado, tal vez 10, moviendo cuadros con textura? ¿Sería realmente mejor calcular las coordenadas de los objetos, recrear el VBO, cargar y dibujar? A diferencia de usar una traducción de matriz (que optimizo para ser simplemente 2 adiciones en lugar de 64 multiplicaciones y 48 adiciones) en cada objeto y luego dibujar para cada uno. – mk12

+1

"Si asumimos puntos de 32 bytes cada uno (posición float4 y color)" Y no tomaría prácticamente ningún esfuerzo cortar eso a la mitad: vec3 de posición y un vec4 de colores de bytes sin signo. Además, debe investigar [la transmisión de objetos del búfer] (http://www.opengl.org/wiki/Buffer_Object_Streaming) para mejorar el rendimiento de esto. –

+1

@ Mk12 Has hecho una pregunta mucho más complicada. La respuesta de su pregunta fue simple porque cada objeto era muy pequeño e incluso cuando tenía muchos de ellos, los datos de los vértices eran pequeños. Una vez que tiene un mayor número de objetos, el costo de calcular sus posiciones se vuelve mucho más significativo, al igual que los costos de carga. –

Cuestiones relacionadas