Ich versuche, meine Engine zu aktualisieren, die OpenGL 2.x-Stil-Vertex-Arrays verwendet hat, um mit OpenGL 3.x zu arbeiten, was bedeutet, dass auf VAOs / VBOs aktualisiert wird. Ich denke, ich bin nicht verbindlich an VBO gebunden. Lesen Sie weiter unten für weitere Informationen oder springen Sie zum Code und finden Sie, was ich falsch mache.
Ein kurzer Überblick über meine Mesh-Klassen sieht ungefähr so aus:
Netz
MeshNode
MeshObject
Wenn ich einen MeshNode mit nur einem MeshObject zeichne, scheint es gut zu sein. Wenn ich einen MeshNode mit mehreren MeshObjects zeichne, erhalte ich etwas, das der allgemeinen Form des Modells entspricht, das ich zeichnen möchte, aber irgendwie verstümmelt.
Ich habe die Vertex-Daten im Visual Studio-Debugger und die VBO-Daten durch gDEbugger geprüft und alles sieht gut aus, also bin ich mir ziemlich sicher, dass das Laden von Dateien und das Laden in VBOs funktioniert.
Ich habe gDEbugger verwendet, um zu erzwingen, dass Punkte für alle Scheitelpunkte anstelle von Dreiecken gezeichnet werden, und es hat die Form eines einzelnen MeshObject, was mich glauben lässt, dass ich einfach nicht an verschiedene VBOs richtig bin. Als ob es versucht, mit verschiedenen Indizes zu zeichnen, aber immer die gleichen Ecken.
VertexData sieht folgendermaßen aus:
%Vor%Relevanter MeshNode-Code:
%Vor%Relevanter MeshObject-Code:
%Vor%Ein kurzer Überblick über meine Mesh-Klassen sieht ungefähr so aus:
Ich denke, dass Ihre Szenegraphhierarchie etwas durcheinander ist. Alle a Node
in der Szenengraph-Anforderung sind eine Transformation, die Liste von Node
untergeordneten Elementen und eine Liste von Netzen, die in diesem Node
gezeichnet werden sollen. Es sollte keinen Elementpuffer oder einen VAO haben; Diese sind konzeptionell Teil der Mesh-Daten.
Tatsächlich stammt Ihr Problem von diesem letzten Punkt. Vertex-Array-Objekte enthalten den Status, der von glVertexAttrib(I)Pointer
-Anrufen festgelegt wurde. Das heißt, jedes Mal, wenn Sie MeshObject::initVBOs
innerhalb desselben MeshNodes aufrufen, überschreiben Sie den Datensatz des vorherigen Aufrufs.
Jedes Mesh benötigt seinen eigenen VAO, nicht den Knoten. Die Meshes können Indexdaten teilen, was Sie anscheinend tun (obwohl sie auch das gleiche Pufferobjekt für ihre Vertex-Daten teilen sollten, wenn Sie Bedenken haben, zu viele Puffer zu haben). Aber die VAOs müssen anders sein. Mehrere VAOs können auf denselben Elementpuffer verweisen.
Ich denke, Sie verwenden glDrawRangeElements
falsch. Die Parameter start
und end
sind der minimale und maximale Vertex-Index, der im Indexarray auftreten kann, aber Sie geben dann m_indexOffest
und m_indexOffset+m_indices.size()
an. Dies ist der von Ihnen gerenderte Indexdatenbereich und nicht unbedingt der Bereich der Vertex-Indizes innerhalb dieser Index-Arrays.
Und als Nebenbemerkung kapselt ein VAO jedes Vertex-Array / jeden Pufferzustand, alle Pufferbindungen, die Zeiger und die aktivierten Flags, so dass Sie viele unnötige Aufrufe tätigen. Binden Sie einfach den Indexpuffer in der Methode initVAO
und dann wird immer gebunden, wenn Sie den VAO in der MeshNode::render
-Methode binden (natürlich in diesem Fall alle glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
-Aufrufe weglassen). Ebenso müssen Sie nur die Attributinstrumente in der initVAO
-Methode aktivieren (vorausgesetzt, dass alle MeshObject
s dieselben Attribute aktiviert haben) und sie automatisch aktiviert werden, wenn Sie den VAO binden. In Ihrer jetzigen Konfiguration ist der VAO völlig überflüssig und Sie profitieren davon in keiner Weise.