2017-02-07 2 views
3

Ich portiere ein älteres Programm mit glBegin()/glEnd() (oben im Bild) zu glDrawArraysInstanced() (Bild unten). Ich habe einige Leistungsverbesserungen erwartet, aber ich habe das Gegenteil erreicht. Nun, das ist das erste Mal, dass ich versucht habe, glDrawArraysInstanced() zu benutzen, also denke ich, dass ich irgendwo etwas vermasselt habe.OpenGL instanced rendering langsamer als glBegin/glEnd

Die beiden sind im Grunde identisch und der einzige Unterschied ist, wie sie die Kreise zeichnen.

Was habe ich falsch gemacht? Und wenn nicht, was macht es langsamer?

enter image description here enter image description here

// This runs once at startup 
std::vector<glm::mat4> transforms; 
glGenBuffers(NUM_BUFFERS, VBO); 
glBindBuffer(GL_ARRAY_BUFFER, VBO[TRANSFORM]); 
for (int i = 0; i < 4; ++i) { 
    glEnableVertexAttribArray(1 + i); 
    glVertexAttribPointer(1 + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), 
         (GLvoid *)(i * sizeof(glm::vec4))); 
    glVertexAttribDivisor(1 + i, 1); 
} // --------- 


// This runs every frame 
if (num_circles > transforms.size()) transforms.resize(num_circles); 
int i = 0; 
for (const auto &circle : circle_vec) { 
    transforms[i++] = circle.transform.getModel(); 
} 

glBindBuffer(GL_ARRAY_BUFFER, VBO[TRANSFORM]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * num_circles, &transforms[0], GL_DYNAMIC_DRAW); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

glBindVertexArray(VAO); 
glDrawArraysInstanced(GL_LINE_LOOP, 0, CIRCLE_NUM_VERTICES, num_circles); 
glBindVertexArray(0); 
// --------- 


// And this is the vertex shader 
#version 410 

in vec3 position; 
in mat4 transform; 

void main() 
{ 
    gl_Position = transform * vec4(position, 1.0); 
} 
+0

Wireframe ist sehr schlecht für die Leistung. Ich sehe, dass Ihre langsamere Version nur Konturen zeichnet, was ein wichtiger Faktor sein könnte. –

+0

@DavidLively Ich benutzte GL_LINE_LOOP. Exakt gleiche Leistung mit GL_TRIANGLE_FAN. –

+0

Das bedeutet, dass das Problem woanders ist. @ OnurA's Antwort über den Vektor ist ein guter Anfang. Die Neuzuordnung eines Vektors mit vielen Elementen in jedem Frame kann schnell zum Engpass werden. –

Antwort

4

Was ich an meinem ersten Blick sah, ist, dass Sie auf jeden Frame einen neuen Vektor schaffen. Erwägen Sie, es zwischenzuspeichern.

// This runs every frame 
std::vector<glm::mat4> transforms; 
+0

@MarcusMathiassen Was er sagte: Halten Sie den Vektor zwischen den Frames, und löschen Sie es jedes Mal. (Nicht zurücksetzen, da dies den Speicher freigibt, was den Zweck vereitelt.) –

+0

Den Vektor nach außen zu setzen und nur bei Bedarf die Größe zu ändern, ergab genau die gleiche Leistung. Ich denke, es muss etwas anderes sein. –

+0

Entschuldigung dafür, dass wir nicht klar genug sind, danke DavidLively, dass wir klar gemacht haben @DavidLively, danke Kumpel! –