Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QOpenGLWidget和glReadPixels及深度缓冲区_C++_Qt_Opengl - Fatal编程技术网

C++ QOpenGLWidget和glReadPixels及深度缓冲区

C++ QOpenGLWidget和glReadPixels及深度缓冲区,c++,qt,opengl,C++,Qt,Opengl,作为我使用QOpenGLWidget在QT中制作的3D网格查看器的一部分,我需要为用户提供单击模型内节点的功能。为了将选择仅限于可见节点,我尝试在选择算法中包含glReadPixels(GLU深度分量) 我的问题是glReadPixels(depth)总是返回0。下面代码中的所有错误输出也返回0。glReadPixels(红色)返回正确的值: GLenum err = GL_NO_ERROR; QTextStream(stdout) << "error before

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

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

    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;
在我的主文件中,我显式地将我的OpenGL版本设置为具有glReadPixels(GL_DEPTH_组件)功能的版本(与OpenGL ES 2.0相反):

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


在调用glReadPixels之前,我是否需要“激活”深度缓冲区以便能够从中读取?或者我需要让我的顶点着色器显式地将深度位置写入其他对象吗?

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();
}
};
QSurfaceFormat format;
format.setVersion(2, 1);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setDepthBufferSize(32);

format.setSamples(0);

QSurfaceFormat::setDefaultFormat(format);
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();
}
};