Comprensión de VAO y VBO

Oct 23 2020

Estoy leyendo Learn OpenGL para actualizar los conceptos básicos, ya que no he tocado en bastante tiempo.

Específicamente, sigo pensando que no puedo entender del todo el significado de VAO y VBO, el libro avanza principalmente a través de ejemplos, en realidad no ofrece definiciones rigurosas.

Sobre la VBO:

Con los datos de vértice definidos, nos gustaría enviarlos como entrada al primer proceso de la canalización de gráficos: el sombreador de vértices. Esto se hace creando memoria en la GPU donde almacenamos los datos del vértice, configuramos cómo OpenGL debe interpretar la memoria y especificamos cómo enviar los datos a la tarjeta gráfica. El sombreador de vértices luego procesa tantos vértices como le indicamos de su memoria. Gestionamos esta memoria a través de los llamados objetos de búfer de vértice (VBO) que pueden almacenar una gran cantidad de vértices en la memoria de la GPU. La ventaja de usar esos objetos de búfer es que podemos enviar grandes lotes de datos de una sola vez a la tarjeta gráfica y mantenerlos allí si queda suficiente memoria, sin tener que enviar datos un vértice a la vez. Enviar datos a la tarjeta gráfica desde la CPU es relativamente lento, por lo que siempre que podemos intentamos enviar la mayor cantidad de datos posible a la vez. Una vez que los datos están en la memoria de la tarjeta gráfica, el sombreador de vértices tiene acceso casi instantáneo a los vértices, lo que lo hace extremadamente rápido.

Entonces, mi comprensión de VBO son esencialmente objetos de búfer (un montón de bytes que se enviarán a la GPU) con la diferencia de que los VBO están específicamente dedicados a Vertex Data. ¿Es esto correcto?

Sobre la VAO:

Aquí, en cambio, realmente no entiendo.

Un objeto de matriz de vértice (también conocido como VAO ) se puede vincular como un objeto de búfer de vértice y cualquier llamada de atributo de vértice posterior a partir de ese punto se almacenará dentro de VAO.

¿Qué significa que cualquier llamada de atributo de vértice posterior a partir de ese momento se almacenará dentro del VAO ? No entiendo el bit de "llamada a almacenar", ¿significa que en algún lugar del contexto opengl creado almacenamos como algunos datos relacionados con el llamadas de atributo de vértice (como el par de entrada y salida de la llamada, la salida de la llamada, ¿algo relacionado con la llamada?).

Esto tiene la ventaja de que al configurar punteros de atributo de vértice solo tiene que hacer esas llamadas una vez y siempre que queramos dibujar el objeto, podemos simplemente vincular el VAO correspondiente. Esto hace que cambiar entre diferentes datos de vértice y configuraciones de atributos sea tan fácil como vincular un VAO diferente. Todo el estado que acabamos de establecer se almacena dentro del VAO.

No entiendo la ventaja aquí. Entiendo la "llamada realizada una vez", porque se almacenan en el VAO (sea lo que sea la "parte almacenada" significa). La parte de conmutación quizás signifique que puedo crear múltiples VAO, cada una capturando diferentes llamadas de Atributos de vértice y puedo vincular cada una de estas cuando lo necesite sin volver a llamar al atributo de vértice.

Como referencia, también encontré esta pregunta que pensé que tenía una respuesta interesante.

Respuestas

3 NicolBolas Oct 23 2020 at 01:05

Entonces, mi comprensión de VBO son esencialmente objetos de búfer (un montón de bytes que se enviarán a la GPU) con la diferencia de que los VBO están específicamente dedicados a Vertex Data. ¿Es esto correcto?

Un "VBO" no es realmente una cosa, y realmente me gustaría que los tutoriales dejaran de fingir que lo son.

Tiene razón en que existen objetos de búfer . Se trata de matrices lineales de datos sin formato que la GPU almacena y a los que puede acceder para varios procesos. Uno de esos "varios procesos" para los que la GPU puede usarlos es proporcionar datos de matriz para operaciones de renderizado de vértices.

Pero el búfer en sí no es especial. No se convierte en algo diferente solo porque lo use para datos de vértice, y no hay ninguna regla que diga que un búfer que está usando actualmente para datos de vértice no se puede usar para otros usos de búfer también.

Tenga en cuenta que esto es diferente de cómo funcionan las texturas. Cuando crea un objeto de textura y lo enlaza como una textura 2D, ese objeto de textura se convierte para siempre en una textura 2D. No puede vincularlo más tarde como un 1D o un mapa de cubos o lo que sea. Los objetos de búfer no son así; dónde los vincula define solo cómo los está utilizando actualmente .

¿Qué significa "cualquier llamada de atributo de vértice posterior a partir de ese punto se almacenará dentro del VAO"

Este es otro tropo molesto del tutorial: que los objetos "almacenan llamadas" o son macros u otras tonterías similares.

Los objetos en OpenGL no almacenan llamadas; almacenan el estado . Son como estructuras; tienen miembros de datos. Vincular un objeto al contexto OpenGL permite que las operaciones OpenGL que acceden a cierto estado encuentren ese estado dentro del objeto vinculado. Entonces, si llama a una función que modifica cierto estado que proviene de un objeto vinculado, esa función modificará el estado dentro del objeto.

Cuando vincula un VAO, está vinculando un objeto que almacena el estado utilizado para las matrices de vértices. Cuando llama a una función que modifica el estado de las matrices de vértices, esa función modificará el estado almacenado en el VAO actualmente vinculado. Cuando renderice, el sistema de renderizado utilizará el estado de la matriz de vértices que se encuentra en el VAO enlazado actualmente.

2 ratchetfreak Oct 23 2020 at 19:53

Un VBO es un búfer de memoria al que puede acceder la gpu. Eso es todo.

Un VAO es un objeto que almacena enlaces de vértices. Esto significa que cuando llama a glVertexAttribPointer y amigos para describir su formato de vértice, esa información de formato se almacena en el VAO enlazado actualmente. Y cuando dibuje, usará los enlaces de vértice en el VAO actualmente vinculado.

Pretender que reproduce las llamadas vinculantes es engañoso. Es una reliquia de por qué se crearon los VAO porque antes de los VAO era necesario rehacer los enlaces de vértices cada vez que cambiaba la malla que estaba dibujando. Un VAO le permite hacer eso en una sola llamada.