Ich habe einen Code, der eine Reihe von Objekten durchläuft und Instanzen dieser Objekte rendert. Die Liste der Objekte, die gerendert werden müssen, wird als std :: map> gespeichert, wobei ein Objekt der Klasse MeshResource die Eckpunkte und Indizes mit den tatsächlichen Daten enthält und ein Objekt der Klasse MeshRenderer den Punkt im Raum definiert, an dem sich das Netz befinden soll gerendert bei.
Mein Rendering-Code lautet wie folgt:
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);
Die Funktion in MeshResource, mit der die Uniformen eingerichtet werden, lautet wie folgt:
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
}
Der Code, der das Objekt rendert, lautet wie folgt:
void MeshResource::render()
{
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
Und der Code, der bereinigt, ist folgender:
void MeshResource::cleanupAfterRendering()
{
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
}
Das Endergebnis davon ist, dass ich einen schwarzen Bildschirm bekomme, obwohl das Ende meiner Rendering-Pipeline nach dem Rendering-Code (im Wesentlichen nur das Zeichnen von Achsen und Linien auf dem Bildschirm) ordnungsgemäß funktioniert, sodass ich ziemlich sicher bin, dass dies kein Problem mit dem ist Übergabe von Uniformen. Wenn ich den Code jedoch geringfügig ändere, sodass der Rendering-Code das Setup unmittelbar vor dem Rendern aufruft, wie folgt:
void MeshResource::render()
{
setupBeforeRendering();
glDrawElements(GL_TRIANGLES, geometry->numIndices, GL_UNSIGNED_SHORT, 0);
}
Das Programm funktioniert wie gewünscht. Ich möchte dies jedoch nicht tun müssen, da mein Ziel darin besteht, Scheitelpunkt-, Material- usw. Daten einmal pro Objekttyp einzurichten und dann jede Instanz so zu rendern, dass nur die Transformationsinformationen aktualisiert werden.
Die uniformizeModelMatrix funktioniert wie folgt:
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