¿Por qué OpenGL> = 3 solo permite VBO?

21

Veo que OpenGL versiones 3 y posteriores eliminan el uso del renderizado del lado del cliente. El modo inmediato ha sido eliminado, y las matrices de vértices parecen estar en desuso. En cambio, si entiendo correctamente, los VBO son la principal forma de representar vértices.

Si bien veo la lógica detrás de tener una forma uniforme de representar todo, ¿es el caso de que los VBO no tienen inconvenientes importantes sobre las matrices de vértices? Pensé que se suponía que los VBO eran grandes memorias intermedias que contenían> 1 MB de datos, generalmente. ¿Qué pasa si tengo una escena que tiene mucha geometría más pequeña? Tengo un gráfico de escena con una gran cantidad de nodos, cada uno de los cuales necesita su propia transformación, etc. Cada nodo también debería poder eliminarse por separado, agregarse por separado, etc. Estaba usando matrices de vértices antes. Entonces, mi primera pregunta es si, si cambio a VBO, habrá una mayor sobrecarga en mis objetos de gráficos de escena ahora porque es necesario asignar un VBO para cada objeto.

Otra preocupación es que la geometría que estoy renderizando puede ser muy dinámica. En el peor de los casos, puede haber ocasiones en que toda la geometría deba volver a enviarse a cada cuadro durante un período de tiempo. ¿Los VBO tendrán un rendimiento peor que las matrices de vértices en este caso de uso, o las VBO en el peor de los casos funcionarán tanto como las matrices de vértices pero no más?

Entonces, en un formato más conciso, mis preguntas son:

1) ¿Existe una sobrecarga considerable para asignar / desasignar VBO (me refiero al simple acto de configurar un búfer)?

2) Si estoy actualizando los datos de la CPU en cada cuadro, ¿puede esto ser mucho peor que si hubiera usado matrices de vértices?

Y finalmente, me gustaría saber:

3) Si la respuesta a cualquiera de las preguntas anteriores es "sí", ¿por qué despreciar otros modos de representación que podrían tener ventajas sobre los VBO? ¿Hay algo que me falta aquí, como las técnicas que se supone que debo usar para mitigar algunos de estos posibles costos de asignación, etc.?

4) ¿Las respuestas a alguna de estas preguntas cambian sustancialmente dependiendo de qué versión de OpenGL estoy usando? Si refactorizo ​​mi código para que sea compatible con OpenGL 3 o 4 utilizando VBO de una manera que sea eficiente, ¿será probable que las mismas técnicas funcionen bien con OpenGL 2, o es probable que ciertas técnicas sean mucho más rápidas con OpenGL 3? + y otros con OpenGL 2?

Hice esta pregunta sobre el desbordamiento de la pila, pero estoy volviendo a publicar aquí porque me di cuenta de que este sitio puede ser más apropiado para mi pregunta.

Gravedad
fuente
1
¿Por qué un voto para cerrar? ¿Es un dup? Si es así, ¿puedo ver un enlace para poder beneficiarme de él?
Gravity

Respuestas:

23

¿Existe una sobrecarga considerable para asignar / desasignar VBO (me refiero al simple acto de configurar un búfer)?

Definir "sustancial". En general, es aconsejable no crearlos en el medio de los marcos; deben configurarse durante la inicialización o donde sea. Pero esto es cierto para la mayoría de los objetos OpenGL, como texturas, renderbuffers o sombreadores.

Si estoy actualizando los datos de la CPU en cada cuadro, ¿puede esto ser mucho peor que si hubiera usado matrices de vértices?

¿Puede? Sí. OpenGL define la funcionalidad, no el rendimiento . De hecho, puedes hacer las cosas mucho más lentas. O puedes hacer las cosas más rápido. Todo depende de cómo lo uses.

OpenGL Wiki tiene un buen artículo sobre cómo transmitir datos correctamente .

Si la respuesta a cualquiera de las preguntas anteriores es "sí", ¿por qué despreciar otros modos de representación que podrían tener ventajas sobre los VBO? ¿Hay algo que me falta aquí, como las técnicas que se supone que debo usar para mitigar algunos de estos posibles costos de asignación, etc.?

Primero, no solo estaban en desuso. La desaprobación significa marcar algo como "para ser eliminado" en futuras versiones. Se desaprobaron en 3.0 y se eliminaron en 3.1 core y superiores.

En segundo lugar, el ARB generalmente ha explicado la razón por la que eliminaron cosas de OpenGL. Hace que la especificación sea más pequeña y simple. Hace que la API sea más pequeña y más racionalizada. Hace que sea más fácil saber qué API debe utilizar; 2.1 tenía 4 formas de proporcionar datos de vértice; 3.1+ tiene 1. Se deshace de una gran cantidad de cruft. Etc.

¿Las respuestas a alguna de estas preguntas cambian sustancialmente según la versión de OpenGL que esté usando? Si refactorizo ​​mi código para que sea compatible con OpenGL 3 o 4 utilizando VBO de una manera que sea eficiente, ¿será probable que las mismas técnicas funcionen bien con OpenGL 2, o es probable que ciertas técnicas sean mucho más rápidas con OpenGL 3? + y otros con OpenGL 2?

Más o menos no. Solo en MacOSX la diferencia entre las versiones 3.1 + core y pre-3.0 es realmente aparente. Todos los controladores para Linux y Windows implementan el perfil de compatibilidad, por lo que puede suponer que el perfil principal de estos controladores en realidad solo agrega comprobaciones para evitar que llame a funciones de compatibilidad.

Bajo Mac OSX 10.7, el núcleo GL 3.2 está disponible, pero no el perfil de compatibilidad. Eso no significa necesariamente nada para las técnicas de rendimiento en uno frente al otro. Pero sí significa que si hay diferencias, esa es la plataforma en la que las verá.

Nicol Bolas
fuente
1
Como acabas de publicar esta pregunta , solo publicaré mi respuesta.
Nicol Bolas
Otra ventaja de mantener la API concisa es que hace que la API de OpenGL sea más fácil de implementar. Esta fue una gran consideración en la especificación original de OpenGL ES.
notlesh 01 de
@stephelton: tiene sentido. Mi pregunta de "por qué despreciar todo menos las VBO" se basó en el pensamiento de que, si bien tiene mucho sentido mantener la inclinación de la API, no tiene sentido despreciar las características que podrían ser mejores que las VBO para muchos casos de uso. Sin embargo, por lo que escucho, parece que no hay desventajas al usar VBO, por lo que tiene mucho sentido desaprobar todo lo demás.
Gravity
@gravity No tienes que usar VBO's. También puedes usar una variedad de vértices.
notlesh
18

La forma en que funciona OpenGL, siempre que use datos que no sean VBO, el controlador debe hacer una copia de ellos, en la práctica, creando un VBO temporal, ya que nada le impide modificar sus matrices desnudas en el espacio de usuario entre llamadas a OpenGL.

Puede haber algunos trucos del lado del conductor para acelerar la asignación temporal, pero no hay nada que pueda hacer para evitar la copia.

Así que sí, siempre y cuando usted y los desarrolladores de controladores hagan todo bien, los VBO deberían (tm) siempre acelerar las cosas.

Jari Komppa
fuente
66
Me gusta más esta respuesta. Es más corto y más directo al grano, imo.
TravisG
@JariKomppa: Eso suena como una explicación muy razonable. Todavía tengo una preocupación: se supone que los VBO son objetos razonablemente grandes, a menudo asignados como buffers de 1MB a 4MB la última vez que lo verifiqué. ¿Qué pasa si mis objetos de geometría no son tan grandes, pero todavía estoy preocupado por el rendimiento porque tengo muchos objetos? Me preocupa que los VBO puedan ser para un caso de uso diferente al que tengo. ¿Debería agrupar varios objetos en un solo VBO y luego usarlos glDrawRangeElementspara dibujar cada objeto individual, o es ineficiente al igual que las matrices de vértices?
Gravity
Dudo que eso haga alguna diferencia, pero si crees que es una preocupación, compárala.
Jari Komppa
@JariKomppa: ¿Qué dudas que hará la diferencia? ¿Usa glDrawRangeElementsvarias veces en cada VBO con unos pocos VBO en lugar de darle a cada objeto su propio VBO?
Gravity
1
Exactamente. Dudo que vea mucha diferencia allí, pero el perfil de algunos casos de prueba debería darle más información. Tampoco me preocuparía ahora, ya que un cambio como ese podría aplicarse más adelante si fuera necesario.
Jari Komppa
9

y las matrices de vértices parecen estar en desuso. En cambio, si entiendo correctamente,

No exactamente. Las matrices de vértices son la base de los objetos de búfer de vértices. Solo el almacenamiento se movió del lado del cliente al servidor.

¿Qué pasa si tengo una escena que tiene mucha geometría más pequeña?

Combina conjuntos de geometría más pequeños en VBO más grandes. No es necesario tener un VBO por lote de geometría. Puede abordar perfectamente subconjuntos de un VBO para renderizar. Utilice un desplazamiento distinto de cero para el parámetro de datos gl ... Puntero.

2) Si estoy actualizando los datos de la CPU en cada cuadro, ¿puede esto ser mucho peor que si hubiera usado matrices de vértices?

Para esto están los indicadores de uso del búfer GL_DYNAMIC_DRAW y GL_STREAM_DRAW.

Si la respuesta a cualquiera de las preguntas anteriores es "sí", ¿por qué despreciar otros modos de representación que podrían tener ventajas sobre los VBO?

Porque no hay ventajas. Los datos de geometría deben transferirse a la GPU en cualquier caso. El uso de una matriz de vértices del lado del cliente normal seguirá causando una transferencia de DMA a la GPU, y el modo inmediato también generará un lote para transferir primero.

No hay absolutamente ningún beneficio en no usar VBO.

datenwolf
fuente
¿Entonces mi rendimiento generalmente no debería ser peor con VBO que con matrices de vértices, pero solo si configuro correctamente el modo en GL_STREAM_DRAW?
Gravedad
@Gravity: de hecho. Sin embargo, el modo de búfer es simplemente una pista sobre el uso esperado, pero, por supuesto, esa pista debe ser fiel a lo que va a hacer. Además, no olvide que puede asignar buffers en el espacio de direcciones de su proceso para actualizaciones (glMapBuffer, glUnmapBuffer).
datenwolf
pero entonces el búfer no podía estar en VRAM, ¿verdad? ¿O todavía estaría en VRAM pero solo direccionable a través de direcciones de espacio de proceso? ¿El acceso aleatorio sería barato con esta técnica, o debería tratar de actualizar solo un pequeño número de rangos contiguos?
Gravity
@ Gravedad: un búfer puede asignarse solo lectura, solo escritura o lectura escritura. Para las actualizaciones elegirías escribir solo. Ahora es importante saber cómo los SO modernos administran el espacio de direcciones virtuales, es decir, a través de la memoria paginada. En el caso de un mapa de solo escritura, se le asigna una parte de la memoria de transferencia de DMA y sus escrituras en ese rango asignado irán a la memoria de la GPU más o menos directamente (los contenidos se escriben primero en la RAM de la CPU, pero luego se transfieren a la GPU por DMA transferir). Es importante que esta sea una ruta más directa que si los datos pasan por una matriz de vértices del lado del cliente: la memoria de proceso normal no es adecuada para DMA
datenwolf