Tengo un código que recorre un conjunto de objetos y muestra instancias de esos objetos. La lista de objetos que necesita ser renderizada se almacena como un std :: map>, donde un objeto de la clase MeshResource contiene los vértices e índices con los datos reales, y un objeto de classMeshRenderer define el punto en el espacio donde la malla debe ser prestado en.
Mi código de representación es el siguiente:
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
for (std::map<MeshResource*, std::vector<MeshRenderer*> >::iterator it = renderables.begin(); it != renderables.end(); it++)
{
it->first->setupBeforeRendering();
cout << "<";
for (unsigned long i =0; i < it->second.size(); i++)
{
//Pass in an identity matrix to the vertex shader- used here only for debugging purposes; the real code correctly inputs any matrix.
uniformizeModelMatrix(Matrix4::IDENTITY);
/**
* StartHere fix rendering problem.
* Ruled out:
* Vertex buffers correctly.
* Index buffers correctly.
* Matrices correct?
*/
it->first->render();
}
it->first->cleanupAfterRendering();
}
geometryPassShader->disable();
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
La función en MeshResource que maneja la configuración de los uniformes es la siguiente:
void MeshResource::setupBeforeRendering()
{
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); // Vertex position
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 12); // Vertex normal
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 24); // UV layer 0
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 32); // Vertex color
glVertexAttribPointer(4, 1, GL_UNSIGNED_SHORT, GL_FALSE, sizeof(Vertex), (const GLvoid*) 44); //Material index
}
El código que representa el objeto es este:
void MeshResource::render()
{
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
Y el código que limpia es este:
void MeshResource::cleanupAfterRendering()
{
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
}
El resultado final de esto es que obtengo una pantalla negra, aunque el final de mi canal de renderizado después del código de renderizado (esencialmente solo dibujando ejes y líneas en la pantalla) funciona correctamente, así que estoy bastante seguro de que no es un problema con el paso de uniformes. Sin embargo, si cambio el código ligeramente para que el código de representación llame a la configuración inmediatamente antes de la representación, así:
void MeshResource::render()
{
setupBeforeRendering();
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
El programa funciona según lo deseado. Sin embargo, no quiero tener que hacer esto, ya que mi objetivo es configurar los datos de vértices, materiales, etc. una vez por tipo de objeto y luego hacer que cada instancia actualice solo la información de transformación.
UniformizeModelMatrix funciona de la siguiente manera:
void RenderManager::uniformizeModelMatrix(Matrix4 matrix)
{
glBindBuffer(GL_UNIFORM_BUFFER, globalMatrixUBOID);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(Matrix4), matrix.ptr());
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
offsetof
al especificar atributos de vértice