Qopenglwidget和GlreadPixels和深度缓冲区
QOpenGLWidget and glReadPixels and depth buffer
作为我使用qopenglwidget在qt中制作的3D网格查看器的一部分,我需要为用户提供单击模型中的节点的能力。为了将选择仅限于可见节点,我试图在选择算法中包括GlreadPixels(gl_depth_component)。
我的问题是GlreadPixels(深度)始终返回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;
我的普通3D渲染工作正常,我的initializeGL()
功能中有glEnable(GL_DEPTH_TEST)
。目前,我不使用任何精美的VBO或VAO。FaceMeshQualityColor
和triVertices
都是数据类型QVector<QVector3D>
。我目前的面部渲染遵循以下进展:
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(深度)问题是否与我对深度缓冲区的处理有关?
我是否需要"激活"深度缓冲区才能在调用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();
}
};
相关文章:
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- 从OpenGL应用程序中提取颜色/深度缓冲区
- 为什么为什么偏离gl_fragcoord.z偏离深度缓冲区
- DirectX-启用深度缓冲区后没有任何渲染
- OpenGL - 深度缓冲区在渲染半透明立方体时剪切掉不应该剪切的面
- C++深度缓冲区Oculus Rift DK2 VR HMD
- 多采样框架渲染对象和深度缓冲区
- GlReadPixel始终从深度缓冲区0中获取
- 有没有办法访问OpenGL的深度缓冲区
- Qopenglwidget和GlreadPixels和深度缓冲区
- 深度缓冲区的绝对距离
- 弄乱了OpenGL深度缓冲区
- OpenGL:只获取模具缓冲区而不获取深度缓冲区
- 使用帧缓冲区将深度缓冲区渲染到纹理中
- 是否可以在opengl中使用深度缓冲区渲染3D纹理
- Direct2D深度缓冲区
- OpenGL ES深度缓冲区渲染(iOS模拟器与真实设备)
- 深度缓冲区未正确渲染
- 将深度呈现缓冲区复制到深度缓冲区
- 为什么我们必须在渲染过程中清除 OpenGL 中的深度缓冲区