Vertex Buffer Objects Revisited
Bisher: Vertices wurden einzeln per glVertex3f() o.ä. übergeben. Nachteil: Langsam, typischerweise werden viele konstante Vertices benutzt (Objekte verändern sich in-sich nicht), mit zusätzlichen Attributen (Material, Farbe, etc.).
Dazu können Vertices in festen Arrays gespeichert werden. Sind diese Arrays OpenGL frühzeitig bekannt gemacht, können die Daten im Grafikspeicher (sehr schnell!) gespeichert werden.
Beispiel:
0.75f, 0.75f, 0.0f,
0.75f, -0.75f, 0.0f,
-0.75f, -0.75f, 0.0f,
};
Nachteil: Wenn viele Vertices verändert werden müssen (z.B. Explosionen) verschwindet der Geschwindigkeitsvorteil.
Erzeugung
Man benötigt ein Vertex Array Object, um die Bindung der Daten an Attribute zu speichern; initial ist keines gesetzt, also muss explizit eines erstellt werden:
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
Mit Hilfe von glGenBuffers(<Anzahl>, <Addresse eines GLuint-Arrays); können dann <Anzahl> Buffer reserviert werden. Bei Anzahl=1 reicht natürlich eine GLuint-Variable, kein Array.
glGenBuffers (1, &vbo);
Buffer können immer wieder mit neuen Daten gefüllt werden. Es können auch nur Teile des Buffers benutzt werden.
Füllen
Man selektiert einen Vertex Buffer Object, und befüllt ihn anschließend mit Daten. Diese werden noch nicht interpretiert!
glBufferData (GL_ARRAY_BUFFER, sizeof(vecData), vecData, GL_STATIC_DRAW);
Benutzen
Schließlich selektiert man ein VBO, schaltet ihn ein und definiert die Datenstruktur durch glVertexAttribPointer (<index=0 für Vertices>, <Anzahl Komponenten je Element>, <typ, z.B. GL_FLOAT>, <GL_FALSE wenn der Wertebereich nicht auf 0..1 reduziert werden soll>, <Abstand zwischen zwei Elementen>, <Byte-Offset zum ersten Wert>)
Der letzte Wert muss aus historischen Gründen als Pointer übergeben werden, obwohl wir einen Ganzahlwert setzen. Um die Warnung zu vermeiden, ggf. auf (void *) casten.
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
Und jetzt zeichnen wir damit, indem wir den Primitivtyp, die Nummer des ersten Elements und die Anzahl übergeben: