在渲染对象时启用GL_DEPTH_TEST时出现问题,发生了以下情况:

GL_CULL_FACE在那一个上被禁用。

它仅在透 View 中发生!有人知道发生了什么吗?

我为此使用Qt 4.8。

当然,如果禁用深度测试,它看起来不错,但是对象按预期的错误方式覆盖。

更新

我用以下方法创建投影矩阵:

ProjectionMatrix.setToIdentity();
ProjectionMatrix.perspective(45, float(width) / float(height), 0, 20.0);

宽度和高度与视口(viewport)大小有关。

这是我绘制场景的代码:
void GLWidget::paintGL()
{
    glClearColor(0.4765625, 0.54296875, 0.6171875, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    editor->setUniformValue("projectMatrix", controller->getProjectionMatrix());
    editor->setUniformValue("viewMatrix", controller->getViewMatrix());

    /** Dibujemos los grids **/
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    for (int i=0; i<3; i++)
    {
        if ((front && i==1) || (side && i==2) || (i==0))
        {
            editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
            editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
            editor->setUniformValue("texture", textureon);

            glEnableClientState(GL_VERTEX_ARRAY);
            editor->enableAttributeArray("vertices");
            Objects[i].vertexbuffer->bind();
            editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
            glDisableClientState(GL_VERTEX_ARRAY);

            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            editor->enableAttributeArray("texuv");
            Objects[i].uvbuffer->bind();
            editor->setAttributeBuffer ("texuv", GL_FLOAT, 0, 2);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);

            glEnableClientState(GL_NORMAL_ARRAY);
            editor->enableAttributeArray("normals");
            Objects[i].normalbuffer->bind();
            editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
            glDisableClientState(GL_NORMAL_ARRAY);

            Objects[i].elementbuffer->bind();
            glBindTexture(GL_TEXTURE_2D, Objects[i].texture);
            glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
        }
    }

    /** Ahora para las operaciones especificas de cada objeto **/
    glEnable(GL_DEPTH_TEST);
    //glEnable(GL_CULL_FACE);
    for (int i=3; i<Objects.size(); i++)
    {
        //Objects[i].modelMatrix.scale(1.0, 1.0, 1.0);
        //Objects[i].modelMatrix.rotate(1.0, 0.0, 1.0, 0.0);

        editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
        editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
        editor->setUniformValue("texture", textureoff);
        editor->setUniformValue("diffuseColor", Objects.at(i).diffuseColor);
        editor->setUniformValue("shininess", Objects.at(i).shininess);
        editor->setUniformValue("hardness", Objects.at(i).hardness);
        editor->setUniformValue("LPos1", Objects.at(i).L1Pos);
        editor->setUniformValue("LPos2", Objects.at(i).L2Pos);
        editor->setUniformValue("LPos3", Objects.at(i).L3Pos);
        editor->setUniformValue("LPos4", Objects.at(i).L4Pos);

        glEnableClientState(GL_VERTEX_ARRAY);
        editor->enableAttributeArray("vertices");
        Objects[i].vertexbuffer->bind();
        editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
        glDisableClientState(GL_VERTEX_ARRAY);

        glEnableClientState(GL_NORMAL_ARRAY);
        editor->enableAttributeArray("normals");
        Objects[i].normalbuffer->bind();
        editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
        glDisableClientState(GL_NORMAL_ARRAY);

        Objects[i].elementbuffer->bind();
        glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
    }
}

简而言之,我首先根据相机所面向的位置绘制网格,以提供类似于Blender的功能。然后,我绘制所有对象。我正在使用索引VBO来实现这一目标。

我也用CCW绘制它们,我99%确信以这种方式将三角形传递给OpenGL。

最佳答案

[EDIT透 View ]投影矩阵的Near值为零。这导致所有深度值在透 View 划分后等于(.xyz / .w)。 @Raxvan显然有正确的想法。试试这个...

ProjectionMatrix.perspective(45, float(width) / float(height), 0.01, 20.0);

当然,对于大型场景,您需要较大的深度范围,但是如果将其设置得太大,则最终会发生Z角战斗,即距离不同的片段仍具有相同的深度值,并且栅格化后的第一个获胜者(这似乎是您遇到的问题)。我试图使我的深度范围不超过10,000倍。

如果场景很大,则可能需要考虑其他方法。首先,请使用精度更高的深度缓冲区。如果这还不够,请使用两个投影矩阵,然后将场景分为近景和远景。如果对象与边界相交,有时会引起问题。这里是一些相关的链接...
  • https://www.opengl.org/wiki/Depth_Buffer_Precision
  • http://outerra.blogspot.com.au/2012/11/maximizing-depth-buffer-range-and.html
  • 关于c++ - 深度测试的结果很奇怪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22291120/

    10-15 06:39