需求和问题
通过鼠标点击获取某一像素的深度值z, 但获取的z始终为1
原因一,所见内容并非实时
参考这篇回答,可以看到必须要手动调用makecurrent()
使当前内容active(想了几个词都不知道怎么翻译比较好),在qt文档中也可以看到:
void QOpenGLWidget::makeCurrent()
Prepares for rendering OpenGL content for this widget by making the corresponding context current and binding the framebuffer object in that context.
It is not necessary to call this function in most cases, because it is called automatically before invoking paintGL().
故在mousePressEvent(QMouseEvent* event)
函数内必须手动调用才可以确保当前opengl内容所得即所见。
原因二,开启自适应高分辨率后的缩放问题
开启自适应高分辨率QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
后,qopenglwidget会进行缩放,但其内部的opengl并不会随qt进行缩放,此时鼠标点击所获得的屏幕坐标需要根据缩放比例进行处理转化为opengl坐标,才能获得准确的像素深度值,代码如下。
在mousePressEvent
中:
void MyWidget::mousePressEvent(QMouseEvent* event) {
makeCurrent();
QPoint screenp= event->pos();
float zpos = GetDepth(screenp);
....
....
doneCurrent();
}
获取深度值GetDepth
:
// screenp: 通过mousePressEvent获得的当前鼠标点击的屏幕点
float MyWidget::GetDepth(QPoint screenp) {
//MyWidget宽、高
double w = this->width();
double h = this->height();
// 待读取的深度值
float zpos = 0.0;
// qopenglwidget内部的opengl不随qt缩放,读取像素需手动从qt屏幕坐标转成opengl坐标
// opengl中y方向0点和qt屏幕中y方向0点不同
glReadPixels(screenp.x() * device_ratio, (h - screenp.y()) * device_ratio, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &zpos);
zpos = zpos * 2 - 1.0;
return zpos;
}
其中device_ratio
在main函数中通过
device_ratio = QApplication::desktop()->devicePixelRatio();
获得