Problemstellung

Wir haben gesehen, wie man in OpenGL rasterisiert. Dieses Vorgehen funktioniert gut wenn man nur wenige Meshes hat. Das Problem: Tatsächlich arbeitet man ja mit einigen hunderten Meshes. Und da jeder dieser Aufrufe ein Call der CPU auf die GPU, ist, dauert das. Oft ist dann nicht mehr die GPU das Bottleneck sondern die CPU, die extrem viele Calls an die GPU senden muss.

Lösung

In OpenGL löst man dieses Problem mit sogenannten Vertex Array Objects. Ein VAO kann man sich als “Recorder” vorstellen, das solange es gebunden ist aufzeichnet, welche Vertex-Input-Streams definiert werden. Dadurch müssen beim Draw-Call die einzelnen Vertex-Inputs nicht jedes mal neu definiert werden, sondern lediglich der VAO gebunden. Der lädt die Konfiguration dann automatisch. In der Praxis sieht das dann so aus:

Initial einmal:

  1. VAO generien mit glGenVertexArrays
  2. VAO binden mit glBindVertexArray
  3. Definieren der Streams wie wir es bereits gesehen haben
  4. VAO unbinden
  5. Buffer unbinden

Für den Draw-Call dann nur noch:

  1. VAO binden
  2. Den Draw-Call ausführen wie wir es bereits gesehen haben
  3. VAO unbinden

Beispiel

Initial einmal:

GLUint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);        // Ab hier wird aufgezeichnet
 
	glBindBuffer(GL_ARRAY_BUFFER, vbo1);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
	
	glBindBuffer(GL_ARRAY_BUFFER, vbo2);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
	
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
	
glBindVertexArray(0);          // Aufzeichnung beendet
 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Draw-Call:

glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

Referenz

Showing 2 of 2 entries