查看: 4332|回复: 14

如何计算一个世界坐标系下的点对应的屏幕坐标,类似于OpenGL的gluProject函数

[复制链接]

该用户从未签到

发表于 2012-11-16 16:23:14 | 显示全部楼层 |阅读模式
本帖最后由 wanggang8826 于 2012-11-16 16:30 编辑

OSG中是怎么封装OpenGL的gluProject函数的?

该用户从未签到

发表于 2014-4-24 16:13:08 | 显示全部楼层
慢慢游86 发表于 2013-12-20 19:06
我也是那样子算的,感觉有点不对
我的情况是,先是在XY平面上绕原点画半径为500的圆(世界坐标),在相机 ...

如果你是从屏幕坐标反算世界坐标,应该是乘以逆矩阵就可以了

该用户从未签到

发表于 2012-11-16 17:14:22 | 显示全部楼层
用VPW矩阵,V 表示摄像机的观察矩阵(View Matrix),P 表示投影矩阵(Projection Matrix),W 表示视口矩阵(Window Matrix)
  windowCoord = worldCoord * VM * PM * WM

该用户从未签到

 楼主| 发表于 2012-11-17 10:23:43 | 显示全部楼层
小手一拿 发表于 2012-11-16 17:14
用VPW矩阵,V 表示摄像机的观察矩阵(View Matrix),P 表示投影矩阵(Projection Matrix),W 表示视口矩阵(Wi ...

谢谢!我尝试了一下,计算出的windowCoord中的(x,y)是正确的,我想问问windowCoord.z表示的是什么?它不是0也不是1。

该用户从未签到

发表于 2012-11-19 10:37:14 | 显示全部楼层
简单来说,windowCoord.z就是线性的深度值

该用户从未签到

 楼主| 发表于 2012-11-20 11:02:42 | 显示全部楼层
array 发表于 2012-11-19 10:37
简单来说,windowCoord.z就是线性的深度值

“线性的深度值”怎理解啊?能不能简单说一下啊?

该用户从未签到

发表于 2012-11-22 17:08:43 | 显示全部楼层
简单说,因为实际的深度不是线性的。。。不过您可以把它当成是深度值来做自定义的遮挡查询就是了

该用户从未签到

发表于 2013-12-18 19:13:01 | 显示全部楼层
请问下楼主是怎么求得 我求的 怎么不对啊

该用户从未签到

发表于 2013-12-19 20:21:26 | 显示全部楼层
看到在OpenGL中可以用glReadPixel得到深度缓冲区中对应的值,在OSG中有没有类似的函数也可以求得对应的深度值呢,我好想没看见呀

该用户从未签到

发表于 2013-12-20 10:23:44 | 显示全部楼层
wanggang8826 发表于 2012-11-17 10:23
谢谢!我尝试了一下,计算出的windowCoord中的(x,y)是正确的,我想问问windowCoord.z表示的是什么?它不 ...

我想问一下,你是怎么求得的,是

  1. viewer.getCamera()->getViewMatrix() *
  2. viewer.getCamera()->getProjectMatrix() *
  3. viewer.getCamera()->getViewPort()->computeWindowMatrix();
复制代码

这样子求得的么

我这样子求出来的有问题,从屏幕的左下角到右上角,得到的世界坐标基本上就没什么变化

该用户从未签到

 楼主| 发表于 2013-12-20 10:24:06 | 显示全部楼层
慢慢游86 发表于 2013-12-19 20:21
看到在OpenGL中可以用glReadPixel得到深度缓冲区中对应的值,在OSG中有没有类似的函数也可以求得对应的深度 ...

我也不知道,貌似没有,就是按照二楼的方法自己计算的,获取相机的MVP矩阵,乘以点坐标

该用户从未签到

 楼主| 发表于 2013-12-20 10:34:15 | 显示全部楼层
慢慢游86 发表于 2013-12-20 10:23
我想问一下,你是怎么求得的,是

这样子求得的么

osg::Matrix vpw=viewer.getCamera()->getViewMatrix() * viewer.getCamera()->getProjectMatrix() *viewer.getCamera()->getViewPort()->computeWindowMatrix();

osg::Vec3 p(0, 0, 4);//世界坐标,Z轴上的一点
osg::Vec3 windowCoord=p*vpw;//p点对应的窗口坐标(windowCoord.x, windowCoord.y),windowCoord.z表示深度[0,1]

该用户从未签到

发表于 2013-12-20 19:06:08 | 显示全部楼层
wanggang8826 发表于 2013-12-20 10:34
osg::Matrix vpw=viewer.getCamera()->getViewMatrix() * viewer.getCamera()->getProjectMatrix() *view ...

我也是那样子算的,感觉有点不对
我的情况是,先是在XY平面上绕原点画半径为500的圆(世界坐标),在相机的视口中我可以看见这整个圆,也就是XY的范围至少是在[-500, 500]之间吧,但是我通过获得屏幕四个角上的点,然后计算他们的世界坐标,得到的结果就没差别,就差个零点几的。搞得我都想认为是单位不对了,世界坐标的单位不是米么

该用户从未签到

 楼主| 发表于 2013-12-23 10:00:56 | 显示全部楼层
慢慢游86 发表于 2013-12-20 19:06
我也是那样子算的,感觉有点不对
我的情况是,先是在XY平面上绕原点画半径为500的圆(世界坐标),在相机 ...

我想你是搞反了,帖子是讨论如何从一个世界坐标点转换成屏幕坐标点,但是从你的描述中“通过获得屏幕四个角上的点,然后计算他们的世界坐标”,你是从屏幕坐标反算世界坐标,那个公式自然不对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表