关于OpenGL的投影函数gluProject

在使用OpenGL进行三维建模工作的时候,gluProject无疑是必须使用的最重要的函数之一,但是我在很长一段时间内一直没有弄明白这个函数的内在工作过程,相信很多作相关研究的新手也并不真正清楚(我本身也是新手)。OpenGL红宝书中的相关讲解也只是针对函数的用途、参数、注意事项等的说明。当我们需要自己需要加载定标参数来写一个新的投影函数,或者说将我们定标得到的原始参数扩展成为符合OpenGL对应的模型视图矩阵、投影矩阵、视口向量的时候,我们必须知道OpenGL的这个函数究竟是如何工作的。本文只就gluProject的工作过程进行分析,对于各种定标参数矩阵的扩展等内容将在以后的文章中说明。

先来揭秘一下gluProject函数的本来面目(源代码):

从这个源码中我们可以看出以下几点:

1)观察transform_point函数中矩阵元素和列向量的相乘过程可知,这个矩阵是被转置后再和列向量相乘的。这就是为什么说OpenGL的矩阵相乘是遵循列主元的,而我们使用gluProject函数的时候输入的矩阵参数却是按照行主元的方式。

2)从列向量被变换的顺序可以看出,一个齐次表示的3D点是先经过模型矩阵变换(蕴含照相机的位移、旋转、缩放等几何变换),在进行投影变换(蕴含照相机的内参数,即本身的参数),最后使用视口向量将齐次表示的2D点限定在当前的视口内。

3)根据函数的输入输出可以看出,输入的3D点是通过直接将向量的第四个元素in[3]赋值为1而齐次化的,输出的齐次表示其实是(winx,winy,1)。winz并不是投影在视口内的2D坐标的齐次表示的第三个元素,它携带的含义是多方面的:表面上看来,它表示了在视口上的深度值;实际上,它是由于照相机参数的不精确性(所有照相机模型都是对实际照相机的模拟,因而不可能完全精确的表达照相机本身)和矩阵相乘过程中的计算误差所造成的;因此假如照相机参数对照相机的建模是完美的,并且计算过程是没有误差的,那么winz的最终结果应该是0,在实际的计算中此参数所返回的值也应该是一个逼近于0的数,这个数的大小反映了误差的总量。所以我们在使用gluProject时通常不必关心winz返回的参数。

4)对于返回的(winx,winy),论坛上曾有朋友发问说为什么得到的投影点和实际的点是关于图像上下倒置的。这个是因为OpenGL窗口坐标系统默认(0,0)点是窗口的左下角,而通常Windows窗口和一般图像坐标系的(0,0)点默认在左上角,因此,当我们在这种不一致的坐标系之间进行点的运算时,要先进行一步winy = height – winy; 的转换。

                                                                                                        (李文凯,200957日,于HIT-VILab

 

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt OpenGL拾取对象是指在使用Qt框架开发OpenGL应用程序时,可以通过拾取操作来确定在OpenGL场景中的鼠标点击位置所对应的物体或对象。 实现这一功能的关键在于使用OpenGL提供的选择缓冲区(Selection Buffer)机制。首先,需要创建选择缓冲区,其大小应足够大以容纳可能被选中的所有对象。然后,使用glRenderMode(GL_SELECT)函数OpenGL切换到选择模式。在选择模式下,OpenGL会将渲染结果写入选择缓冲区而不是屏幕。 接下来,通过设置选择缓冲区的视口、投影矩阵及渲染函数的参数,来定义拾取操作的范围和方式。例如,可以使用gluPickMatrix函数设置拾取操作的矩形范围;使用glOrtho函数或glFrustum函数设置拾取操作的投影矩阵。最后,调用绘制函数进行渲染,OpenGL会将渲染结果写入选择缓冲区。 当完成渲染后,需要将OpenGL切换回渲染模式(如glRenderMode(GL_RENDER))。然后,通过遍历选择缓冲区内容,解析渲染结果,并根据鼠标点击位置的像素坐标获取对应的物体或对象信息。可以根据需要使用OpenGL提供的函数,如gluUnProject或gluProject来转换坐标。 最后,根据获取到的物体或对象信息,可以执行相应的操作,如选中对象、显示对象信息等。 总结来说,Qt OpenGL拾取对象可以通过选择缓冲区机制实现,通过设置视口、投影矩阵和渲染函数的参数,将渲染结果写入选择缓冲区,然后解析缓冲区内容获取对应的物体或对象信息,最后执行相应的操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值