C++ 片段着色器将面绘制在彼此的顶部,即使它不应该';T

C++ 片段着色器将面绘制在彼此的顶部,即使它不应该';T,c++,opengl,glfw,glm-math,C++,Opengl,Glfw,Glm Math,我正在用OpenGL编写一个简单的3D世界,可以渲染各种东西。我对OpenGL比较陌生,可能没有注意到什么,但是(我猜)片段着色器有一个很大的问题 它所做的是忽略z值并按索引缓冲区给定的顺序绘制面。我的意思是,例如,如果有条件索引缓冲区,它包含三角形1、三角形2和三角形3,它们在相机前面排成一行,那么三角形3,不管它的z值是多少,都会被画在其他两个的上面,因为它是最后一个。 结果,我变成了这样: 这张图片正好显示了我的意思。相对于相邻侧,正面的行为就像是透明的,但就透明度而言,它忽略了平行侧,

我正在用OpenGL编写一个简单的3D世界,可以渲染各种东西。我对OpenGL比较陌生,可能没有注意到什么,但是(我猜)片段着色器有一个很大的问题

它所做的是忽略z值并按索引缓冲区给定的顺序绘制面。我的意思是,例如,如果有条件索引缓冲区,它包含三角形1、三角形2和三角形3,它们在相机前面排成一行,那么三角形3,不管它的z值是多少,都会被画在其他两个的上面,因为它是最后一个。

结果,我变成了这样:

这张图片正好显示了我的意思。相对于相邻侧,正面的行为就像是透明的,但就透明度而言,它忽略了平行侧,因为它们是按这样的顺序绘制的

我的相机代码:

PCamera::PCamera(GLFWwindow* projectWindow, float windowWidth, float windowHeight)
{
    window = projectWindow;
    wWidth = windowWidth;
    wHeight = windowHeight;

    Position = glm::vec3(0.f, 0.f, -10.f);
    Rotation = glm::vec3(0.f, glm::pi<float>(), 0.f);

    if (glfwRawMouseMotionSupported())
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

    glfwGetCursorPos(window, &xposnormal, &yposnormal);
}

PCamera::~PCamera()
{
}

glm::mat4 PCamera::NavigateCamera()
{   
    double xpos, ypos;
    int state;

    glfwGetCursorPos(window, &xpos, &ypos);

    state = glfwGetKey(window, GLFW_KEY_ESCAPE);
    if (state == GLFW_PRESS) 
    { 
        bMouseControl = false; 
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
    }
    state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
    if ((state == GLFW_PRESS) && (bMouseControl == false))
    { 
        bMouseControl =  true;
        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); 
        glfwGetCursorPos(window, &xposnormal, &yposnormal);
    }

    if (bMouseControl)
    {
        glfwGetCursorPos(window, &xpos, &ypos);
        
        Rotation.x += (float)(yposnormal - ypos) / -300.f;
        Rotation.y += (float)(xposnormal - xpos) / -300.f;

        glfwSetCursorPos(window, xposnormal, yposnormal);
    }
    
    glm::mat4 RTSMatrix =   glm::rotate(UnitMatrix, Rotation.x, glm::vec3(1.f, 0.f, 0.f)) * glm::rotate(UnitMatrix, Rotation.y, glm::vec3(0.f, 1.f, 0.f));

    glm::vec3 DeltaPosition(0.f, 0.f, 0.f);

    state = glfwGetKey(window, GLFW_KEY_W);
    if (state == GLFW_PRESS)        DeltaPosition.z += 0.01f;

    state = glfwGetKey(window, GLFW_KEY_S);
    if (state == GLFW_PRESS)        DeltaPosition.z -= 0.01f;

    state = glfwGetKey(window, GLFW_KEY_A);
    if (state == GLFW_PRESS)        DeltaPosition.x += 0.01f;

    state = glfwGetKey(window, GLFW_KEY_D);
    if (state == GLFW_PRESS)        DeltaPosition.x -= 0.01f;

    state = glfwGetKey(window, GLFW_KEY_LEFT_SHIFT);
    if (state == GLFW_PRESS)        DeltaPosition.y -= 0.01f;

    state = glfwGetKey(window, GLFW_KEY_SPACE);
    if (state == GLFW_PRESS)        DeltaPosition.y += 0.01f;
    
    glm::vec4 D4Position(Position, 0.f);

    glm::mat4 InverseRTSMatrix = glm::rotate(UnitMatrix, -Rotation.y, glm::vec3(0.f, 1.f, 0.f)) * glm::rotate(UnitMatrix, -Rotation.x, glm::vec3(1.f, 0.f, 0.f));
    D4Position -= InverseRTSMatrix*glm::vec4(DeltaPosition, 0.0);
    
    Position.x = D4Position.x;
    Position.y = D4Position.y;
    Position.z = D4Position.z;
    
    RTSMatrix = RTSMatrix * glm::translate(UnitMatrix, -Position);

    return RTSMatrix;
}

void PCamera::UpdateProjectionMatrix(float Angle, float windowWidth, float windowHeight)
{
    ProjectionMatrix = glm::perspective(Angle, (GLfloat)windowWidth / (GLfloat)windowHeight, -1.0f, 1.0f);
}
我的主执行文件的代码:

PProject::PProject(PRenderer * Renderer)
{
    ProjectRenderer = Renderer;
}

PProject::~PProject()
{
}

int PProject::Launch()
{
    GLFWwindow* window;

    if (!glfwInit())                    return -1;

    window = glfwCreateWindow(640, 480, "PhysMaker", NULL, NULL);

    if (!window) { glfwTerminate(); return -1; }

    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK)          return -1;

    float pos[] =
    {
        -0.5, -0.5, -0.5,           1.0, 0.0, 0.0,
        -0.5, -0.5,  0.5,           0.0, 1.0, 0.0,
        -0.5,  0.5,  0.5,           0.0, 0.0, 1.0,
        -0.5,  0.5, -0.5,           1.0, 0.0, 1.0,

         0.5,  0.5,  0.5,           1.0, 0.0, 1.0,
         0.5, -0.5,  0.5,           1.0, 1.0, 0.0,
         0.5, -0.5, -0.5,           1.0, 0.0, 0.0,
         0.5,  0.5, -0.5,           0.0, 1.0, 1.0,

         0.5, -0.5,  0.5,           1.0, 0.0, 0.0,
        -0.5, -0.5,  0.5,           0.0, 1.0, 0.0,
         0.5,  0.5,  0.5,           0.0, 0.0, 1.0,
        -0.5,  0.5,  0.5,           1.0, 0.0, 0.0
    };

    unsigned int ind[]
    {
        0, 1, 2,
        2, 3, 0,

        6, 5, 4,
        4, 7, 6,

        8, 9, 10,
        9, 11, 10
    };

    PShader NewShader("Source/Shaders/Vertex.shader","Source/Shaders/Fragment.shader");
    NewShader.Bind();

    glfwGetWindowSize(window, &windowWidth, &windowHeight);

    PCamera MainCamera(window, windowWidth, windowHeight);

    PObject NewObject(pos, 24, ind, 18, 0);
    ProjectRenderer->SceneObjects.insert(ProjectRenderer->SceneObjects.end(), &NewObject);

    while (!glfwWindowShouldClose(window))
    {
        glfwGetWindowSize(window, &windowWidth, &windowHeight);
        glViewport(0, 0, windowWidth, windowHeight);

        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.3f, 0.3f, 0.3f, 1.0f);

        MainCamera.UpdateProjectionMatrix(45.f, windowWidth, windowHeight);
        glm::mat4 translation = MainCamera.ProjectionMatrix * MainCamera.NavigateCamera();
        glUniformMatrix4fv(glGetUniformLocation(NewShader.Shader_ID, "u_MVP"), 1, GL_FALSE, &translation[0][0]);

        ProjectRenderer->Draw(&NewObject);

        glfwSwapBuffers(window);

        glfwPollEvents();
    }
        glfwTerminate();
        return 0;
}

片段和顶点着色器:

#FRAGMENT
#version 330 core

out vec4 color;
in vec3 vertexColor;

void main()
{
    color = vec4(vertexColor, 1.0);;
}

#VERTEX
#version 330 core

in layout(location = 0) vec3 position;
in layout(location = 1) vec3 Color;
out vec3 vertexColor;

uniform mat4 u_MVP;

void main()
{
    gl_Position = (u_MVP * vec4(position, 1.f));
    vertexColor = Color;
}
也许是透视法有问题?我应该使用深度吗?如何使用?我以前用过,但没用。好像是投影矩阵的问题。那么,怎么了?

您必须启用。如果启用了深度测试,则根据所写入样本的深度测试片段的深度。如果失败,该片段将被丢弃。
深度测试是一种全局状态。在应用程序循环之前启用一次就足够了

glEnable(GL_深度_测试);
启用深度测试后,还必须清除深度缓冲区:
(见附件)

glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);

您必须启用。但是如果我启用了深度,它根本不会渲染任何东西,我得到的只是灰色屏幕:(@NicolasIceberg我已经扩展了答案。
glClear(GL\u COLOR\u BUFFER\u BIT | GL\u depth\u BUFFER\u BIT);
)哦,谢谢你。它帮助将情况改变为稍微不同的情况(它仍然是错误的,但它是正确的)。现在向后的面总是在前面渲染。我尝试了glDepthFunc(GL_LEQUAL),但当时没有帮助all@NicolasIceberg投影矩阵错误。在透视投影时,近平面和远平面必须为正值(0ProjectionMatrix=glm::perspective(Angle,(GLfloat)windowWidth/(GLfloat)窗高,0.01f,1.0f);非常感谢您,您帮了我很多忙。我真的很感谢您的努力,我很抱歉您花了这么多时间解决我的问题。祝您玩得愉快)
#FRAGMENT
#version 330 core

out vec4 color;
in vec3 vertexColor;

void main()
{
    color = vec4(vertexColor, 1.0);;
}

#VERTEX
#version 330 core

in layout(location = 0) vec3 position;
in layout(location = 1) vec3 Color;
out vec3 vertexColor;

uniform mat4 u_MVP;

void main()
{
    gl_Position = (u_MVP * vec4(position, 1.f));
    vertexColor = Color;
}