• 【转】Glut处理鼠标事件


    http://blog.csdn.net/wuyong2k/article/details/7839973

    目录(?)[-]

    1. 检测鼠标单击
    2. 检测动作
    3. 检测鼠标进入或离开窗口
    4. 应用
     

    检测鼠标单击

    要想在OpenGL中处理鼠标事件非常的方便,GLUT已经为我们的注册好了函数,只要我们提供一个方法。使用函数glutMouseFunc,就可以帮我们注册我们的函数,这样当发生鼠标事件时就会自动调用我们的方法。

    函数的原型是:

    void glutMouseFunc(void(*func)(int button,int state,int x,int y));
    参数:
    func:处理鼠标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)提供了鼠标当前的窗口坐标(以左上角为原点)。

    检测动作

    GLUT提供鼠标动作检测能力。有两种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

    应用

    现在想实现的功能就是使用鼠标拖动,来转动场景中的物体,当鼠标左键按下,并且上下左右滑动时,场景中的物体相应的会随之上下左右旋转,当鼠标右键按下,并且上下滑动时,场景中的物体相应的会随之移入或是移出屏幕。

    首先,定义几个全局变量:

    bool mouseLeftDown;
    bool mouseRightDown;
    float mouseX, mouseY;
    float cameraDistance;
    float cameraAngleX;
    float cameraAngleY;

    其中,mouseLeftDown和 mouseRightDown变量标志鼠标左右键按下与否,mouseX和mouseY变量标志鼠标滑动时,前一刻的鼠标所在位置,cameraDistance这个变量根据鼠标右键按下并上下滑动来控制场景中物体移入屏幕的远近。cameraAngleX和cameraAngleY变量根据鼠标左键按下并滑动来控制场景中物体的旋转。

    void mouseCB(int button, int state, int x, int y)
    {
        mouseX = x;
        mouseY = y;
    
        if(button == GLUT_LEFT_BUTTON)
        {
            if(state == GLUT_DOWN)
            {
                mouseLeftDown = true;
            }
            else if(state == GLUT_UP)
                mouseLeftDown = false;
        }
    
        else if(button == GLUT_RIGHT_BUTTON)
        {
            if(state == GLUT_DOWN)
            {
                mouseRightDown = true;
            }
            else if(state == GLUT_UP)
                mouseRightDown = false;
        }
    }
    
    void mouseMotionCB(int x, int y)
    {
        if(mouseLeftDown)
        {
            cameraAngleY += (x - mouseX);
            cameraAngleX += (y - mouseY);
            mouseX = x;
            mouseY = y;
        }
        if(mouseRightDown)
        {
            cameraDistance += (y - mouseY) * 0.2f;
            mouseY = y;
        }
    
        glutPostRedisplay();
    }

    在主函数中,调用相应的函数注册即可:

    glutMouseFunc(mouseCB);
    glutMotionFunc(mouseMotionCB);

    在场景中物体绘制之前,这样就可以:

    glTranslatef(0, 0, cameraDistance);
    glRotatef(cameraAngleX, 1, 0, 0);
    glRotatef(cameraAngleY, 0, 1, 0);
    参考:
    鼠标事件处理
  • 相关阅读:
    操作excel语法
    MySQL exists的用法介
    vim 快捷键
    mysql中datetime比较大小问题
    MySQL CAST与CONVERT 函数的用法
    tbxvUZIAJH
    springBoot相关
    springCloud
    Spring Boot使用JavaMailSender发送邮件
    RabbitMq 消息队列
  • 原文地址:https://www.cnblogs.com/lzhitian/p/2818389.html
Copyright © 2020-2023  润新知