primero, apagado VAO solo "recuerda" los últimos enlaces de atributo de vértice (y el enlace de VBO para un buffer de índice (GL_ELEMENT_ARRAY_BUFFER_BINDING
), si hay alguno). Por lo tanto, no se acuerda de las compensaciones en glDrawElements()
, es necesario llamar más tarde que cuando se utiliza el VAO. El laso no le impide usar arreglos de vértices intercalados. Voy a tratar de explicar:
int vbo[3];
glGenBuffers(3, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, data0, size0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, data1, size1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data2, size2);
// create some buffers and fill them with data
int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// create a VAO
{
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // not saved in VAO
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(float), NULL); // this is VAO saved state
glEnableVertexAttribArray(0); // this is VAO saved state
// sets up one vertex attrib array from vbo[0] (say positions)
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); // not saved in VAO
glVertexAttribPointer(1, 3, GL_FLOAT, false, 5 * sizeof(float), NULL); // this is VAO saved state
glVertexAttribPointer(2, 2, GL_FLOAT, false, 5 * sizeof(float), (const void*)(2 * sizeof(float))); // this is VAO saved state
glEnableVertexAttribArray(1); // this is VAO saved state
glEnableVertexAttribArray(2); // this is VAO saved state
// sets up two more VAAs from vbo[1] (say normals interleaved with texcoords)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]); // this is VAO saved state
// uses the third buffer as the source for indices
}
// set up state that VAO "remembers"
glBindVertexArray(0); // bind different vaos, etc ...
tarde ...
glBindVertexArray(vao); // bind our VAO (so we have VAAs 0, 1 and 2 as well as index buffer)
glDrawElements(GL_TRIANGLE_STRIP, 57, GL_UNSIGNED_INT, NULL);
glDrawElements(GL_TRIANGLE_STRIP, 23, GL_UNSIGNED_INT, (const void*)(57 * sizeof(unsigned int)));
// draws two parts of the mesh as triangle strips
por lo que ver ... puede dibujar vertex arrays intercalados utilizando glDrawElements
utilizando un solo VAO y uno o más OISCIV.
Para responder la segunda parte de su pregunta, puede tener diferentes VAO y VBO para diferentes partes de la malla (por lo que es fácil extraer partes separadas), o puede fusionar todo en un solo par VAO VBO (por lo que necesita no llame glBind*()
a menudo) y el uso de múltiples glDraw*()
llama para dibujar las partes individuales de la malla (como se ve en el código anterior - se imaginan la primera glDrawElements()
señala a la nave y la segunda señala a la torreta, que acaba de actualizar algunos uniforme de la matriz entre las llamadas).
Dado que los sombreadores pueden contener matrices de modelos múltiples en uniformes, también puede codificar mesh id como otro atributo de vértice y dejar que el sombreado de vértices elija qué matriz usar para transformar el vértice en función de este atributo. Esta idea también se puede extender al uso de matrices múltiples por un solo vértice, con algunos pesos asignados para cada matriz. Esto se usa comúnmente cuando se animan objetos orgánicos, como el personaje del jugador (buscar "pelado").
Como van los objetos de búfer uniformes, la única ventaja es que puede empaquetar una gran cantidad de datos en ellos y que se pueden compartir fácilmente entre sombreadores (simplemente vincule el UBO a cualquier sombreador que pueda usarlo). No hay una ventaja real al usarlos para usted, excepto si tuviera objetos con 100 ohmios de matrices.
Además, escribí los códigos fuente arriba de la memoria. Déjame saber si hay algunos errores/problemas ...
fresca Creo Lo consigo con el entrelazado, tengo que probarlo. Pero creo que cometió un error, así que para estar seguro, al definir el primer puntero glVertexAttrib para las posiciones de los vértices, como lo entendí, las posiciones de los vértices están bien empaquetadas en vbo [0] pero ¿le dio un paso? ¿No debería el paso ser cero para las posiciones ya que no están intercaladas. – CodeMonkey
Me gusta la idea sobre la identificación de malla en el sombreador y pasarla como un atributo, pero ¿cómo voy a proceder al análisis en muchas matrices en el sombreador (como una matriz uniforme)? ¿Es aquí donde puedo usar los UBO para pasar, digamos, 10 matrices de transformación diferentes para 10 torretas diferentes y usar un índice analizado como atributo para buscar la matriz correcta dentro del sombreador? Esto también me permitiría usar las funciones glMultiDrawElements/Arrays dibujando un barco completo con múltiples partes, todo de una vez. – CodeMonkey
Hola, buena observación con la zancada. Pero no es un error O podría dejar stride 0 y OpenGL sabría (del segundo y tercer argumento) que tengo flujo de 3D GL_FLOATS (y por lo tanto el tamaño es 3 * sizeof (float)), o puedo calcular el paso para ello. No hay nada de malo en eso. Para aclarar aún más: zancada es la distancia entre direcciones de dos vértices consecutivos, NO es el espacio entre ellos (por lo tanto, 0 no significa que no haya bytes sin usar entre los vértices, significa que OpenGL debe calcular la zancada real a partir del número de dimensiones y tipo de datos utilizados). –