OpenGL选择与拾取GL_SELECT 附源码
来源:互联网 发布:网络硬盘录像机哪个好 编辑:程序博客网 时间:2024/06/05 17:28
在介绍开始,首先给出工程和可执行程序的下载链接:
OpenGL选择和拾取obj模型_代码及可执行文件
或者http://download.csdn.net/detail/mahabharata_/9709959
程序的执行结果如下:
首先,我们在OpenGL的绘制方式有两种:GL_RENDER和GL_SELECT。顾名思义,GL_RENDER是渲染模式,也就是默认的绘制方式,通俗的讲,就是绘制操作都会被绘制在屏幕上;GL_SELECT则是选择模式,这种方式不会被绘制在屏幕上,之后的矩阵变化为选取矩阵的变化。
这里对GL_RENDER不做过多说明,因为这是默认方式,就是操纵显示在屏幕上时的矩阵变换。
对于GL_SELECT:在用OpenGL进行图形编程的时候,通常要用鼠标进行交互操作,比如用鼠标点选择画面中的物体,我们称之为拾取(Picking),这里我们介绍一下:在OpenGL中如何拾取,如何利用OpenGL提供的一系列函数来完成拾取,再简单介绍下OpenGL的名字栈(Name stack),拾取矩阵(Picking Matrix)等等。
1. 首先获得一系列参数信息:
const int BUFSIZE = 1024; //缓冲区selectBuf GLuint selectBuf[BUFSIZE]; glSelectBuffer (BUFSIZE, selectBuf); GLint viewport[4]; //获取视口viewport的信息 glGetIntegerv (GL_VIEWPORT, viewport);
2. 进入GL_SELECT模式,并初始化名字栈
glRenderMode(GL_SELECT); glInitNames(); glPushName(-1);
3. 保存一下矩阵信息:
glPushMatrix();
4. 在GL_SELECT模式下,指定拾取窗口,并进行投影变换(GL_PROJECTION)
投影变换事实上在GL_RENDER模式下已经进行过一次,但是需要在GL_SELECT模式下,再进行一次。
glMatrixMode (GL_PROJECTION); // 投影变换 glLoadIdentity (); gluPickMatrix((GLdouble)x, (GLdouble) (viewport[3]-y), 5.0, 5.0, viewport); // 指定选取窗口(x,y为鼠标点击位置) gluPerspective(45.0, (GLfloat)width()/(GLfloat)height(), 0.1, 10000.0); // 指定视景体5. 在GL_SELECT模式下,进行模型视图变换GL_MODELVIEW
glMatrixMode(GL_MODELVIEW); // 2: GL_SELECT下模型视图变换 glLoadIdentity(); gluLookAt(0.0,0.0,10.0, 0.0,0.0,0.0, 0.0,1.0,0.0); //指定摄像机位置 /* 为了保证选取结果的正确性,在GL_RENDER下进行的所有缩放、平移、旋转等操作,这里也要进行一次。 */
6. 在GL_SELECT重新绘制物体,这里使用我上传的程序中的例子。
调用绘制函数,总共有3个人物,绘制函数为renderNPC(GLenum mode);
for(int i=0; i< 3 ;i++) { _characters[i]->renderNPC(GL_SELECT); // 使用GL_SELECT方式渲染一次(并不绘制在屏幕上) }
关于renderNPC(GLenum mode)的具体实现,在后面给出。
7. 出栈,让之前进行的矩阵操作释放掉。
glPopMatrix();
8. 对选取的名字栈进行处理(选取结果已经储存在名字栈中了)
// 切换回GL_RENDER模式 GLint hits = glRenderMode (GL_RENDER); // 返回的hit:表示名字栈中结果的个数。 glMatrixMode (GL_PROJECTION); /// 此处需要重新进行一次GL_RENDER模式下的投影变换。 glLoadIdentity (); gluPerspective(45.0, (GLfloat)width()/(GLfloat)height(), 0.1, 10000.0); if(hits) ///如果选中物体,设置为"选中"状态 { _characters[selectBuf[3]]->_isSelected=!( _characters[selectBuf[3]]->_isSelected ); } updateGL(); // 在屏幕上重绘,因为有的物体已经被选中。
关于在上面出现的renderNPC(GLenum mode)函数,下面给出其内部细节(为了简单表述,以画方块为例)。
void renderNPC(GLenum model) { glPushMatrix(); /* 这里进行属于本物体的旋转、平移、缩放变换 */ if(model == GL_SELECT) { glLoadName(_name); //这里的_name为预先设计的该物体的名字,为一个GLuint值,比如1、2、3、..... } if(_isSelected == true) ///如果被选中 { /* 对于选取的物体,进行诸如修改颜色啊啥啥啥的操作。 */ } glutSolidCube(3.0); //绘制出物体,这里以一个“方块”举例。 glPopMatrix(); }
此外,我们还需要了解的最后一点,名字栈的机制,名字栈最终保存在selectBuffer[]中。当某物件被“拾取”(被光束射中)的时候,对应的名字和相关信息便会被提交给HIT Record,存储在selectBuffer里面。相关信息包括该物件离光束发射处(相机/眼睛)最近的点的深度值和最远的点的深度值等等,以下反映了当一个物件被拾取后,名字栈机制向HIT Record发送的信息(然后HIT Record把此信息存入selectBuffer):
击中的物件的名字的数目这个物件中最近的点的深度值这个物件中最远的点的深度值击中的物件的名字之一击中的物件的名字之二(若有多个名字,则如此类推...)
- OpenGL选择与拾取GL_SELECT 附源码
- OpenGL-选择与拾取
- OpenGL-选择与拾取
- OpenGL-选择与拾取
- OpenGL - 鼠标选择与拾取
- OpenGL学习笔记:拾取与选择
- OpenGL学习笔记:拾取与选择
- OpenGL选择-拾取机制(上)
- OpenGL选择-拾取机制(下)
- 乱弹OpenGL选择-拾取机制(下)
- OpenGL拾取
- [OpenGL] 兔子与顶点数组、拾取
- [OpenGL]课后案例08:选择模式拾取程序
- <<opengl编程基础>> 3.13 拾取和选择模式
- OpenGL选择-拾取机制(转载自zwqxin)
- OpenGL选择-拾取机制(转载自zwqxin)
- gluLookAt()与glRenderMode(GL_SELECT)的使用
- OpenGL精确选择与连线DEMO(含源码)
- 《针对网络空间关键基础设施情报收集的组织行为分析报告》——读后记
- 【编程之法】有趣的字符串全排列
- CentOS-7-64bit 下为firefox安装flashplayer
- Hive学习笔记 --- return code 1 from org.apache.hadoop.hive
- j2ee的web工程,导入后,报错Syntax error, parameterized types are only available if source level is 5.
- OpenGL选择与拾取GL_SELECT 附源码
- hibernate与sqlserver的连接
- 实现 tomcat 热加载证书
- 深入分析ClassLoader工作机制
- 开关三极管的使用误区
- ssh配置连接多台服务器快捷键
- Ubuntu 主要命令
- 开始学习C语言了,scanf如何用?
- 李嘉诚用餐之道