首页 > 解决方案 > 任何人都知道为什么这个特定的对象被渲染在另一个对象的前面,尽管它的 z 坐标?

问题描述

我正在使用 OpenGL 重新创建 3D 的 2D 场景。我的目标是用显示器、塔、键盘和鼠标重新创建一张桌子的图像。到目前为止,我已经为监视器渲染了监视器和屏幕。显示器(灰色框)的 z 坐标最初大于纯白屏幕的 z 坐标,因为屏幕应该在它的前面。但是,当它呈现时,会发生与您期望的完全相反的情况。屏幕呈现在矩形立方体的后面。我可以告诉我何时对我的旋转矩阵应用 180 度旋转。因此,当我调整 z 坐标以使屏幕大于显示器时,它会出现在前面。但是随着 z 坐标的增加,物体应该会越来越远,所以这真的很奇怪。

这是屏幕 z 坐标大于显示器 z 坐标时的屏幕截图:

带屏幕的监视器

这是旋转 45 度的相同两个对象:

屏幕旋转 45 度的显示器

当然,这就是它应该看起来的样子,但前提是屏幕的坐标小于监视器的坐标。这里有一些相关的代码可以帮助你理解我在说什么。我留下了一些我认为不相关的代码。如果您需要我提供更多代码,请告诉我。

void uCreateScreenMesh(GLMesh& mesh) {
    GLfloat vertices[] = {
        -0.25f, 0.95f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //0
        -0.25f, 0.65f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //1
         0.25f, 0.65f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //2
         0.25f, 0.95f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f  //3
    };

    GLushort indices[] = {
        0, 1, 2,
        0, 3, 2
    };

    const GLuint floatsPerVertex = 3;
    const GLuint floatsPerColor = 4;
    const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
    mesh.nIndices = sizeof(indices) / sizeof(indices[0]);

    glGenVertexArrays(1, &mesh.vao);
    glBindVertexArray(mesh.vao);

    glGenBuffers(2, mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //create vertex attribute pointers
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
    glEnableVertexAttribArray(1);
}

void uCreateMonitorMesh(GLMesh& mesh)
{
    GLfloat vertices[] = {
        //monitor (rectangle)
        -0.3f, 1.0f, 0.75f,         0.5f, 0.5f, 0.5f, 1.0f, //0
        -0.3f, 1.0f, 0.8f,          0.5f, 0.5f, 0.5f, 1.0f, //1
        
        -0.3f, 0.6f, 0.75f,         0.5f, 0.5f, 0.5f, 1.0f, //2
        -0.3f, 0.6f, 0.8f,          0.5f, 0.5f, 0.5f, 1.0f, //3
 
         0.3f, 0.6f, 0.75f,          0.5f, 0.5f, 0.5f, 1.0f, //4
         0.3f, 0.6f, 0.8f,           0.5f, 0.5f, 0.5f, 1.0f, //5

         0.3f, 1.0f, 0.75f,          0.5f, 0.5f, 0.5f, 1.0f, //6
         0.3f, 1.0f, 0.8f,           0.5f, 0.5f, 0.5f, 1.0f  //7



        
    };

    GLushort indices[] = {
        //monitor front
        0, 2, 4,
        0, 6, 4,

        //top
        0, 1, 7,
        0, 6, 7,

        //left side
        0, 3, 1,
        0, 2, 1,

        //bottom side
        2, 3, 5,
        2, 5, 4,

        //right side
        4, 5, 6,
        4, 7, 6,

        //monitor back
        1, 3, 5,
        1, 7, 5
    };

    const GLuint floatsPerVertex = 3;
    const GLuint floatsPerColor = 4;
    const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
    mesh.nIndices = sizeof(indices) / sizeof(indices[0]);

    glGenVertexArrays(1, &mesh.vao);
    glBindVertexArray(mesh.vao);

    glGenBuffers(2, mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //create vertex attribute pointers
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
    glEnableVertexAttribArray(1);
}

void uRender()
{
    //enable z-depth
    glEnable(GL_DEPTH_TEST);

    //clear frame and z buffers
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glm::mat4 scale = glm::scale(glm::vec3(1.2f, 1.2f, 1.2f));
    glm::mat4 rotation = glm::rotate(glm::radians(0.f), glm::vec3(0.0f, 1.0f, 0.0f));
    glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));

    glm::mat4 model = translation * rotation * scale;

    glm::mat4 view = glm::translate(glm::vec3(0.0f, 0.0f, -3.5f));

    glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);

    glUseProgram(programId);

    GLint modelLoc = glGetUniformLocation(programId, "model");
    GLint viewLoc = glGetUniformLocation(programId, "view");
    GLint projLoc = glGetUniformLocation(programId, "projection");

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glBindVertexArray(screenMesh.vao);
    glDrawElements(GL_TRIANGLES, screenMesh.nIndices, GL_UNSIGNED_SHORT, NULL);

    glBindVertexArray(monitorMesh.vao);
    glDrawElements(GL_TRIANGLES, monitorMesh.nIndices, GL_UNSIGNED_SHORT, NULL);
    
    

    glBindVertexArray(0);
    glfwSwapBuffers(window);
}

我尝试更改顶点数组对象的绑定顺序,但正如我所料,这并没有改变任何东西。

感谢所有帮助,谢谢。

标签: c++openglgraphics3d

解决方案


推荐阅读