My code should render the front of a cube, but instead shows the back. Why?

Viewed 105

I'm rendering this cube and it should show the front of the cube but instead it shows the back (green color). How do i solve this? I've been sitting for a couple of hours trying to fix this but nothing helped. I was trying various things like changing the order in which the triangles are rendered and it didn't help either. Thanks for any help. Here's my code.

float vertices[] =
{
    //front
    -0.5f, -0.5f, 0.0f,     1.f, 0.0f, 0.5f,
    0.5f, -0.5f, 0.0f,      1.f, 0.0f, 0.5f,
    0.5f, 0.5f, 0.0f,       1.f, 0.0f, 0.5f,
    -0.5f, 0.5f, 0.0f,      1.f, 0.0f, 0.5f,

    //back
    -0.5f/2, -0.5f/2, -0.5f,        0.0f, 1.f, 0.0f,
    0.5f/2, -0.5f/2, -0.5f,         0.0f, 1.f, 0.0f,
    0.5f/2, 0.5f/2, -0.5f,          0.0f, 1.f, 0.0f,
    -0.5f/2, 0.5f/2, -0.5f,         0.0f, 1.f, 0.0f,
};

unsigned int indices[] =
{
    //front
    0, 2, 3,
    0, 1, 2,
    //back
    4, 6, 7,
    4, 5, 6,
    //top
    3, 6, 2,
    3, 7, 6,
    //bottom
    0, 1, 5,
    0, 5, 4,
    //left
    3, 0, 4,
    3, 4, 7,
    //right
    1, 2, 5,
    2, 6, 5
    
};

int main()
{
    if (!glfwInit())
    {
        std::cout << "ERROR" << std::endl;
        return -1;
    }

    int width = 640;
    int height = 480;

    window = glfwCreateWindow(width, height, "OPENGL", NULL, NULL);

    if (!window)
    {
        std::cout << "ERROR: WINDOW" << std::endl;
    }

    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    if (glewInit() != GLEW_OK)
    {
        std::cout << "ERROR: GLEW" << std::endl;
    }

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);


    std::cout << "OpenGL " << glGetString(GL_VERSION) << std::endl;

    VertexArray va1;

    VertexBuffer vb1(vertices, sizeof(vertices), GL_STATIC_DRAW);
    IndexBuffer ib1(indices, sizeof(indices), GL_STATIC_DRAW);

    va1.linkAttrib(vb1, 0, 3, GL_FLOAT, 6 * sizeof(float), 0);
    va1.linkAttrib(vb1, 1, 3, GL_FLOAT, 6 * sizeof(float), 3 * sizeof(float));

    ShaderSources sources = parseShader("basic.shader");
    unsigned int program = createShaderProgram(sources.vertexSource, sources.fragmentSource);
    glUseProgram(program);

    while (!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(unsigned int), GL_UNSIGNED_INT, nullptr);
        glfwSwapBuffers(window);

        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

And here what the cube looks like: enter image description here

1 Answers

You currently are using glEnable(GL_DEPTH_TEST) withglDepthFunc(GL_LESS), which means only fragments having a smaller z (or depth) component are rendered when rendering overlapped triangles. Since your vertex positions are defined with the back-face having a smaller z coordinate than the front-face, all front-face fragments are ignored (since their z coordinate is larger).

Solutions are:

  • Using glDepthFunc(GL_GREATER) instead of glDepthFunc(GL_LESS) (which may not work in your case, considering your vertices have z <= 0.0 and the depth buffer is cleared to 0.0)
  • Modify your vertex positions to give front-face triangles a smaller z component than back-face triangles.

I believe that when using matrix transforms, a smaller z component normally indicates the fragment is closer to the camera, which is why glDepthFunc(GL_LESS) is often used.

Related