一旦启用GL_DEPTH_TEST,就不会绘制任何内容

时间:2016-06-24 13:34:48

标签: qt opengl

只要我在下面的代码中设置glEnable(GL_DEPTH_TEST),屏幕上就会绘制除了清晰颜色之外的任何内容。

window.cpp

void Window::initializeGL() {
    makeCurrent();
    initializeOpenGLFunctions();

    glClearColor(0.0f, 0.03f, 0.2f, 1.0f);

    Shaders::initShaders();
    glEnable(GL_DEPTH_TEST);

    currentLevel.addTiles();

    viewMatrix.setToIdentity();
    viewMatrix.translate(0.0f, 0.0f, -8.0f);
    viewMatrix.rotate(45.0f, -1.0f, 0.0f, 0.0f);
}

void Window::resizeGL(int width, int height) {
    const float fov = 45.0f,
          zNear = 0.0f,
          zFar = 1000.0f;

    projectionMatrix.setToIdentity();
    projectionMatrix.perspective(fov, width / float(height), zNear, zFar);
}

void Window::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    currentLevel.setProjectionMatrix(projectionMatrix);
    currentLevel.setViewMatrix(viewMatrix);
    currentLevel.draw();
}

tile.cpp:

// Constructor with custom shader
Tile::Tile(QVector3D v1, QVector3D v2, QVector3D v3, QVector3D v4, QOpenGLShaderProgram* shaderProgram) :
    vbo(QOpenGLBuffer::VertexBuffer),
    cbo(QOpenGLBuffer::VertexBuffer),
    ibo(QOpenGLBuffer::IndexBuffer) {

    // Calculate surface normal & second set of vertices
    QVector3D surfaceNormal = QVector3D::normal(v1, v2, v3);
    QVector3D v1_n = v1 - surfaceNormal;
    QVector3D v2_n = v2 - surfaceNormal;
    QVector3D v3_n = v3 - surfaceNormal;
    QVector3D v4_n = v4 - surfaceNormal;

    // Set up rectangular mesh from given corner vectors
    vertices = {
        v1, v2, v3, v4,
        v1_n, v2_n, v3_n, v4_n
    };

    colors = {
        color1, color1, color2, color2,
        color1, color1, color2, color2
    };

    indices = {

        // Face 1
        0, 1, 2,
        2, 3, 0,

        // Face 2
        0, 4, 5,
        5, 1, 0,

        // Face 3
        4, 5, 6,
        6, 7, 4

    };

    this->shaderProgram = shaderProgram;

    cacheShaderLocations();
    createBuffers();
}

Tile::~Tile() {
    vbo.destroy();
    vao.destroy();
    ibo.destroy();
}

// Cache Uniform Locations for shaders
void Tile::cacheShaderLocations() {
    positionLocation = shaderProgram->attributeLocation("position");
    colorLocation = shaderProgram->attributeLocation("color");
    modelLocation = shaderProgram->uniformLocation("model");
    viewLocation = shaderProgram->uniformLocation("view");
    projectionLocation = shaderProgram->uniformLocation("projection");
}

// Create buffers
void Tile::createBuffers() {

    // Vertex Buffer Object
    vbo.create();
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices.constData(), vertices.size() * sizeof(QVector3D));
    vbo.release();

    // Color Buffer Object
    cbo.create();
    cbo.bind();
    cbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    cbo.allocate(colors.constData(), colors.size() * sizeof(QVector3D));
    cbo.release();

    // Index Buffer Object
    ibo.create();
    ibo.bind();
    ibo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    ibo.allocate(indices.constData(), indices.size() * sizeof(GLushort));
    ibo.release();

    // Vertex Array Object
    vao.create();

    // Setup buffer attributes
    shaderProgram->bind();
    vao.bind();
    vbo.bind();
    shaderProgram->enableAttributeArray(positionLocation);
    shaderProgram->setAttributeBuffer(positionLocation, GL_FLOAT, 0, 3, 0);
    cbo.bind();
    shaderProgram->enableAttributeArray(colorLocation);
    shaderProgram->setAttributeBuffer(colorLocation, GL_FLOAT, 0, 3, 0);
    ibo.bind();
    vao.release();

    // Release buffers & shader program
    vbo.release();
    cbo.release();
    ibo.release();
    shaderProgram->release();
}

void Tile::draw() {
    shaderProgram->bind();

    // Send uniforms to shader
    shaderProgram->setUniformValue(projectionLocation, projectionMatrix);
    shaderProgram->setUniformValue(viewLocation, viewMatrix);
    shaderProgram->setUniformValue(modelLocation, modelMatrix);

    // Draw vertices
    vao.bind();
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
    vao.release();

    shaderProgram->release();
}

至于深度缓冲区本身,根据Qt文档,它默认启用。在main.cpp中,我设置了表面格式/上下文:

  // Set OpenGL Version information
  QSurfaceFormat format;
  format.setDepthBufferSize(24);
  format.setRenderableType(QSurfaceFormat::OpenGL);
  format.setProfile(QSurfaceFormat::CoreProfile);
  format.setVersion(3,3);

当我尝试使用深度测试时,我真的不知道为什么没有画出来所以我非常感谢任何帮助。

0 个答案:

没有答案