Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

mOfl

Frischling

  • »mOfl« ist der Autor dieses Themas
  • Private Nachricht senden

1

21.04.2010, 21:15

MD2 für VBO in OpenGL 3.2 laden

Hallo Leute,

ich wende mich an euch, weil ich hoffe, dass viele Köpfe mehr Ideen haben als mein einer kleiner, rauchender Kopf. Ich arbeite gerade an einem MD2-Modelloader für ein Spiel (ich weiß selbst, dass MD2 veraltet ist, aber es muss eben trotzdem sein), das unter dem OpenGL Core Profile laufen soll. Also musste ich meinen für OpenGL 2.x geschriebenen MD2-Loader updaten, der noch mit glBegin()/glEnd() und so gearbeitet hat. VAO/VBO heißen die großen Zauberworte, und da wird es schon interessant. Statt jedes Dreieck einzeln mit den dazugehörigen Texturkoordinaten für jeden Vertex zu zeichnen, muss ich ja alles in großen Arrays übergeben. Untexturiert funktioniert alles super, aber bekannter Krisenherd: mehrere Texturkoordinaten für denselben Vertex. Da ich es in mehreren Anläufen nicht richtig hinbekommen habe, die betroffenen Vertizes selbst zu duplizieren, habe ich im Internet mal nach MD2-Loadern gesucht und wollte spickeln, wie dort die Vertices kopiert werden. Leider habe ich jetzt nach dem Durchsehen von etwa 10 Loadern bemerkt, dass die alle (verständlicherweise) vor mehreren Jahren geschrieben wurden und noch mit den alten GL-Befehlen arbeiten, wo man sich noch keine Sorgen um doppelte Texturkoordinaten machen musste. Lediglich in assimp (http://assimp.sourceforge.net/ ) konnte ich einen Kommentar finden, der verheißt, dass eine Überprüfung erfolgt, die ich aber nicht finden kann... Ich habe mal - hoffentlich im Einklang mit den Lizenzbedingungen - den Auszug hier hochgeladen: http://pastebin.org/166131 Der Kommentar findet sich in Zeile 69/70, aber ich finde die entsprechenden Zeilen im Code dafür nicht. Bin ich schon weich in der Birne oder ist das wirklich nicht implementiert? Zugegeben, ich bin nicht sehr fit darin, fremden Code sofort zu durchschauen...

Nun suche ich also weiterhin nach der richtigen Methode, die Vertizes beim Laden zu duplizieren, wenn es verschiedene Texturkoordinatenverweise darauf gibt. Ich habe ja erwähnt, dass ich bereits mehrere eigene Anläufe unternommen habe, deshalb will ich euch einmal zeigen, was ich bisher gemacht habe: http://pastebin.org/166142

Das eigentliche Problem ist, dass das nur für manche Models funktioniert. Ich habe momentan drei verschiedene Models, von denen das eine für jeden Vertex genau eine Texturkoordinate hat und zwei Models, die mehr Texturkoordinaten als Vertices haben. Für eines dieser Models funktioniert das ganze auch prima, wie es soll, d.h. am Ende des Ladens habe ich genau so viele Vertices wie Texturkoordinaten, beim anderen Model werden seltsamerweise zu viele Duplikate erstellt, sodass ich am Ende mehr Vertices als Texturkoordinaten habe. Der Output dieses Models:

Quellcode

1
2
3
4
5
6
7
numVertices: 844
numTexCoords: 1379
numTriangles: 1664
numFrames: 198

clonedVertices: 546
numVertices: 1390


Und ich möchte euch jetzt fragen, warum das so ist. Irgendwo zwischen Zeile 39 und Zeile 54 dieses Auszugs habe ich wohl eine Überprüfung vergessen, die es 11 Vertices ermöglicht, sich noch einmal zu verdoppelt, obwohl das nicht nötig gewesen wäre. Ich prüfe zuerst, ob ich in mein Index-Array bereits den jetzt einzufügenden Vertex geschrieben habe und, wenn ja, ob dieser den gleichen Texturkoordinatenindex hat. Hat er das, ist alles kein Problem. Hat er das nicht, muss ich alle bereits bestehenden Duplikate (clones) durchsehen. Ich habe dazu drei Arrays wie eine Lookup-Tabelle angelegt, wobei clonedVertexOrigin immer den ursprünglichen Vertex-Index enthält, clonedVertexDestination den neuen. clonedVertexOriginTexCoords ist der Index auf die Texturkoordinate, der sich beim Duplizieren nicht ändert. Zusätzlich habe ich eine Zählvariable clonedVertices, die mir dabei hilft, ans Ende dieser Lookup-Arrays zu navigieren.
So gehe ich nun also alle Duplikate durch und prüfe, ob ich für die Kombination Vertex-Index / Texturkoordinaten-Index bereits ein Duplikat angelegt habe. Ist das der Fall, ändere ich einfach den Vertex-Index des einzufügenden Punktes auf den neuen Wert aus clonedVertexDestination. Ist das nicht der Fall, lege ich ein Duplikat des Vertex und seiner Normalen in allen Frames an und schreibe das auch für die nächste Iteration in die Lookup-Arrays.

Meinem Gedankengang nach berücksichtigt das bereits alles, was man berücksichtigen müsste, aber trotzdem scheint es noch möglich zu sein, dass ein Vertex dupliziert wird, obwohl es nicht nötig wäre. Weiß einer, woran das liegen könnte? Ich würde mich wirklich freuen, wenn ich meinen Code so korrigieren könnte, dass es funktioniert, aber zur Not bin ich auch dankbar über einen funktionierenden MD2-Loader, der mir meine Daten korrekt so einliest, dass ich sie in Arrays habe und an die VBOs weitergeben kann. Bis die Sache richtig funktioniert, werde ich vermutlich jeden Vertex-Index jedes Dreiecks als eigenen Vertex behandeln, sodass ich am Ende numTriangles * 3 Vertices, Normals und dann auch Texturkoordinaten habe. Da kann man glaube ich nicht viel falsch machen, außer, dass es eine sehr ineffiziente Methode mit etwa dreimal so vielen Vertices wie die Optimallösung.

Viele Grüße
mOfl

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

21.04.2010, 22:32

Wieso erstellst du den Puffer nicht einfach aufgrund der Triangleliste?

Pseudo:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int index = 0;

foreach t in triangles

  for i = 0 to 2
    vertex newVertex;
    newVertex.xyz = modelVertices[t.vertexIndex[i]];
    newVertex.uv = modelUv[t.uvIndex[i]]

    // puffer updaten
    *buffer = newVertex;
    *indices = index++;
    buffer += sizeof vertex
    indices += 1
@D13_Dreinig

mOfl

Frischling

  • »mOfl« ist der Autor dieses Themas
  • Private Nachricht senden

3

22.04.2010, 00:33

Danke für die Antwort. Ich habe das in meinem Beitrag am Ende ja schon geschrieben, dass ich es gerade so mache. Ich hab das etwas unverständlich geschrieben mit dem AnzahlDerDreiecke * 3, aber gemeint habe ich genau das. Die Dreiecksliste durchgehen und jeden Vertex / jede Texturkoordinate der Reihe nach in die Arrays für die VBOs schreiben. Das funktioniert natürlich, nur das ist etwas ineffizient. Natürlich spielt es bei der Grafikkartenleistung für meine Zwecke keine sonderlich große Rolle, aber das Optimum wäre natürlich die Lösung, bei der man am Ende nur Arrays der Länge AnzahlDerTexturkoordinaten an die VBOs übergibt, nicht AnzahlDerDreiecke * 3, worauf dein Vorschlag ja hinausläuft. Das sind pro Model in meinem Fall 4992 Vertices statt 1379, wenn das mehrere Male gleichzeitig gezeichnet werden soll (inklusive Interpolation für die framebasierte Animation im Vertex-Shader), dann ist man doch immer bestrebt, die Datenstrukturen so klein wie möglich zu halten.

Werbeanzeige

Ähnliche Themen