Problem z głębokością w OpenGL/Qt

0

Zaczynam przygodę z OpenGL w Qt. Punktem wyjścia był http://qt-project.org/doc/qt-5.0/qtgui/openglwindow.html

Ja zamiast okna OpenGL zrobiłem widget umieszczony na oknie. Wszystko działa dobrze do momentu, w którym chciałem wyświetlić dwa prostokąty (ściany). Domyąlnie rysują się wszystkie ściany w kolejności ich rysowania, a nie zgodnie z głębią w przestrzeni, więc jeżeli najpierw się namaluje bliższą sciane, a potem dalszą będącą za tą bliższą, to na tle tej blizszej ściany będzie widoczna ta dalsza ściana, co jest niepożądane.

Gdzieś wyczytałem, że aby uzyskać pożądany efekt, należy wywołać funkcję "glEnable(GL_DEPTH_TEST)".
Okazuje się, że to też nie działa, raz nie wyświetla nic, a raz wyświetla jakieś dziwaczne kształty, w każdym razie to nie jest to, co chciałem.

Z interfejsu użytkownika mogę zmieniać wartości globalnych zmiennych Xrot, Yrot i Zrot, co pozwala obracać wyświetlane obiekty.

Kod programu klasy kontrolki wyświetlającej obraz:

#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>
#include <QGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>

class TestWidget : public QGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT
public:
    explicit TestWidget(QWidget *parent = 0);

    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();

    void DrawTriangle(float X1, float Y1, float Z1, float R1, float G1, float B1, float X2, float Y2, float Z2, float R2, float G2, float B2, float X3, float Y3, float Z3, float R3, float G3, float B3);
    void DrawRectangle(float X1, float Y1, float Z1, float R1, float G1, float B1, float X2, float Y2, float Z2, float R2, float G2, float B2, float X3, float Y3, float Z3, float R3, float G3, float B3, float X4, float Y4, float Z4, float R4, float G4, float B4);

    int XRot;
    int YRot;
    int ZRot;

protected:

signals:
    
public slots:
    
private:
    GLuint m_posAttr;
    GLuint m_colAttr;
    GLuint m_matrixUniform;

    QOpenGLShaderProgram *m_program;
};

#endif // TESTWIDGET_H
#include "testwidget.h"

TestWidget::TestWidget(QWidget *parent) :
    QGLWidget(parent)
{
    XRot = 0;
    YRot = 0;
    ZRot = 0;
}

void TestWidget::initializeGL()
{
    const char *vertexShaderSource =
        "attribute highp vec4 posAttr;\n"
        "attribute lowp vec4 colAttr;\n"
        "varying lowp vec4 col;\n"
        "uniform highp mat4 matrix;\n"
        "void main() {\n"
        "   col = colAttr;\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";

    const char *fragmentShaderSource =
        "varying lowp vec4 col;\n"
        "void main() {\n"
        "   gl_FragColor = col;\n"
        "}\n";

    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_colAttr = m_program->attributeLocation("colAttr");
    m_matrixUniform = m_program->uniformLocation("matrix");

    glEnable(GL_DEPTH_TEST);
}

void TestWidget::resizeGL(int w, int h)
{


}

void TestWidget::paintGL()
{
    glViewport(0, 0, width(), height());

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_program->bind();

    QMatrix4x4 matrix;
    float WW = width();
    float HH = height();
    matrix.perspective(60, WW / HH, 0.0, 100.0);

    matrix.translate(0, 0, -5);

    matrix.rotate(XRot, 1, 0, 0);
    matrix.rotate(YRot, 0, 1, 0);
    matrix.rotate(ZRot, 0, 0, 1);

    m_program->setUniformValue(m_matrixUniform, matrix);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);


    //DrawTriangle(1, 1, -1, 0, 1, 0, -1, 1, -1, 1, 0, 0, -1, -1, -1, 0, 0, 1);
    //DrawTriangle(1, 1,  1, 0, 1, 0, -1, 1,  1, 1, 0, 0, -1, -1,  1, 0, 0, 1);

/*
    DrawRectangle(
                -1,  1, -1, 0, 0, 0,
                 1,  1, -1, 1, 0, 0,
                -1, -1, -1, 0, 1, 0,
                 1, -1, -1, 1, 1, 0
                );

    DrawRectangle(
                -1,  1,  1, 0, 0, 0,
                 1,  1,  1, 1, 0, 0,
                -1, -1,  1, 0, 1, 0,
                 1, -1,  1, 1, 1, 0
                );
*/

    DrawRectangle(
                -1,  1, -1, 0, 0, 0,
                 1,  1, -1, 1, 0, 0,
                -1, -1,  1, 0, 1, 0,
                 1, -1,  1, 1, 1, 0
                );

    DrawRectangle(
                -1,  1,  1, 0, 0, 0,
                 1,  1,  1, 1, 0, 0,
                -1, -1, -1, 0, 1, 0,
                 1, -1, -1, 1, 1, 0
                );


    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);


    m_program->release();
}

void TestWidget::DrawTriangle(float X1, float Y1, float Z1, float R1, float G1, float B1, float X2, float Y2, float Z2, float R2, float G2, float B2, float X3, float Y3, float Z3, float R3, float G3, float B3)
{
    GLfloat vertices[] = {
        X1, Y1, Z1,
        X2, Y2, Z2,
        X3, Y3, Z3,
    };
    GLfloat colors[] = {
        R1, G1, B1,
        R2, G2, B2,
        R3, G3, B3
    };
    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

void TestWidget::DrawRectangle(float X1, float Y1, float Z1, float R1, float G1, float B1, float X2, float Y2, float Z2, float R2, float G2, float B2, float X3, float Y3, float Z3, float R3, float G3, float B3, float X4, float Y4, float Z4, float R4, float G4, float B4)
{
    GLfloat vertices[] = {
        X1, Y1, Z1,
        X2, Y2, Z2,
        X3, Y3, Z3,
        X4, Y4, Z4,
    };
    GLfloat colors[] = {
        R1, G1, B1,
        R2, G2, B2,
        R3, G3, B3,
        R4, G4, B4
    };
    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

Tu ewidentnie jest jakiś problem z głębią. Co może być przyczyną?

1 użytkowników online, w tym zalogowanych: 0, gości: 1