Computergrafik

Vertex Buffer Objects

2D Texturen Mehrfachtexturen | | Per-Vertex Attribute Im VBO

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:

const float vecData[] = {
    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:

GLuint vao;
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);

“Vertex Array Object is brought to you by the OpenGL ARB Subcommittee for Silly Names.”

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.

GLuint vbo;
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!

glBindBuffer (GL_ARRAY_BUFFER, vbo);
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.

glBindBuffer (GL_ARRAY_BUFFER, vbo);
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:

glDrawArrays (GL_TRIANGLES, 0, 3);

VBOs im Framework

VBOs sind im Framework in der lglVBO Klasse abstrahiert. Man fügt Vertices und Attribute hinzu, wie man es im Direct Mode gewohnt war.

lglVBO  vbo;
// Fill VBO with data
vbo.lglBegin(LGL_TRIANGLES);
vbo.lglColor(1, 0, 0, 0);
vbo.lglVertex(-0.5,-0.5,0);
vbo.lglColor(0, 1, 0, 0);
vbo.lglVertex(0.5,-0.5,0);
vbo.lglColor(0, 0, 1, 0);
vbo.lglVertex(0,0.5,0);
vbo.lglEnd();

Und später in der Display-Routine:

lglRender(vbo);


2D Texturen Mehrfachtexturen | | Per-Vertex Attribute Im VBO

Options: