使用c ++单击OpenGL窗口时如何获取世界坐标

Posted

技术标签:

【中文标题】使用c ++单击OpenGL窗口时如何获取世界坐标【英文标题】:How to get the world coordinates when clicking on an OpenGL window with c++ 【发布时间】:2013-09-15 07:47:41 【问题描述】:

这是COpenGl Control 类,到目前为止,我一直在使用它来在 MFC 中完成我的项目。 我已经在此类上编写了许多导航功能,例如panzoom toolfixed zoom infixed zoom out 等,并且我还设法在其上渲染了图像。 在所有这些导航任务中,我都使用了鼠标事件和 opengl 窗口坐标来实现。 现在在项目的一部分中(处理在 shapefile 的帮助下注册 tiff 图像)我需要使用世界坐标: 例如,假设我放大图像并单击一个点,我需要知道我正在缩放图像的哪个像素而不是 opengl 窗口的像素。 或者假设,我放大在 opengl 中呈现的 shapefile,然后单击一个点,我需要知道我单击的点的坐标是什么,例如 (65696.5577,43995.3245) 米。

如何在 opengl 中实现这样的功能?

单击时如何获取渲染形状的世界坐标 opengl窗口没有窗口坐标?

【问题讨论】:

【参考方案1】:

我见过很多方法。

如果您只对单击的对象感兴趣,有些人已经完成了渲染过程,其中每个对象都被渲染为唯一的颜色,并且单击鼠标下方的像素。不能推荐,因为这可能不可靠,并且抗锯齿之类的东西会破坏它。如果每帧都这样做,性能不会那么高,因为 GPU 驱动程序必须等到绘制完成,然后停下来将图像交还给您,然后继续。 如果您手头有变换矩阵,您可以将鼠标光标位置转换为标准化的设备坐标(-1:左/下,0:屏幕中间,1:右/上 - 虽然我可能已经得到了上/底部混合在那里)并使用 -1 和 1 的 Z 反转变换,让您获得可以执行碰撞的射线的起点和终点。如果您使用一些统一的网格类或有办法迭代场景中的所有三角形,这很容易。 作为上述两种方法的混合,从深度缓冲区获取深度,并(您需要对其进行线性化)使用它在光线上的近点和远点之间进行插值。 遍历场景中的每个三角形,将它们转换为标准化的设备坐标,然后转换为屏幕空间,(加一,乘以屏幕宽度/高度,除以 2)然后针对屏幕空间。如果您在找到鼠标悬停的三角形时保留了世界空间坐标,请找到重心坐标并与每个顶点的位置相乘。

【讨论】:

以上是关于使用c ++单击OpenGL窗口时如何获取世界坐标的主要内容,如果未能解决你的问题,请参考以下文章

Python,Tkinter:如何在可滚动画布上获取坐标

使用 glut 函数 glutMouseFunc() 将窗口坐标转换为 3D 世界坐标

Qt 如何获取滚动窗体中鼠标点击的坐标

单击窗口时如何防止c ++程序停止?

将鼠标坐标转换为世界空间坐标

如何在按钮单击时获取 GPS 坐标? (最简单的)