【问题标题】:QOpenGLWidget and glReadPixels and depth bufferQOpenGLWidget 和 glReadPixels 和深度缓冲区
【发布时间】:2016-06-20 07:08:29
【问题描述】:

作为我在 QT 中使用 QOpenGLWidget 制作的 3D 网格查看器的一部分,我需要让用户能够单击模型中的节点。为了将选择限制为仅可见节点,我尝试在我的选择算法中包含 glReadPixels (GL_DEPTH_COMPONENT)。

我的问题是 glReadPixels(depth) 总是返回 0。下面代码中的所有错误输出也返回 0。 glReadPixels(red) 返回正确的值:

    GLenum err = GL_NO_ERROR;
    QTextStream(stdout) << "error before reading gl_red = " << err << endl;
    GLfloat winX, winY, myred, mydepth;
    winX = mousex;
    winY = this->height() - mousey;
    glReadPixels(winX,winY,1,1,GL_RED,GL_FLOAT, &myred);
    QTextStream(stdout) << "GL RED = " << myred << endl;
    err =  glGetError();
    QTextStream(stdout) << "error after reading gl_red = " << err << endl;
    glReadPixels(winX,winY,1,1,GL_DEPTH_COMPONENT,GL_FLOAT, &mydepth);
    QTextStream(stdout) << "GL_DEPTH_COMPONENT = " << mydepth << endl;
    err =  glGetError();
    QTextStream(stdout) << "error after reading gl_depth = " << err << endl;

我的正常 3D 渲染工作正常,我的 glEnable(GL_DEPTH_TEST) 函数中有 initializeGL()。目前我没有使用任何花哨的 VBO 或 VAO。 FaceMeshQualityColortriVertices 都是数据类型 QVector&lt;QVector3D&gt;。我当前的面部渲染遵循以下进程:

shader = shaderVaryingColor;
shader->bind();
shader->setAttributeArray("color", FaceMeshQualityColor.constData());
shader->enableAttributeArray("color");
shader->setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
shader->setAttributeArray("vertex", triVertices.constData());
shader->enableAttributeArray("vertex");
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1,1);
glDrawArrays(GL_TRIANGLES, 0, triVertices.size());
glDisable(GL_POLYGON_OFFSET_FILL);
shader->disableAttributeArray("vertex");
shader->disableAttributeArray("color");
shader->release();

在我的主文件中,我明确地将我的 OpenGL 版本设置为具有 glReadPixels(GL_DEPTH_COMPONENT) 功能的东西(相对于 OpenGL ES 2.0):

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QSurfaceFormat format;
    format.setVersion(2, 1);
    format.setProfile(QSurfaceFormat::CoreProfile);
    format.setDepthBufferSize(32);
    QSurfaceFormat::setDefaultFormat(format);
    MainWindow w;
    w.showMaximized();
    return a.exec();
}

我的 glReadPixels(depth) 问题是否与我对深度缓冲区的处理有关?

在调用 glReadPixels 之前,我是否需要“激活”深度缓冲区才能读取它?还是我需要让我的顶点着色器将深度位置显式写入其他对象?

【问题讨论】:

    标签: c++ qt opengl


    【解决方案1】:

    QOpenGLWidget 在底层 FBO 中工作,如果启用了多重采样,您不能简单地从该 FBO 读取深度组件。最简单的解决方案是将样本设置为零,因此您的代码将如下所示:

    QSurfaceFormat format;
    format.setVersion(2, 1);
    format.setProfile(QSurfaceFormat::CoreProfile);
    format.setDepthBufferSize(32);
    
    format.setSamples(0);
    
    QSurfaceFormat::setDefaultFormat(format);
    

    或者您也可以使用多重采样,但在没有多重采样的情况下需要一个额外的 FBO,其中可以复制深度缓冲区。

    class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
    {
    //
    // OTHER WIDGET RELATED STUFF
    //
    QOpenGLFramebufferObject* mFBO = nullptr;
    
    MyGLWidget::paintGL()
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
      //
      // DRAW YOUR SCENE HERE!
      //
    
      QOpenGLContext *ctx = QOpenGLContext::currentContext();
    
      // FBO must be re-created! is there a way to reset it?
      if(mFBO) delete mFBO;
    
      QOpenGLFramebufferObjectFormat format;
      format.setSamples(0);
      format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
      mFBO = new QOpenGLFramebufferObject(size(), format);
    
      glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->defaultFramebufferObject());
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO->handle());
      ctx->extraFunctions()->glBlitFramebuffer(0, 0, width(), height(), 0, 0, mFBO->width(), mFBO->height(), GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
    
      mFBO->bind(); // must rebind, otherwise it won't work!
    
      float mouseDepth = 1.f;
      glReadPixels(mouseX, mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouseDepth);
    
      mFBO->release();
    }
    };
    

    【讨论】:

      猜你喜欢
      • 2011-09-27
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      相关资源
      最近更新 更多