Wie minimiere ich glVertexAttribPointer-Aufrufe bei Verwendung von instanzierten Arrays?

Ich habe OpenGL-Code mit einem VAO für alle Modelldaten und zwei VBOs. Die erste für Standardscheitelpunktattribute wie Position und Normal und die zweite für die Modellmatrizen. Ich verwende instanziiertes Zeichnen, also lade ich die Modellmatrizen als instanziierte Arrays (die im Grunde Vertex-Attribute sind).

Zunächst lade ich die Standard-Vertex-Attribute in einen VBO und richte alles einmal mit @ eglVertexAttribPointer. Dann lade ich die Modellmatrizen in einen anderen VBO. Jetzt muss ich @ anrufglVertexAttribPointerin der Ziehschleife. Kann ich das irgendwie verhindern?

Der Code sieht so aus:

// vertex data of all models in one array
GLfloat myvertexdata[myvertexdatasize];

// matrix data of all models in one array
// (one model can have multiple matrices)
GLfloat mymatrixdata[mymatrixsize];

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, myvertexdatasize*sizeof(GLfloat), myvertexdata, GL_STATIC_DRAW);

glVertexAttribPointer(
          glGetAttribLocation(myprogram, "position"),
          3,
          GL_FLOAT,
          GL_FALSE,
          24,
          (GLvoid*)0
);
glEnableVertexAttribArray(glGetAttribLocation(myprogram, "position"));
glVertexAttribPointer(
          glGetAttribLocation(myprogram, "normal"),
          3,
          GL_FLOAT,
          GL_FALSE,
          24,
          (GLvoid*)12
);
glEnableVertexAttribArray(glGetAttribLocation(myprogram, "normal"));

GLuint matrixbuffer;
glGenBuffers(1, &matrixbuffer);
glBindBuffer(GL_ARRAY_BUFFER, matrixbuffer);
glBufferData(GL_ARRAY_BUFFER, mymatrixsize*sizeof(GLfloat), mymatrixdata, GL_STATIC_DRAW);

glUseProgram(myprogram);


draw loop:
    int vertices_offset = 0;
    int matrices_offset = 0;
    for each model i:
        GLuint loc = glGetAttribLocation(myprogram, "model_matrix_column_1");
        GLsizei matrixbytes = 4*4*sizeof(GLfloat);
        GLsizei columnbytes = 4*sizeof(GLfloat);
        glVertexAttribPointer(
              loc, 
              4, 
              GL_FLOAT, 
              GL_FALSE, 
              matrixbytes,
              (GLvoid*) (matrices_offset*matrixbytes + 0*columnbytes)
        );
        glEnableVertexAttribArray(loc);
        glVertexAttribDivisor(loc, 1); // matrices are in instanced array
        // do this for the other 3 columns too...

        glDrawArraysInstanced(GL_TRIANGLES, vertices_offset, models[i]->num_vertices(), models[i]->num_instances());

        vertices_offset += models[i]->num_vertices();
        matrices_offset += models[i]->num_matrices();

Ich dachte an den Ansatz, Eckendaten und Matrizen in einem VBO zu speichern. Das Problem ist dann, wie man die Schritte richtig einstellt. Ich konnte keine Lösung finden.

Jede Hilfe wäre sehr dankbar.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage