OpenGL---GLUT教程(九) GLUT鼠标
2011-09-16 11:26
357 查看
转自:http://blog.csdn.net/xie_zi/article/details/1925778
在前几节,我们看了怎么使用GLUT的keyboard函数,来增加一个OpenGL程序的交互性。现在,是时候研究下鼠标了。GLUT的鼠标接口提供一些列的选项来增加鼠标的交互性。也就是检测鼠标单击,和鼠标移动。
检测鼠标Clicks
和键盘处理一样,GLUT为你的注册函数(也就是处理鼠标clicks事件的函数)提供了一个方法。函数glutMouseFunc,这个函数一般在程序初始化阶段被调用。函数原型如下:
voidglutMouseFunc(void(*func)(intbutton,intstate,intx,inty));
参数:
func:处理鼠标click事件的函数的函数名。
从上面可以看到到,处理鼠标click事件的函数,一定有4个参数。第一个参数表明哪个鼠标键被按下或松开,这个变量可以是下面的三个值中的一个:
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
第二个参数表明,函数被调用发生时,鼠标的状态,也就是是被按下,或松开,可能取值如下:
GLUT_DOWN
GLUT_UP
当函数被调用时,state的值是GLUT_DOWN,那么程序可能会假定将会有个GLUT_UP事件,甚至鼠标移动到窗口外面,也如此。然而,如果程序调用glutMouseFunc传递NULL作为参数,那么GLUT将不会改变鼠标的状态。
剩下的两个参数(x,y)提供了鼠标当前的窗口坐标(以左上角为原点)。
检测动作(motion)
GLUT提供鼠标motion检测能力。有两种GLUT处理的motion:activemotion和passive
motion。Activemotion是指鼠标移动并且有一个鼠标键被按下。Passive
motion是指当鼠标移动时,并有没鼠标键按下。如果一个程序正在追踪鼠标,那么鼠标移动期间,没一帧将产生一个结果。
和以前一样,你必须注册将处理鼠标事件的函数(定义函数)。GLUT让我们可以指定两个不同的函数,一个追踪passivemotion,另一个追踪activemotion
它们的函数原型,如下:
voidglutMotionFunc(void(*func)(intx,inty));
voidglutPassiveMotionFunc(void(*func)(intx,inty));
参数:
Func:处理各自类型motion的函数名。
处理motion的参数函数的参数(x,y)是鼠标在窗口的坐标。以左上角为原点。
检测鼠标进入或离开窗口
GLUT还能检测鼠标鼠标离开,进入窗口区域。一个回调函数可以被定义去处理这两个事件。GLUT里,调用这个函数的是glutEntryFunc,函数原型如下:
voidglutEntryFunc(void(*func)(intstate));
参数:
Func:处理这些事件的函数名。
上面函数的参数中,state有两个值:
GLUT_LEFT
GLUT_ENTERED
表明,是离开,还是进入窗口。
把它们放一起
首先我们要做的是在GLUT里定义哪些函数将负责处理鼠标事件。因此我们将重写我们的main函数,让它包含所有必须的回调注册函数。我们将在程序里描述其他一些教程里没说清楚的地方。
OK,现在做点有趣的。我们将定义那些将做一些不可思议事件的回调函数。当一个鼠标键和alt键都被按下,我们将改变三角形的颜色。鼠标左键使三角形变成红色,中间的将三角形变成绿色,鼠标右键将三角形变成蓝色。函数如下:
接下来有一个精细的颜色拾取方法。当一个鼠标键被按下,但alt键被被按下。我们把blue设为0.0,并且让red和green分量的值取决于鼠标在窗口中的位置。。函数如下:
下面给passivemotion添加一些动作。当shift键被按下,鼠标将在x轴上有一个旋转。我们不得不修改renderScene函数。函数如下:
在前几节,我们看了怎么使用GLUT的keyboard函数,来增加一个OpenGL程序的交互性。现在,是时候研究下鼠标了。GLUT的鼠标接口提供一些列的选项来增加鼠标的交互性。也就是检测鼠标单击,和鼠标移动。
检测鼠标Clicks
和键盘处理一样,GLUT为你的注册函数(也就是处理鼠标clicks事件的函数)提供了一个方法。函数glutMouseFunc,这个函数一般在程序初始化阶段被调用。函数原型如下:
voidglutMouseFunc(void(*func)(intbutton,intstate,intx,inty));
参数:
func:处理鼠标click事件的函数的函数名。
从上面可以看到到,处理鼠标click事件的函数,一定有4个参数。第一个参数表明哪个鼠标键被按下或松开,这个变量可以是下面的三个值中的一个:
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
第二个参数表明,函数被调用发生时,鼠标的状态,也就是是被按下,或松开,可能取值如下:
GLUT_DOWN
GLUT_UP
当函数被调用时,state的值是GLUT_DOWN,那么程序可能会假定将会有个GLUT_UP事件,甚至鼠标移动到窗口外面,也如此。然而,如果程序调用glutMouseFunc传递NULL作为参数,那么GLUT将不会改变鼠标的状态。
剩下的两个参数(x,y)提供了鼠标当前的窗口坐标(以左上角为原点)。
检测动作(motion)
GLUT提供鼠标motion检测能力。有两种GLUT处理的motion:activemotion和passive
motion。Activemotion是指鼠标移动并且有一个鼠标键被按下。Passive
motion是指当鼠标移动时,并有没鼠标键按下。如果一个程序正在追踪鼠标,那么鼠标移动期间,没一帧将产生一个结果。
和以前一样,你必须注册将处理鼠标事件的函数(定义函数)。GLUT让我们可以指定两个不同的函数,一个追踪passivemotion,另一个追踪activemotion
它们的函数原型,如下:
voidglutMotionFunc(void(*func)(intx,inty));
voidglutPassiveMotionFunc(void(*func)(intx,inty));
参数:
Func:处理各自类型motion的函数名。
处理motion的参数函数的参数(x,y)是鼠标在窗口的坐标。以左上角为原点。
检测鼠标进入或离开窗口
GLUT还能检测鼠标鼠标离开,进入窗口区域。一个回调函数可以被定义去处理这两个事件。GLUT里,调用这个函数的是glutEntryFunc,函数原型如下:
voidglutEntryFunc(void(*func)(intstate));
参数:
Func:处理这些事件的函数名。
上面函数的参数中,state有两个值:
GLUT_LEFT
GLUT_ENTERED
表明,是离开,还是进入窗口。
把它们放一起
首先我们要做的是在GLUT里定义哪些函数将负责处理鼠标事件。因此我们将重写我们的main函数,让它包含所有必须的回调注册函数。我们将在程序里描述其他一些教程里没说清楚的地方。
voidmain(intargc,char**argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("SnowMen");
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
//addingherethemouseprocessingcallbacks
glutMouseFunc(processMouse);
glutMotionFunc(processMouseActiveMotion);
glutPassiveMotionFunc(processMousePassiveMotion);
glutEntryFunc(processMouseEntry);
glutMainLoop();
}
OK,现在做点有趣的。我们将定义那些将做一些不可思议事件的回调函数。当一个鼠标键和alt键都被按下,我们将改变三角形的颜色。鼠标左键使三角形变成红色,中间的将三角形变成绿色,鼠标右键将三角形变成蓝色。函数如下:
voidprocessMouse(intbutton,intstate,intx,inty){
specialKey=glutGetModifiers();
//
当鼠标键和alt键都被按下
if((state==GLUT_DOWN)&&
(specialKey==GLUT_ACTIVE_ALT)){
//setthecolortopureredfortheleftbutton
if(button==GLUT_LEFT_BUTTON){
red=1.0;green=0.0;blue=0.0;
}
//setthecolortopuregreenforthemiddlebutton
elseif(button==GLUT_MIDDLE_BUTTON){
red=0.0;green=1.0;blue=0.0;
}
//setthecolortopurebluefortherightbutton
else{
red=0.0;green=0.0;blue=1.0;
}
}
}
接下来有一个精细的颜色拾取方法。当一个鼠标键被按下,但alt键被被按下。我们把blue设为0.0,并且让red和green分量的值取决于鼠标在窗口中的位置。。函数如下:
voidprocessMouseActiveMotion(intx,inty){
//theALTkeywasusedinthepreviousfunction
if(specialKey!=GLUT_ACTIVE_ALT){
//settingredtoberelativetothemouse
//positioninsidethewindow
if(x<0)
red=0.0;
elseif(x>width)
red=1.0;
else
red=((float)x)/height;
//settinggreentoberelativetothemouse
//positioninsidethewindow
if(y<0)
green=0.0;
elseif(y>width)
green=1.0;
else
green=((float)y)/height;
//removingthebluecomponent.
blue=0.0;
}
}
下面给passivemotion添加一些动作。当shift键被按下,鼠标将在x轴上有一个旋转。我们不得不修改renderScene函数。函数如下:
floatangleX=0.0;
...
voidrenderScene(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle,0.0,1.0,0.0);
//Thisisthelineweaddedforthe
//rotationontheXaxis;
glRotatef(angleX,1.0,0.0,0.0);
glColor3f(red,green,blue);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glPopMatrix();
angle++;
glutSwapBuffers();
}
现在我们的有个函数处理passivemotion事件。函数将改变angleX的值。
voidprocessMousePassiveMotion(intx,inty){
//UsermustpresstheSHIFTkeytochangethe
//rotationintheXaxis
if(specialKey!=GLUT_ACTIVE_SHIFT){
//settingtheangletoberelativetothemouse
//positioninsidethewindow
if(x<0)
angleX=0.0;
elseif(x>width)
angleX=180.0;
else
angleX=180.0*((float)x)/height;
}
}
最后鼠标离开窗口将使动画停止,为了做到这,我们也需要改变函数renderScene。
//initiallydefinetheincreaseoftheangleby1.0;
floatdeltaAngle=1.0;
...
voidrenderScene(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle,0.0,1.0,0.0);
glRotatef(angleX,1.0,0.0,0.0);
glColor3f(red,green,blue);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glPopMatrix();
//thisisthenewline
//previouslyitwas:angle++;
angle+=deltaAngle;
glutSwapBuffers();
}
processMouseEntry是最后一个函数。注意,这个在微软操作系统下可能工作的不是很好。
voidprocessMouseEntry(intstate){
if(state==GLUT_LEFT)
deltaAngle=0.0;
else
deltaAngle=1.0;
}
VC6.0工程可以在这里下载(glut8.zip)。
(到这里位置,键盘,鼠标方面的控制讲完了,下面就是菜单了。)
(原文地址:http://www.lighthouse3d.com/opengl/glut/index.php?9)
相关文章推荐
- OpenGL---GLUT教程(九) GLUT鼠标
- OpenGL---GLUT教程(九) GLUT鼠标/OpenGL(Win32 窗体应用程序框架)
- OpenGL---GLUT教程(九) GLUT鼠标
- OpenGL---GLUT教程(九) GLUT鼠标
- OpenGL---GLUT教程(三) GLUT窗口设置
- OpenGL---GLUT教程(六) GLUT场景漫游
- OpenGL 入门基础教程 —— 键盘和鼠标响应
- OpenGL---GLUT教程(一) GLUT简介,体系
- OpenGL---GLUT教程(一) GLUT简介,体系
- OpenGL---GLUT教程(七) GLUT高级键盘控制
- OpenGL---GLUT教程(二) GLUT初始化
- OpenGL---GLUT教程(十) GLUT菜单
- OpenGL---GLUT教程(八) GLUT场景漫游II
- OpenGL---GLUT教程 GLUT初始化
- OpenGL---GLUT教程(三) GLUT窗口设置
- OpenGL---GLUT教程(二) GLUT初始化
- OpenGL---GLUT教程(十一) GLUT子菜单
- OpenGL织梦之旅【第三章】第4节.glut键盘鼠标响应
- OpenGL---GLUT教程 GLUT初始化
- OpenGL---GLUT教程(四) GLUT动画