我的代码应该渲染立方体的正面,而不是显示背面。为什么?

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

我正在渲染这个立方体,它应该显示立方体的正面,但它显示背面(绿色)。我该如何解决这个问题?我已经坐了几个小时试图解决这个问题,但没有任何帮助。我正在尝试各种方法,例如更改三角形的渲染顺序,但也无济于事。谢谢你的帮助。这是我的代码。

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;
}

这是立方体的样子:

您目前正在使用 glEnable(GL_DEPTH_TEST)glDepthFunc(GL_LESS),这意味着只有具有较小 z(或 深度)组件的片段被渲染渲染重叠的三角形时。由于您的顶点位置是用 back-face 定义的 z 坐标小于 front-face,所有 front-face 片段都将被忽略(因为它们的 z 坐标更大).

解决方案是:

  • 使用 glDepthFunc(GL_GREATER) 而不是 glDepthFunc(GL_LESS)(考虑到您的顶点有 z <= 0.0 并且深度缓冲区被清除为 0.0,这在您的情况下可能不起作用)
  • 修改您的顶点位置,使 front-face 个三角形的 z 分量小于 back-face 个三角形。

我相信在使用矩阵变换时,较小的 z 组件通常表示片段 更接近 相机,这就是为什么 glDepthFunc(GL_LESS)经常使用。