2011-08-28 10 views
7

¿Es posible almacenar atributos de vértice diferentes en diferentes búferes de vértices?Almacenar diferentes atributos de vértice en diferentes VBO

Todos los ejemplos que he visto hasta ahora hacen algo como esto

float data[] = 
{ 
//position 
    v1x, v1y, v1z, 
    v2x, v2y, v2z, 
    ... 
    vnx, vny, vnz, 

//color 
    c1r, c1g, c1b, 
    c2r, c2g, c2b, 
    ... 
    cnr, cng, cnb, 
}; 
GLuint buffname; 
glGenBuffers(1, &buffname); 
glBindBuffer(GL_ARRAY_BUFFER, buffname); 
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 

Y el dibujo se hace algo como esto:

glBindBuffer(GL_ARRAY_BUFFER, buffname); 
glEnableVertexAttrib(position_location); 
glEnableVertexAttrib(color_location); 
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, (void*)(3*n)); 

glDrawArrays(GL_TRIANGLES, 0, n/3); 

glDisableVertexAttrib(position_location); 
glDisableVertexAttrib(color_location); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

¿No es posible almacenar datos de posición y datos de color en diferentes VBO? El problema es que no entiendo cómo funcionaría esto porque no puedes unir dos búferes a la vez, ¿o sí?

Si hay una solución simple pero ineficiente, preferiría una solución más complicada pero eficiente porque estoy en el estado de aprendizaje primario y no quiero complicar demasiado las cosas.

Además, si lo que estoy preguntando es posible, ¿es una buena idea o no?

Para aclarar: entiendo cómo podría almacenar diferentes atributos en diferentes VBO de. No entiendo cómo los dibujaré más tarde.

Respuesta

9

La asociación entre la ubicación del atributo X y el objeto del búfer que proporciona ese atributo se realiza con el comando glVertexAttribPointer. La forma en que funciona es simple, pero no intuitiva.

En el momento glVertexAttribPointer se llama (esa es la parte que mucha gente no lo entiendo), cualquiera que sea memoria intermedia de objetos en la actualidad está obligado a GL_ARRAY_BUFFER se asocia con el atributo X, donde X es el primer parámetro de glVertexAttribPointer.

Así que si usted quiere tener un atributo que viene de un tampón y un atributo que viene de otro, esto se hace:

glEnableVertexAttrib(position_location); 
glEnableVertexAttrib(color_location); 
glBindBuffer(GL_ARRAY_BUFFER, buffPosition); 
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0); 
glBindBuffer(GL_ARRAY_BUFFER, buffColor); 
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, 0); 

cuanto a si debe dividir atributos en diferentes tampones. ... Yo diría que solo debes hacerlo si tienes una demostrable que necesita.

Por ejemplo, supongamos que está haciendo un mapa de altura dinámico, tal vez por algún tipo de efecto de agua. La posición Z de cada elemento cambia, pero esto también significa que las normales cambian. Sin embargo, las posiciones XY y las coordenadas de textura no cambian.

La transmisión eficiente suele requerir objetos de búfer de doble búfer o invalidarlos (reasignándolos con un glBufferData (NULL) o glMapBufferRange (GL_INVALIDATE_BIT)). De cualquier manera, solo funciona si los datos transmitidos están en otro objeto de búfer de los datos no transmitidos.

Otro ejemplo de una necesidad demostrable es si la memoria es una preocupación y varios objetos comparten ciertas listas de atributos. Tal vez los objetos tienen diferentes posiciones y matrices normales, pero las mismas matrices de coordenadas de color y textura. O algo así.

Pero, por lo demás, es mejor simplemente poner todo para un objeto en un búfer. Incluso si no intercalas las matrices.

+1

¡Muchas gracias! ¡Entiendo!Mucho más se hizo de repente más claro :))) ¿Qué pasa con mi segunda pregunta? ¿Se considera generalmente una buena idea o no? –

+1

@Armen: ver mi edición. –

+0

Lo veo mucho más claro ahora. Muchas gracias. Entonces, en casos simples deberíamos usar el primer enfoque mencionado por Nicol, y si es necesario, usamos VBO diferentes. ¡Mucho más claro gracias! –

Cuestiones relacionadas