gpt4 book ai didi

c++ - 无法使用 QOpenGLWidget 读取 GL_DEPTH_COMPONENT

转载 作者:太空狗 更新时间:2023-10-29 20:37:16 24 4
gpt4 key购买 nike

我正在为 QOpenGLWidget 中的 3D 对象实现一个简单的点击选择。为此,我需要将 2D 鼠标坐标转换为 3D 世界空间。我以前使用 QGLWidget 实现了整个过程。使用 QOpenGLWidget,我无法读取像素的 GL_DEPTH_COMPONENT:

float z;
glReadPixels(pixel.x, height - pixel.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);

'z' 始终为 0。为了确保我的像素坐标正确,我尝试接收 GL_RGBA 值:

float rgba[4];
glReadPixels((int)p_temp.x(), (int) (viewport[3] - p_temp.y()), 1, 1, GL_RGBA, GL_FLOAT, rgba);

,返回正确的像素颜色。为了让它起作用,我必须将像素坐标的域从本地坐标更改为父坐标。这可能是由于 GL_VIEWPORT 的设置对应于父小部件的大小:

int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);

对于 QGLWidget 这返回:{0, 0, this->width(), this->height()}

对于 QOpenGLWidget 这返回:{0, 0, this->parent()->width(), this->parent()->height()}

顺便说一句,我的 OpenGL 版本是 4.5,使用带有 GL_DEPTH_COMPONENT 的 glReadPixels 时我没有收到任何 OpenGL 错误

现在,我有点不知道我可能遗漏了什么。有什么想法吗?

最佳答案

QOpenGLWidget 作用于底层的帧缓冲对象 (FBO),如果启用了多重采样,您不能简单地从该 FBO 读取深度分量。最简单的解决方案是将样本设置为零,因此您的代码将如下所示:

QSurfaceFormat format;
format.setVersion(2, 1);
format.setProfile(QSurfaceFormat::CoreProfile);

format.setSamples(0);

QSurfaceFormat::setDefaultFormat(format);

或者您可以使用像 format.setSamples(4) 这样的多重采样,但是在没有多重采样的情况下需要一个额外的 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, 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();
}
};

关于c++ - 无法使用 QOpenGLWidget 读取 GL_DEPTH_COMPONENT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35303918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com