2012-01-14 10 views
7

que vinieron de esta pregunta:Estructura OpenGL de VAO/VBO para modelo con piezas móviles?

opengl vbo advice

que utilizan OpenGL 3.3 y no usar elementos obsoletos. Estoy usando Assimp para importar mis modelos de licuadora. Pero estoy un poco confundido sobre cuánto debería dividirlos en términos de VAO y VBO.

primer lugar una pequeña pregunta lado. Yo uso glDrawElements, hacer eso significa que no pueda intercalar mi vértice atributos o puede la figura VAO a cabo utilizando el glVertexAttribPointer y los glDrawElements desplazamiento para ver donde mi posición de vértice es?

cuestión principal que supongo, se reduce a ¿Cómo estructuro mi VAO/VBO de un modelo con múltiples partes móviles, y varias mallas pr. parte.

Cada nodo en assimp puede contener múltiples mallas donde cada malla tiene textura, vértices, normales, material, etc. Los nodos en assimp contiene las transformaciones. Digamos que tengo un barco con una torreta de cañón. Quiero poder rootear la torreta. Esto significa que haré del nodo de barco un VAO separado con VBO para cada malla que contenga sus atributos (o múltiples VBO, etc.). supongo que va como

draw(ship); //call to draw ship VAO 
pushMatrix(turretMatrix) //updating uniform modelview matrix for the shader 
draw(turret); //call to draw turret VAO 

No entiendo totalmente UBO (objetos de amortiguamiento uniforme) aún, pero parece que puedo pasar en múltiples uniformes, habrá que me ayude a contener un modelo completo con partes móviles en una solo VAO?

Respuesta

13

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 ...

+0

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

+0

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

+0

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). –

0

@theswine

no vinculante esto durante la inicialización VAO hace que mi programa se bloquee, pero la unión que después de la unión del VAO lo hace funcionar correctamente. ¿Estás seguro de que esto no se guarda en el VAO?

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // not saved in VAO 

(Por cierto: lo siento para la crianza de un viejo tema, pensé que esto podría ser útil a los demás, este post era seguro (que me recuerda, gracias !!))

+0

Hola. Acabo de ver esto por accidente, ya que los usuarios no reciben notificaciones cuando publica una respuesta, comenzando con '@ login' (solo se notifica a OP). Deberías haber dejado un comentario en mi respuesta, sería notificado de eso. Le sugiero que comience una nueva pregunta y publique un código mínimo que reproduzca su falla. ¿Sería eso posible? Entonces puedes dejarme un comentario '@ login' debajo de este comentario y veré tu problema. –

+0

Lo siento, no pude comentar tu publicación debido a mi falta de reputación. Pero trataré de juntar algo para que lo revises (¿quizás sea solo mi hardware?) – luveti

+0

Por lo general, es solo un índice intercambiado o encuadernado encuadernado. Sucede lo mejor. En ocasiones, el búfer de elemento array (índice) crea problemas, especialmente en las tarjetas gráficas Intel. –

Cuestiones relacionadas