简体   繁体   中英

OpenGL renders in release mode but not debug mode

Right now I'm writing a basic OpenGL wrapper using Visual Studio 2015, and I'm running into this really strange phenomenon where my cubes are not rendered when I build and run in Debug mode. In Release mode, however, everything seems to render perfectly fine.

As is notable, the program does run in Debug mode, and it does clear the screen with the green color I have set. So it appears that OpenGL is working to a certain extent. The problem is that it is not rendering my cube mesh as it does in Release mode. I have confirmed through debugging that my assets (shaders and image files) are being loaded properly in Debug mode, so that does not appear to be the issue.

Code-wise, here are the interesting parts of the program:

In Main.cpp :

renderer.Clear(0.2f, 0.3f, 0.3f, 1.0f);

for(GLuint i = 0; i < 10; ++i) {
    renderer.PushMatrix();
    renderer.Translate(cubePositions[i].x, cubePositions[i].y, cubePositions[i].z);
    renderer.Rotate(20.0f * i, glm::vec3(1.0f, 0.3f, 0.5f));
    renderer.Render(cube);
    renderer.PopMatrix();
}

window.SwapBuffers();

In Renderer.cpp :

void Renderer::updateMVP() const {
    glm::mat4 _proj = camera.GetProjectionMatrix();
    glm::mat4 _view = camera.GetViewMatrix();
    glm::mat4 _model = model.top();
    glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "projection"), 1, GL_FALSE, glm::value_ptr(_proj));
    glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "view"), 1, GL_FALSE, glm::value_ptr(_view));
    glUniformMatrix4fv(glGetUniformLocation(shader.GetProgram(), "model"), 1, GL_FALSE, glm::value_ptr(_model));
}

void Renderer::Clear(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) const {
    glClearColor(red, green, blue, alpha);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Renderer::Render(const Mesh& mesh) const {
    shader.Use();
    updateMVP();
    mesh.Render(this->shader);
}

In Mesh.cpp :

void Mesh::Render(const Shader& shader) const {
    assert(this->VAO);

    for (GLuint i = 0; i < this->textures.size(); ++i) {
        shader.BindTexture(this->textures[i], i);
    }

    glBindVertexArray(this->VAO);
    glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    for (GLuint i = 0; i < this->textures.size(); ++i) {
        shader.UnbindTexture(i);
    }
}

I am using the following (static) libraries: GLEW , GLFW , SOIL2

I am also using the header-only library: GLM

When building the static libraries, I ensured they were all built using Visual Studio's v140 Platform toolset. I built each static library in both Debug and Release. The Debug versions were all built using the /MDd CRT, and the Release versions were built using the /MD CRT.

All of my code and project config files are open source here: Github

Any help is greatly appreciated! Thanks.

调试模式/发布模式

The problem:

I feel silly. I placed a bunch of glError checks, and I managed to pinpoint the problem down to my function generating the cube mesh where I was depending on RVO. But with visual studio RVO is apparently only done in Release mode and not Debug mode. So my mesh's destructor was being called as soon as it was created, removing it from GPU memory before it could be rendered.

The solution:

Always always always follow the Rule of 5 . The solution was to simply add copy and move constructors / assignment operators to my Mesh and Texture classes to prevent the deallocation of their managed resources.

Mesh destructor:

Mesh::~Mesh() {
    glDeleteVertexArrays(1, &this->VAO);
    glDeleteBuffers(1, &this->VBO);
    glDeleteBuffers(1, &this->EBO);
}

Cube creation function:

sr::Mesh createCube() {
    sr::Mesh mesh;
    mesh.AddTexture(sr::Texture("wood_container.jpg", "Texture1"));
    mesh.AddTexture(sr::Texture("awesome_face.png", "Texture2"));

    glm::vec3 p1(-0.5f, -0.5f,  0.5f);
    glm::vec3 p2( 0.5f, -0.5f,  0.5f);
    glm::vec3 p3( 0.5f,  0.5f,  0.5f);
    glm::vec3 p4(-0.5f,  0.5f,  0.5f);
    glm::vec3 p5( 0.5f, -0.5f, -0.5f);
    glm::vec3 p6(-0.5f, -0.5f, -0.5f);
    glm::vec3 p7(-0.5f,  0.5f, -0.5f);
    glm::vec3 p8( 0.5f,  0.5f, -0.5f);

    glm::vec2 tc00(0.0f, 0.0f);
    glm::vec2 tc01(0.0f, 1.0f);
    glm::vec2 tc10(1.0f, 0.0f);
    glm::vec2 tc11(1.0f, 1.0f);

    glm::vec3 norm;

    GLuint v1, v2, v3, v4, v5, v6, v7, v8;

    // Front
    norm = glm::vec3(0.0f, 0.0f, 1.0f);
    v1 = mesh.AddVertex(p1, norm, tc00);
    v2 = mesh.AddVertex(p2, norm, tc10);
    v3 = mesh.AddVertex(p3, norm, tc11);
    v4 = mesh.AddVertex(p4, norm, tc01);
    mesh.AddTriangle(v1, v2, v3);
    mesh.AddTriangle(v1, v3, v4);

    // Back
    norm = glm::vec3(0.0f, 0.0f, -1.0f);
    v5 = mesh.AddVertex(p5, norm, tc00);
    v6 = mesh.AddVertex(p6, norm, tc10);
    v7 = mesh.AddVertex(p7, norm, tc11);
    v8 = mesh.AddVertex(p8, norm, tc01);
    mesh.AddTriangle(v5, v6, v7);
    mesh.AddTriangle(v5, v7, v8);

    // Right
    norm = glm::vec3(1.0f, 0.0f, 0.0f);
    v2 = mesh.AddVertex(p2, norm, tc00);
    v5 = mesh.AddVertex(p5, norm, tc10);
    v8 = mesh.AddVertex(p8, norm, tc11);
    v3 = mesh.AddVertex(p3, norm, tc01);
    mesh.AddTriangle(v2, v5, v8);
    mesh.AddTriangle(v2, v8, v3);

    // Left
    norm = glm::vec3(-1.0f, 0.0f, 0.0f);
    v6 = mesh.AddVertex(p6, norm, tc00);
    v1 = mesh.AddVertex(p1, norm, tc10);
    v4 = mesh.AddVertex(p4, norm, tc11);
    v7 = mesh.AddVertex(p7, norm, tc01);
    mesh.AddTriangle(v6, v1, v4);
    mesh.AddTriangle(v6, v4, v7);

    // Top
    norm = glm::vec3(0.0f, 1.0f, 0.0f);
    v4 = mesh.AddVertex(p4, norm, tc00);
    v3 = mesh.AddVertex(p3, norm, tc10);
    v8 = mesh.AddVertex(p8, norm, tc11);
    v7 = mesh.AddVertex(p7, norm, tc01);
    mesh.AddTriangle(v4, v3, v8);
    mesh.AddTriangle(v4, v8, v7);

    // Bottom
    norm = glm::vec3(0.0f, -1.0f, 0.0f);
    v6 = mesh.AddVertex(p6, norm, tc00);
    v5 = mesh.AddVertex(p5, norm, tc10);
    v2 = mesh.AddVertex(p2, norm, tc11);
    v1 = mesh.AddVertex(p1, norm, tc01);
    mesh.AddTriangle(v6, v5, v2);
    mesh.AddTriangle(v6, v2, v1);

    mesh.Build();

    return mesh;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM