代码之家  ›  专栏  ›  技术社区  ›  CodyT96

有人知道为什么这个特定的对象会在另一个对象的前面渲染,尽管它有z坐标吗?

  •  0
  • CodyT96  · 技术社区  · 3 年前

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

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

    monitor with screen

    以下是旋转了45度的两个相同对象:

    monitor with screen rotated 45 degrees

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

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

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

    感谢大家的帮助,谢谢。

    0 回复  |  直到 3 年前