opengl
Utilizando VAOs
Buscar..
Introducción
El objeto de matriz Vertex almacena cómo opengl debe interpretar un conjunto de VBO.
En esencia, le permitirá evitar llamar a glVertexAttribPointer cada vez que quiera renderizar una nueva malla.
Si no quiere lidiar con VAOs, simplemente puede crear uno y vincularlo durante la inicialización del programa y pretender que no existen.
Sintaxis
void glEnableVertexAttribArray (GLuint attribIndex);
void glDisableVertexAttribArray (GLuint attribIndex);
void glVertexAttribPointer (GLuint attribIndex, tamaño de GLint, tipo GLenum, GLboolean normalizado, zancada GLsizei, const GLvoid * puntero);
void glVertexAttribFormat (GLuint attribIndex, tamaño de GLint, tipo GLenum, GLboolean normalizado, relativo relativo GLuint);
void glVertexAttribBinding (GLuint attribIndex, GLuint bindingIndex);
void glBindVertexBuffer (GLuint bindingIndex, GLuint buffer, GLintptr offset, GLintptr stride);
Parámetros
parámetro | Detalles |
---|---|
attribIndex | la ubicación del atributo de vértice a la que la matriz de vértices alimentará datos |
tamaño | El número de componentes que se extraerán del atributo. |
tipo | El tipo C ++ de los datos de atributo en el búfer |
normalizado | si se deben asignar tipos de enteros al rango de punto flotante [0, 1] (para sin signo) o [-1, 1] (para firmado) |
puntero | el byte se desplaza en el búfer al primer byte de los datos del atributo (conversión a void* por razones heredadas) |
compensar | el desplazamiento de bytes base desde el principio del búfer hasta donde comienzan los datos de la matriz |
relativoOffset | el desplazamiento a un atributo particular, relativo al desplazamiento base para el búfer |
paso | el número de bytes de los datos de un vértice al siguiente |
buffer | el objeto de búfer donde se almacenan las matrices de vértices |
bindingIndex | el índice al que se enlazará el objeto de búfer de origen |
Observaciones
El formato de atributo separado VAO setup puede interoperar con glVertexAttribPointer
(este último se define en términos del primero). Pero debes tener cuidado al hacerlo.
La versión de formato de atributo separada tiene equivalentes de acceso directo de estado (DSA) en 4.5. Estos tendrán los mismos parámetros, pero en lugar de usar el VAO vinculado, el VAO que se está modificando se pasa explícitamente. Cuando se utiliza DSA de index buffer para glDrawElements
se puede configurar con glVertexArrayElementBuffer(vao, ebo);
Versión 3.0
Cada atributo está asociado con un recuento de componentes, tipo, normalizado, desplazamiento, zancada y VBO. El VBO no se pasa explícitamente como un parámetro, sino que es el búfer vinculado a GL_ARRAY_BUFFER en el momento de la llamada.
void prepareMeshForRender(Mesh mesh){
glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
glVertexAttribPointer (posAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, pos));//will associate mesh.vbo with the posAttrLoc
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribPointer (normalAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, normal));
glEnableVertexAttribArray(normalAttrLoc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); //this binding is also saved.
glBindVertexArray(0);
}
void drawMesh(Mesh[] meshes){
foreach(mesh in meshes){
glBindVertexArray(mesh.vao);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
}
}
Versión 4.3
OpenGL 4.3 (o ARB_separate_attrib_format) agrega una forma alternativa de especificar los datos de vértice, que crea una separación entre el formato de los datos enlazados para un atributo y el origen del objeto del búfer que proporciona los datos. Entonces, en lugar de tener un VAO por malla, puede tener un formato VAO por vértice.
Cada atributo está asociado con un formato de vértice y un punto de enlace. El formato de vértice consiste en el tipo, el recuento de componentes, si está normalizado y el desplazamiento relativo desde el inicio de los datos a ese vértice en particular. El punto de enlace especifica de qué búfer un atributo toma sus datos. Al separar los dos, puede vincular buffers sin volver a especificar ningún formato de vértice. También puede cambiar el búfer que proporciona datos a múltiples atributos con una sola llamada de enlace.
//accessible constant declarations
constexpr int vertexBindingPoint = 0;
constexpr int texBindingPoint = 1;// free to choose, must be less than the GL_MAX_VERTEX_ATTRIB_BINDINGS limit
//during initialization
glBindVertexArray(vao);
glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
glVertexAttribBinding(posAttrLoc, vertexBindingPoint);
// which buffer binding point it is attached to
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribFormat(normalAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, normal));
glVertexAttribBinding(normalAttrLoc, vertexBindingPoint);
glEnableVertexAttribArray(normalAttrLoc);
glVertexAttribFormat(texAttrLoc, 2, GL_FLOAT, false, offsetof(Texture, tex));
glVertexAttribBinding(texAttrLoc, texBindingPoint);
glEnableVertexAttribArray(texAttrLoc);
Luego, durante el sorteo, mantendrá el vao enlazado y solo cambiará los enlaces del búfer.
void drawMesh(Mesh[] mesh){
glBindVertexArray(vao);
foreach(mesh in meshes){
glBindVertexBuffer(vertexBindingPoint, mesh.vbo, mesh.vboOffset, sizeof(Vertex));
glBindVertexBuffer(texBindingPoint, mesh.texVbo, mesh.texVboOffset, sizeof(Texture));
// bind the buffers to the binding point
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
//draw
}
}