OpenGL VBO's
-
Ich lerne gerade OpenGL und möchte jetzt VBO's nutzen.
Dazu habe ich dieses Tutorial gelesen: http://www.opengl.org/wiki/Vertex_Buffer_Object
Ich verstehe das aber nicht ganz.1. Padding: Man weiß doch eh nicht was genau der Compiler aus der Struktur macht, oder wird hier einfach angenommen, dass an 64/32 byte nichts mehr geändert wird?
2. Warum wird die Adresse von &pvertices[0].x statt &pvertices[0] übergeben?
2.1 Wird hier schon wieder angenommen, dass der Compiler die Struktur einfach so lässt, wie sie ist?3. Müssen Vertexe für VBO's immer genau so aussehen wie in der obigen Struktur?
-
truppel schrieb:
1. Padding: Man weiß doch eh nicht was genau der Compiler aus der Struktur macht, oder wird hier einfach angenommen, dass an 64/32 byte nichts mehr geändert wird?
Man weiß normalerweise schon, was der Compiler genau aus der Struktur macht (siehe Dokumentation deines Compilers).
truppel schrieb:
2. Warum wird die Adresse von &pvertices[0].x statt &pvertices[0] übergeben?
Ist beides gleichwertig, das garantiert dir in dem Fall (POD) sogar der C++ Standard.
truppel schrieb:
3. Müssen Vertexe für VBO's immer genau so aussehen wie in der obigen Struktur?
Was genau meinst du mit "genau so aussehen"?
-
dot schrieb:
Man weiß normalerweise schon, was der Compiler genau aus der Struktur macht (siehe Dokumentation deines Compilers).
Ja, aber die wissen ja nicht welchen Compiler ich nutze. Es ist doch eigentlich nicht mal garantiert, dass sizeof(float) == 4, oder irre ich mich da?
Da hätte man doch OpenGL-Typen für definieren können. (Wobei das Padding Problem dann immer noch nicht gelöst wäre.)
Der große Vorteil von OpenGL ist ja, dass es nicht nur unter einem System (und einem Compiler) läuft.dot schrieb:
Ist beides gleichwertig, das garantiert dir in dem Fall (POD) sogar der C++ Standard.
Ok, danke.
dot schrieb:
Was genau meinst du mit "genau so aussehen"?
Na.. genau so aufgebaut sein. Erst kommen drei mal 4-byte große float's für die Vertexposition, dann die Normalen, dann drei mal je zwei Texturkoordinaten. Also man baut seinen Puffer immer genau so auf, weil die Grafikkarte (bzw. die OpenGL-API) den nur genau so verarbeiten kann?
Denn dann könnte man ja z.B. nicht einfach einen Würfel der nur aus ein paar Punkten besteht in einen VBO packen. (Zumindest nicht ohne Speicherplatz für nicht vorhandene Normalen/Textur-Koordinaten zu reservieren.)
-
Ließ mal da skomplette Tutorial durch und überleg dir mal genau, was der Sinn der gl*Pointer Aufrufe sein könnte.
-
truppel schrieb:
Ja, aber die wissen ja nicht welchen Compiler ich nutze. Es ist doch eigentlich nicht mal garantiert, dass sizeof(float) == 4, oder irre ich mich da?
Nein. Aber dann ist nichtmal garantiert dass float überhaupt ein IEEE 754 float ist. Es gibt ein typedef GLfloat. Aber wenn die Hardware nicht mit IEEE 754 zurechtkommt, dann helfen alle typedefs der Welt nix. Davon wird einfach mal ausgegangen. Und ja natürlich werden da Annahmen getroffen über das Layout des struct. Wenn dir das nicht gefällt, kannst du ja alles in float-Arrays packen
truppel schrieb:
dot schrieb:
Was genau meinst du mit "genau so aussehen"?
Na.. genau so aufgebaut sein. Erst kommen drei mal 4-byte große float's für die Vertexposition, dann die Normalen, dann drei mal je zwei Texturkoordinaten. Also man baut seinen Puffer immer genau so auf, weil die Grafikkarte (bzw. die OpenGL-API) den nur genau so verarbeiten kann?
Nein. Die Reihenfolge spielt keine Rolle. Du könntest einzelne Attribute auch in separate Buffer stecken oder was dir auch immer sonst noch einfallen mag. Dafür gibts ja glVertexPointer() etc.
-
dot schrieb:
Und ja natürlich werden da Annahmen getroffen über das Layout des struct. Wenn dir das nicht gefällt, kannst du ja alles in float-Arrays packen
Hach, wie ich den Standard doch hasse.
dot schrieb:
Nein. Die Reihenfolge spielt keine Rolle. Du könntest einzelne Attribute auch in separate Buffer stecken oder was dir auch immer sonst noch einfallen mag. Dafür gibts ja glVertexPointer() etc.
Ah ok. Da sieht man, dass ich das Konzept noch nicht ganz verstanden habe. Ist auch nicht ganz leicht wie ich finde, da sehr viele Funktionen einfach intern etwas verändern (Bind, *Pointer), da sieht man auf den ersten Blick wenig. Aber gut, ich denke, ich habe das Grundprinzip jetzt halbwegs verstanden.
Ein paar Fragen habe ich allerdings noch:
1. Was machen die hier:Bind your VBO. P.S., Our VBO is already bound actually.
...
Bind your IBO. P.S., Our IBO is already bound actually.Die Befehle sehen doch genau gleich aus!
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
2. Ein nicht Index-basiertes Array zu rendern ist so aber nicht möglich, oder übersehe ich da wieder etwas?
3. Wird dieses Konzept/glDrawRangeElements noch außerhalb der fixed-pipeline genutzt, oder wurde das auch alles umgekrempelt und ich lerne gerade quasi altes Zeug?
Vielen Dank schon mal für eure Zeit und Hilfe!
-
truppel schrieb:
Ist auch nicht ganz leicht wie ich finde, da sehr viele Funktionen einfach intern etwas verändern (Bind, *Pointer) [...]
Ja, das kaputte Objektmodell ist imo auch eine der große Schwachstellen von OGL. Gab mal Versuche das zu fixen, ist aber leider nix draus geworden.
truppel schrieb:
[...] Die Befehle sehen doch genau gleich aus!
Versteh nicht ganz was du damit meinst!?
truppel schrieb:
2. Ein nicht Index-basiertes Array zu rendern ist so aber nicht möglich, oder übersehe ich da wieder etwas?
Doch klar: glDrawArrays().
truppel schrieb:
3. Wird dieses Konzept/glDrawRangeElements noch außerhalb der fixed-pipeline genutzt, oder wurde das auch alles umgekrempelt und ich lerne gerade quasi altes Zeug?
glDraw*() ist in zeitgenössischem OpenGL der einzige Weg um was zu zeichnen
-
Du glaubst gar nicht was für Wissenslöcher du mit einfachen Verknüpfungen gerade bei mir geschlossen hast.
dot schrieb:
Versteh nicht ganz was du damit meinst!?
Na, sie binden zwei mal hintereinander genau das gleiche Objekt A (wenn wir die ID mal als Objekt sehen wollen), mit der Aussage: "Bind your A P.S., our A is already bound actually. "
Das verstehe ich nicht so ganz, mir ist weder klar war P.S. heißt, noch warum sie zwei mal das augenscheinlich gleiche Objekt binden, mit der Aussage es wären verschiedene.truppel schrieb:
glDraw*() ist in zeitgenössischem OpenGL der einzige Weg um was zu zeichnen
Hm.. vielleicht ist modernes OpenGL doch gar nicht so schlimm. Aber ich dachte, man müsste um überhaupt etwas ausgeben zu können eigene Shader bauen? Das System habe ich irgendwie auch noch so gar nicht durchblickt.
-
truppel schrieb:
Aber ich dachte, man müsste um überhaupt etwas ausgeben zu können eigene Shader bauen? Das System habe ich irgendwie auch noch so gar nicht durchblickt.
Das ist auch so. Statt gezielt Vertex, Texturkoordinaten etc. festzulegen, gibt es in der aktuellen OpenGL Spec nur noch glVertexAttribPointer, wo man einen Index für die jeweiligen Daten bestimmt. Der Index gibt dann die Reihenfolge an, in der die verschiedenen Daten dann im Vertexshader übergeben werden. Wie man die Daten dann genau nutzt, ist natürlich dann Sache des Shaders.
An der generellen Vorgehensweise ändert sich aber nichts. Es wird nur der aktuelle Shader eingesetzt, statt der fixed function pipeline.