OpenGL中鼠标点取

来源:互联网 发布:windows arp攻击 编辑:程序博客网 时间:2024/05/01 22:00

OpenGL中鼠标点取

(2008-07-27 00:29:19)
OpenGL中鼠标点取转载
标签:

杂谈

分类:计算机图形学
获取拣选射线的例程如下所示(使用C++语言编写):
class Point3f;
class LineSegment;
LineSegment GetSelectionRay(int mouse_x, int mouse_y){
// 获取 Model-View,Projection 矩阵 & 获取Viewport 视区
GLdouble modelview[16];
GLdouble projection[16];
GLint viewport[4];
glGetDoublev (GL_MODELVIEW_MATRIX, modelview);
glGetDoublev (GL_PROJECTION_MATRIX, projection);
glGetIntegerv (GL_VIEWPORT, viewport);
GLdouble world_x, world_y, world_z;
// 获取近裁剪面上的交点
gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y,0.0,
modelview, projection, viewport,
&world_x, &world_y, &world_z);
Point3f near_point(world_x, world_y, world_z);
// 获取远裁剪面上的交点
gluUnProject( (GLdouble) mouse_x, (GLdouble) mouse_y,1.0,
modelview, projection, viewport,
&world_x, &world_y, &world_z);
Point3f far_point(world_x, world_y, world_z);
return LineSegment(near_point, far_point);
}
如果你是使用Win32平台进行开发,那么应当注意传入正确的参数.因为无论是使用Win32 API 还是 DirectInput来获取鼠标坐标,得到的Y值都应取反后再传入.因为OpenGL默认的原点在视区的左下角,Y轴从左下角指向左上角, 而Windows默认的原点在窗口的左上角,而Y轴方向与OpenGL相反,从左上角指向左下角.如下图所示:
我们可以看到代码被注释分为了三个部分:获取当前矩阵及视区,获取近裁剪面的交点,获取远裁剪面的交点.
我们通过OpenGL提供的查询函数轻松得到当前的ModelView和Projection矩阵,以及当前的Viewport(视区,也就是窗口的客户端区域,如果整个窗口区域用于OpenGL渲染的话).
获得两个裁剪面上的交点的代码基本上是一样的,唯一的不同点是我们前面曾经详细地讨论过的窗口的Z坐标.不错,这个坐标表示的就是"深浅"的概念.它的值从点P'到点P的变化是从0.0f逐渐增至1.0f.此处类似于OpenGL的深度测试机制.
在得到两个交点之后,我们使用它们通过返回语句直接构建一条线段.在这里仅仅作为实例代码,故简捷清晰地直接返回线段对象,而没有通过引用参数来提高效率.
此时用户可以使用这个函数来判断所选择的对象了.只需在需要的地方判断对象是否与此线段相交即可判断对象是否被选中,还可以通过进一步计算其交点位置来得到详细的交点信息.这些计算均是常见的计算机图形学与三维数学计算,比如线段与三角形求交,线段与面求交,线段与球体求交,线段与柱体或锥体求交,等等. 请参考所列出的计算机图形学书籍.
五,结论(Conclusion)

在本文中,我们介绍了一种行之有效的三维坐标拾取方法,主要使用GLU库中的实用工具实现.这种方法速度快,效率高,能在不必重新绘制对象的前提下完成拣选工作.对比OpenGL自带的拣选机制来看,RIP的确在各种方面均有一定的优势.
六,参考文献(Reference)
【1】《OpenGL Programming Guide》
OpenGL ARB Mason Woo, Jackie Heider,Tom Davis, Dave Shreiner
【2】《OpenGL Reference Manual》
OpenGL ARB
【3】《Computer Graphics》
Donald Heam, M. Pauline Baker
【4】《Computer Graphics using OpenGL 2nd Edition》
F.S. Hill, JR.
Win32 默认窗口坐标样式
OpenGL 默认窗口坐标样式
0 0