在QT中使用QOpenGLWidget时,鼠标点击读取像素深度glReadPixels遇到的问题

需求和问题

通过鼠标点击获取某一像素的深度值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();

获得

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值