¿Qué es un objeto de matriz de vértices en OpenGL?

Un objeto de matriz de vértices (VAO) es un objeto OpenGL. Sin embargo, a diferencia de un Buffer Objects que contiene almacenamiento, un VAO no lo hace. En cambio, un VAO es un contenedor para objetos Vertex Buffer (VBO).

¿Por qué usar un VAO?
Supongamos que necesita representar 12 caracteres diferentes, cada uno con su propio tipo de datos, desplazamiento, etc. Toda esta información debe prepararse antes de que se represente. Estos son muchos estados para configurar y muchos errores de comprobación que el controlador tendrá que hacer.

Aquí es donde un VAO puede ayudar a organizar toda esta información. Un VAO es un contenedor que almacena todos los estados necesarios para la representación. Almacena la información de vértice-atributo, así como el objeto de búfer.

Ahora, si recuerda, antes de que se pueda usar un Objeto OpenGL, primero debe crearse y vincularse. Por lo tanto, antes de poder usar un VAO, debe crearlo y vincularlo al contexto OpenGL.

Usar un objeto de matriz de vértices es bastante simple. Creamos y vinculamos un VAO antes de la creación de un búfer OpenGL.

Aquí he resumido los 11 pasos necesarios para renderizar en OpenGL:

  1. Generar un VAO ( glGenVertexArrays ): Informa a OpenGL para crear un VAO.
  2. Vincula el VAO ( glBindVertexArray ): Informa a OpenGL para vincular un VAO.
  3. Generar un VBO ( glGenBuffers () ): Informa a OpenGL para crear un Buffer.
  4. Vincula el VBO ( glBindBuffer () ): Informa a OpenGL para usar este búfer para operaciones posteriores.
  5. Datos del búfer ( glBufferData () o glBufferSubData () ): Informa a OpenGL para asignar e inicializar suficiente memoria para el búfer actualmente vinculado.
  6. Obtener ubicación de atributos ( glGetAttribLocation () ): obtiene la ubicación de los atributos en el sombreador activo actual.
  7. Obtener la ubicación del uniforme ( glGetUniformLocation () ): obtener la ubicación de los uniformes en el sombreador activo correcto.
  8. Enable ( glEnableVertexAttribArray () ): habilita las ubicaciones de atributos que se encuentran en el sombreador.
  9. Establecer punteros ( glVertexAttribPointer () ): Informa a OpenGL sobre los tipos de datos en buffers vinculados y cualquier compensación de memoria necesaria para acceder a los datos.
  10. Draw ( glDrawArrays () o glDrawElements () ): Informa a OpenGL para representar una escena utilizando datos en buffers actualmente vinculados y habilitados.
  11. Eliminar ( glDeleteBuffers () ): dígale a OpenGL que elimine los búferes generados previamente y los recursos asociados gratuitos.

La preparación de un búfer con un VAO se realiza simplemente como se muestra arriba. Antes de crear un VBO, creamos y vinculamos un VAO (pasos 1-2).

El objeto de matriz de vértices puede representarse como un objeto que almacena punteros a enlaces de matriz de vértices que apuntan a variables específicas del objeto, por ejemplo, puntero de color, puntero de vértice, puntero de atributo N, etc.

Para decirlo de manera simple, un VAO es una matriz de punteros que apuntan a otros búferes que contienen atributos de vértice. Me gusta:

glGenBuffers (1, y Elmbuff);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, Elmbuff);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (sin signo corto) * vicount * 2, VINDEX, GL_STATIC_DRAW);
glGenBuffers (1, y Vertexbuff);
glBindBuffer (GL_ARRAY_BUFFER, Vertexbuff);
glBufferData (GL_ARRAY_BUFFER, sizeof (Vertex) * j, VERTEX, GL_STATIC_DRAW);

glGenBuffers (1, y Tngbuff);
glBindBuffer (GL_ARRAY_BUFFER, Tngbuff);
glBufferData (GL_ARRAY_BUFFER, sizeof (Vec3f) * j, TNG, GL_STATIC_DRAW);

Luego, cuando dibujas, usas:

glBindBuffer (GL_ARRAY_BUFFER, Vertexbuff);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), 0);
glEnableVertexAttribArray (0);
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (Vertex), (void *) sizeof (Vec3f));
glEnableVertexAttribArray (1);
glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), (void *) (sizeof (Vec3f) + sizeof (Vec2f)));
glEnableVertexAttribArray (2);
glBindBuffer (GL_ARRAY_BUFFER, tbuff ());
glVertexAttribPointer (3, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray (3);

glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, elmbuff ());
glDrawElements (GL_TRIANGLES_ADJACENCY, vcount (), GL_UNSIGNED_SHORT, 0);

Por supuesto, esto no es un programa completo, necesita cargar modelos, texturas y también escribir y cargar sombreadores, pero así es como usa VAO: s.