2017-04-25 2 views
0

Ich versuche, zwei verschiedene Vertexsammlungen übereinander zu rendern. Im Moment rendert meine Hauptschleife eine korrekt, wenn sie selbst ist, und die andere korrekt, wenn sie alleine ist, aber wenn ich meine beiden Zeichenfunktionen aufruft, sehe ich ein leeres Fenster. Warum könnte das passieren?OpenGL mehrere Draw-Aufrufe mit eindeutigen Shadern gibt leeren Bildschirm

Der erste Zeichenaufruf verwendet einen Shader, während der zweite Zeichenaufruf einen anderen verwendet. Ich lösche den Bildschirm nicht zwischendurch.

Wenn es den Code klarer macht, werden meine Shader-Programme als Klassenvariablen gespeichert, ebenso wie die Textur-IDs, nachdem sie elderhwere in meinem Programm geladen sind.

Das ist meine Hauptschleife:

while (true) 
{ 
    // Clear the colorbuffer 
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    drawModel1(); // This works when drawModel2() is commented out 
    drawModel2(); // This works when drawModel1() is commented out 

    // Unbind buffer 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    // Swap the screen buffers 
    glfwSwapBuffers(_window); 
} 

Meine drawModel1() Funktion macht Punkte:

void drawModel1() 
{ 
    // Use the image shader 
    _img_shader.use(); 

    // Feed the position data to the shader 
    glBindBuffer(GL_ARRAY_BUFFER, _img_pos_VBO); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 
    glEnableVertexAttribArray(0); 

    // Feed the color data to the shader 
    glBindBuffer(GL_ARRAY_BUFFER, _img_color_VBO); 
    glVertexAttribPointer(1, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3 * sizeof(GLubyte), (GLvoid*)0); 
    glEnableVertexAttribArray(1); 

    // Set the projection matrix in the vertex shader 
    GLuint projM = glGetUniformLocation(_img_shader.program(), "proj"); 
    glm::mat4 proj = _ndc * _persMat; 
    glUniformMatrix4fv(projM, 1, GL_TRUE, glm::value_ptr(proj)); 

    // Set the view matrix in the vertex shader 
    GLuint viewM = glGetUniformLocation(_img_shader.program(), "view"); 
    glUniformMatrix4fv(viewM, 1, GL_TRUE, glm::value_ptr(_viewMat)); 

    // Draw the points 
    glBindVertexArray(_img_VAO); 
    glDrawArrays(GL_POINTS, 0, _numImageVertices); 

    // Disable attributes 
    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 
} 

Und meine drawModel2() Funktion macht indexierten Dreiecken:

void drawModel2() 
{ 
    _model_shader.use(); 

    // Load the mesh texture 
    GLuint texID = _loaded_textures.at(mesh.tex_file()); 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texID); 
    glUniform1i(glGetUniformLocation(_model_shader.program(), "texture_img"), 0); 

    // Set the proj matrix in the vertex shader 
    GLuint nvpmM = glGetUniformLocation(_model_shader.program(), "npvm"); 
    glm::mat4 npvm = _ndc * _persMat * _viewMat * mat; 
    glUniformMatrix4fv(nvpmM, 1, GL_FALSE, glm::value_ptr(npvm)); 

    // Feed the position data to the shader 
    glBindBuffer(GL_ARRAY_BUFFER, mesh.pos_VBO()); 
    GLuint pos_att = glGetAttribLocation(_model_shader.program(), "position"); 
    glEnableVertexAttribArray(pos_att); 
    glVertexAttribPointer(pos_att, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); 

    // Feed the texture coordinate data to the shader 
    glBindBuffer(GL_ARRAY_BUFFER, mesh.tex_VBO()); 
    GLuint tex_coord_att = glGetAttribLocation(_model_shader.program(), "texCoords"); 
    glEnableVertexAttribArray(tex_coord_att); 
    glVertexAttribPointer(tex_coord_att, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); 

    // Draw mesh 
    glBindVertexArray(mesh.VAO()); 
    glDrawElements(GL_TRIANGLES, mesh.numIndices(), GL_UNSIGNED_SHORT, (void*)0); 

    // Disable attributes 
    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 

    // Release resources 
    glBindTexture(GL_TEXTURE_2D, 0); 
} 
+0

Was passiert, wenn Sie das Vertex-Array zu Beginn des Zeichenaufrufs binden, anstatt direkt vor dem Zeichnen des Objekts? – Xirema

+0

@Xirema: Das hat den Trick gemacht! Woher? – marcman

Antwort

1

Sie benötigen zu binden Vertex-Arrays zu Beginn Ihrer Funktion, nicht richtig t vor der Ziehung selbst. Das Vertex-Array ist für die Verwaltung des Status verantwortlich, der einem bestimmten Objekt [-type] zugeordnet ist, und alle Aufrufe, die eingerichtet werden (wie glVertexAttribPointer oder glEnableVertexAttribArray), werden auf diesem Vertex-Array verwaltet. Was Sie im Wesentlichen mit Ihrem alten Code gemacht haben, ist, dass Sie den Zustand für Ihr Objekt eingerichtet haben, dann zu einem völlig anderen VAO gewechselt sind, dann Zeichnung, was bedeutet, dass Model1 die Bindings und das Setup von Model2 verwendet und umgekehrt. Wenn sie nicht identische Regeln und Setups haben, ist es sehr unwahrscheinlich, dass sie beide zeichnen.

Übrigens, da VAO's Speicherzustand, die einzigen Dinge, die in Ihren Draw-Calls sein müssen, sind der Zeichenaufruf selbst, und alle Daten, die diesen Rahmen geändert. Daher sollten Sie in Betracht ziehen, etwas Zeit für das Refactoring Ihres Codes zu investieren, da die meisten dieser Einstellungen (wie die Pufferbindung) nicht Frame für Frame geändert werden.

+0

Danke für die Erklärung! Die Dokumentation ist für einen Anfänger furchtbar schwer zu verstehen – marcman

Verwandte Themen