¿Qué son los objetos Vertex Array?


Estoy empezando a aprender OpenGL hoy de este tutorial: http://openglbook.com/the-book /
Llegué al capítulo 2, donde dibujo un triángulo, y entiendo todo excepto VAOs (¿está bien este acrónimo?). El tutorial tiene este código:

glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);

Aunque entiendo que el código es necesario, no tengo ni idea de lo que hace. Aunque nunca uso VaoId pasado este punto (excepto para destruirlo), el código no funciona sin él. Estoy asumiendo que esto es porque se requiere para estar atado, pero no se por qué. ¿Este código exacto solo necesita ser parte de cada programa OpenGL? El tutorial explica VAOs como:

Un objeto de matriz de Vértices (o VAO) es un objeto que describe cómo se almacenan los atributos de vértices en un objeto de Búfer de Vértices (o VBO). Esto significa que el VAO no es el objeto real que almacena los datos del vértice, sino el descriptor de los datos del vértice. Los atributos de vértices pueden ser descritos por la función glVertexAttribPointer y sus dos funciones hermanas glVertexAttribIPointer y glVertexAttribLPointer, el primero de los cuales exploraremos a continuación.

No entiendo cómo el VAO describe los atributos de vértices. No los he descrito de ninguna manera. ¿Obtiene la información del glVertexAttribPointer? Supongo que debe ser aquí. Es el VAO simplemente un destino para la información de glVertexAttribPointer?

En una nota al margen, ¿es aceptable el tutorial que estoy siguiendo? ¿Hay algo por lo que deba tener cuidado o algo mejor? tutorial a seguir?

Author: Soocks, 2012-08-06

3 answers

"Vertex Array Object" es traído a usted por el Subcomité ARB de OpenGL para Nombres Tontos.

Piense en ello como un objeto de geometría. (Como un viejo programador SGI Performer, los llamo geosets.) Las variables de instancia / miembros del objeto son su puntero de vértice, puntero normal, puntero de color, puntero attrib N,...

Cuando un VAO está enlazado por primera vez, asigna estos miembros llamando a

glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer...;
glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer...;

Y así sucesivamente. Qué atributos están habilitados y los punteros que suministre se almacenan en el VAO.

Después de eso, cuando vuelve a enlazar el VAO, todos esos atributos y punteros también se vuelven actuales. Así que una llamada glBindVertexArray es equivalente a todo el código previamente necesario para configurar todos los atributos. Es útil para pasar geometría entre funciones o métodos sin tener que crear sus propias estructuras u objetos.

(Configuración de una sola vez, uso múltiple es la forma más fácil de usar VAOs, pero también puede cambiar los atributos simplemente vinculándolo y haciendo más enable / pointer llamada. Los VAOs no son constantes.)

Más información en respuesta a las preguntas de Patrick:

El valor predeterminado para un VAO recién creado es que está vacío (AFAIK). No hay geometría en absoluto, ni siquiera vértices, así que si intentas dibujarlo, obtendrás un error de OpenGL. Esto es razonablemente sano, como en "inicializar todo a False / NULL / zero".

Solo necesitas glEnableClientState cuando configures las cosas. El VAO recuerda el estado de enable / disable para cada puntero.

Sí el VAO almacenará glEnableVertexAttribArray y glVertexAttrib. El viejo vértice, normal, color,... los arrays son lo mismo que los arrays de atributos, vertex == #0 y así sucesivamente.

 82
Author: Hugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-10 20:50:02

Los objetos de matriz de vértices son como macros en programas de procesamiento de textos y similares. Una buena descripción se encuentra aquí.

Macros solo recuerda las acciones que hiciste, como activar este atributo, enlazar ese búfer, etc. Cuando llamas a glBindVertexArray( yourVAOId ), simplemente reproduce esos enlaces de puntero de atributos y enlaces de búfer.

Así que su próxima llamada para dibujar utiliza lo que estaba limitado por el VAO.

Los VAO no almacenan datos de vértices. No. El los datos de vértices se almacenan en un vertex buffer o en una matriz de memoria cliente.

 7
Author: bobobobo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-08 18:30:47

VAO es un objeto que representa la etapa de búsqueda de vértices de la canalización OpenGL y se utiliza para suministrar entrada al sombreador de vértices.

Puede crear un objeto de matriz de vértices como este

GLuint vao;
glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);

Primero hagamos un ejemplo simple. Considere este parámetro de entrada en un código de sombreado

layout (location = 0) in vec4 offset; // input vertex attribute

Para completar este atributo podemos usar

glVertexAttrib4fv(0, attrib); // updates the value of input attribute 0

Aunque el objeto vertex array almacena estos valores de atributos estáticos para usted, puede hacer mucho mas.

Después de crear el objeto vertex array podemos empezar a rellenar su estado. Le pediremos a OpenGL que lo rellene automáticamente utilizando los datos almacenados en un objeto buffer que suministramos. Cada atributo de vértice obtiene datos de un búfer enlazado a uno de varios enlaces de búfer de vértice. Para ello utilizamos glVertexArrayAttribBinding(GLuint vao, GLuint attribindex, GLuint bindingindex). También usamos la función glVertexArrayVertexBuffer() para enlazar un búfer a uno de los enlaces de búfer de vértices. Usamos la función glVertexArrayAttribFormat() para describir el diseño y el formato de los datos, y finalmente habilite el llenado automático del atributo llamando a glEnableVertexAttribArray().

Cuando se habilita un atributo de vértice, OpenGL alimentará datos al sombreador de vértices en función del formato y la información de ubicación que haya proporcionado glVertexArrayVertexBuffer() y glVertexArrayAttribFormat(). Cuando el atributo está desactivado, el sombreador de vértices se proporcionará con la información estática que proporcione con una llamada a glVertexAttrib*().

// First, bind a vertex buffer to the VAO
glVertexArrayVertexBuffer(vao, 0, buffer, 0, sizeof(vmath::vec4));

// Now, describe the data to OpenGL, tell it where it is, and turn on automatic
// vertex fetching for the specified attribute
glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0);

glEnableVertexArrayAttrib(vao, 0);

Y código en un sombreador

layout (location = 0) in vec4 position;

Después de todo, debe llamar a glDeleteVertexArrays(1, &vao).


Puedes leer OpenGL SuperBible para entenderlo mejor.

 5
Author: Yola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 08:17:18