设为首页 收藏本站
查看: 1082|回复: 0

[经验分享] perl-opengl-鼠标事件

[复制链接]

尚未签到

发表于 2017-5-18 09:44:32 | 显示全部楼层 |阅读模式

#!/usr/bin/perl -w
use strict;
use warnings;
use OpenGL qw/ :all /;
use OpenGL::Config;   

glutInit();
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("my  OpenGL program");
glClearColor(0,0,100,255);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-200,200,-200,200);
glMatrixMode(GL_MODELVIEW);
glutDisplayFunc(\&mydis);
glutMouseFunc(\&mymouse);
glutMainLoop();
sub mymouse()
{
my ($button,$state,$myx,$myy)=@_;
if ($button==GLUT_LEFT_BUTTON  and $state==GLUT_DOWN)
{
glPointSize(3);
glBegin(GL_LINES);  
glColor3f(255,0,0);
glVertex2f($myx-200,200-$myy);
glVertex2f(-200,200-$myy);
glEnd();
glFlush();      
}
print "mouse x:$myx-y:$myy\n";
}
sub mydis()
{
glPointSize(3);
glFlush();
}  







DSC0000.png
 


 

              鼠标


在前几节,我们看了怎么使用GLUT的keyboard函数,来增加一个OpenGL程序的交互性。现在,是时候研究下鼠标了。GLUT的鼠标接口提供一些列的选项来增加鼠标的交互性。也就是检测鼠标单击,和鼠标移动。

 

检测鼠标Clicks


和键盘处理一样,GLUT为你的注册函数(也就是处理鼠标clicks事件的函数)提供了一个方法。函数glutMouseFunc,这个函数一般在程序初始化阶段被调用。函数原型如下:



void glutMouseFunc(void(*func)(int button,int state,int x,int y));

参数:

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:active motion和passive motion。Active motion是指鼠标移动并且有一个鼠标键被按下。Passive motion是指当鼠标移动时,并有没鼠标键按下。如果一个程序正在追踪鼠标,那么鼠标移动期间,没一帧将产生一个结果。

 

和以前一样,你必须注册将处理鼠标事件的函数(定义函数)。GLUT让我们可以指定两个不同的函数,一个追踪passive motion,另一个追踪active motion

 

它们的函数原型,如下:



void glutMotionFunc(void(*func)(int x,int y));

void glutPassiveMotionFunc(void (*func)(int x,int y));

参数:

Func:处理各自类型motion的函数名。



处理motion的参数函数的参数(x,y)是鼠标在窗口的坐标。以左上角为原点。

 

检测鼠标进入或离开窗口

GLUT还能检测鼠标鼠标离开,进入窗口区域。一个回调函数可以被定义去处理这两个事件。GLUT里,调用这个函数的是glutEntryFunc,函数原型如下:



void glutEntryFunc(void(*func)(int state));

参数:

Func:处理这些事件的函数名。



上面函数的参数中,state有两个值:

GLUT_LEFT

GLUT_ENTERED

表明,是离开,还是进入窗口。

 

把它们放一起

首先我们要做的是在GLUT里定义哪些函数将负责处理鼠标事件。因此我们将重写我们的main函数,让它包含所有必须的回调注册函数。我们将在程序里描述其他一些教程里没说清楚的地方。



void main(int argc, 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);
 
         //adding here the mouse processing callbacks
         glutMouseFunc(processMouse);
         glutMotionFunc(processMouseActiveMotion);
         glutPassiveMotionFunc(processMousePassiveMotion);
         glutEntryFunc(processMouseEntry);
        
         glutMainLoop();
}
OK,现在做点有趣的。我们将定义那些将做一些不可思议事件的回调函数。当一个鼠标键和alt键都被按下,我们将改变三角形的颜色。鼠标左键使三角形变成红色,中间的将三角形变成绿色,鼠标右键将三角形变成蓝色。函数如下:



void processMouse(int button, int state, int x, int y) {
 
 
         specialKey = glutGetModifiers();
         // 当鼠标键和alt键都被按下
         if ((state == GLUT_DOWN) &&
                          (specialKey == GLUT_ACTIVE_ALT)) {
 
                 // set the color to pure red for the left button
                 if (button == GLUT_LEFT_BUTTON) {
                          red = 1.0; green = 0.0; blue = 0.0;
                 }
                 // set the color to pure green for the middle button
                 else if (button == GLUT_MIDDLE_BUTTON) {
                          red = 0.0; green = 1.0; blue = 0.0;
                 }
                 // set the color to pure blue for the right button
                 else {
                          red = 0.0; green = 0.0; blue = 1.0;
                 }
         }
}
接下来有一个精细的颜色拾取方法。当一个鼠标键被按下,但alt键被被按下。我们把blue设为0.0,并且让red和green分量的值取决于鼠标在窗口中的位置。。函数如下:



void processMouseActiveMotion(int x, int y) {
 
         // the ALT key was used in the previous function
         if (specialKey != GLUT_ACTIVE_ALT) {
                 // setting red to be relative to the mouse
                 // position inside the window
                 if (x < 0)
                          red = 0.0;
                 else if (x > width)
                          red = 1.0;
                 else
                          red = ((float) x)/height;
                 // setting green to be relative to the mouse
                 // position inside the window
                 if (y < 0)
                          green = 0.0;
                 else if (y > width)
                          green = 1.0;
                 else
                          green = ((float) y)/height;
                 // removing the blue component.
                 blue = 0.0;
         }
}
下面给passive motion添加一些动作。当shift键被按下,鼠标将在x轴上有一个旋转。我们不得不修改renderScene函数。函数如下:



float angleX = 0.0;
...
void renderScene(void) {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glPushMatrix();
         glRotatef(angle,0.0,1.0,0.0);
        
         // This is the line we added for the
         // rotation on the X axis;
         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();
}
现在我们的有个函数处理passive motion事件。函数将改变angleX的值。


void processMousePassiveMotion(int x, int y) {
 
         // User must press the SHIFT key to change the
         // rotation in the X axis
         if (specialKey != GLUT_ACTIVE_SHIFT) {
 
                 // setting the angle to be relative to the mouse
                 // position inside the window
                 if (x < 0)
                          angleX = 0.0;
                 else if (x > width)
                          angleX = 180.0;
                 else
                          angleX = 180.0 * ((float) x)/height;
         }
}
最后鼠标离开窗口将使动画停止,为了做到这,我们也需要改变函数renderScene。


// initially define the increase of the angle by 1.0;
float deltaAngle = 1.0;
...
void renderScene(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();
         // this is the new line
         // previously it was: angle++;
         angle+=deltaAngle;
         glutSwapBuffers();
}
processMouseEntry是最后一个函数。注意,这个在微软操作系统下可能工作的不是很好。


void processMouseEntry(int state) {
         if (state == GLUT_LEFT)
                 deltaAngle = 0.0;
         else
                 deltaAngle = 1.0;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-378658-1-1.html 上篇帖子: Perl 的 html 解析模块 下篇帖子: Perl POE
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表