【OpenGL】-009 GLUT中处理键盘鼠标事件

【OpenGL】-009 GLUT中处理键盘鼠标事件

  键盘和鼠标是GUI程序获取用户输入的重要方式,在windows程序中,通过WM_KEY_DOWN/WM_KEY_UP/WM_LBUTTONDOWN/WM_RBUTTONDOWN等消息的响应,用户可以方便的处理键盘鼠标的输入。在使用GLUT作为窗口管理时,如何进行键盘和鼠标的输入处理呢?

1. glutKeyboardFunc函数

  glut中定义了glutKeyboardFunc函数,用于设置键盘输入的回调函数。该函数定义如下:

FGAPI void    FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );

例如,函数调用形式如下:

void keyboardFunc(unsigned char c, int x, int y)
{
    switch(c)
    {
        case 27:
        glutLeaveMainLoop();
        std::cout << c << std::endl;
        break;
        case 'r':
        case 'R':
        g_c = 0;
        break;
    }
}
glutKeyboardFunc(keyboardFunc);

  该调用表示使用keyboardFunc函数处理键盘输入。其中,keyboardFunc函数的三个参数意义如下:

参数 类型 意义
c unsigned char 按下的键的值
x int 该键按下时鼠标的位置,窗口左上角为0,0
y int 该键按下时鼠标的位置,窗口左上角为0,0

2. glutMouseFunc函数

  GLUT中定义了glutMouseFunc函数用于设置鼠标消息处理回调函数。函数原型如下:

FGAPI void    FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );

例如,函数调用形式如下:

void mouseFunc(int button,int state,int x, int y)
{
    switch(button)
    {
        case GLUT_LEFT_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"LB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
        case GLUT_RIGHT_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"RB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
        case GLUT_MIDDLE_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"MB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
    }

}


glutMouseFunc(mouseFunc);

  该调用表示使用mouseFunc函数进行鼠标消息处理。回调函数mouseFunc函数具有四个参数:

参数 类型 意义
button int 当前鼠标消息对应的鼠标按键
state int 当前鼠标消息对应的鼠标按键的状态
x int 鼠标的位置,窗口左上角为0,0
y int 鼠标的位置,窗口左上角为0,0

3. 实现

  本程序效果如下:

  • 1 在窗口中显示一个彩色三角形;
  • 2 三角形随着时间向下位移;
  • 3 在窗口中按下左键、右键、中键时在终端输出提示信息;
  • 4 按下’r’或’R’键,三角形回到原始位置;
  • 5 按下’ESC’键后,程序窗口关闭,退出。
#include <GL/glut.h>
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#include <iostream>

#define REDISPLAYTIMERID 1

void init(void)
{
    glClearColor(0.0,0.0,0.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glOrtho(-5,5,-5,5,5,15);
    glMatrixMode(GL_MODELVIEW);
    gluLookAt(0,0,10,0,0,0,0,1,0);
    return ;
}
int g_c = 0;

void display(void)
{

    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0,0,0);

    glBegin(GL_TRIANGLES);
    glColor3f(1,0,0);glVertex2f(-5,5-g_c*0.01);
    glColor3f(0,1,0);glVertex2f(-5,-5-g_c*0.01);
    glColor3f(0,0,1);glVertex2f(5,-5-g_c*0.01);
    glEnd();
 
    glFlush();
    return ;
}

void timerFunc(int nTimerID)
{
    switch(nTimerID)
    {
        case REDISPLAYTIMERID:
            g_c++;
            glutPostRedisplay();
            glutTimerFunc(100,timerFunc,REDISPLAYTIMERID);
        break;
    }
}

void keyboardFunc(unsigned char c, int x, int y)
{
    switch(c)
    {
        case 27:
        glutLeaveMainLoop();
        std::cout << c << std::endl;
        break;
        case 'r':
        case 'R':
        g_c = 0;
        break;
    }
}

void mouseFunc(int button,int state,int x, int y)
{
    switch(button)
    {
        case GLUT_LEFT_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"LB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
        case GLUT_RIGHT_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"RB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
        case GLUT_MIDDLE_BUTTON:
        if(state == GLUT_DOWN)
        {
            std::cout <<"MB_DOWN x: "<<x << " y: "<<y<<std::endl;
        }
        break;
    }

}
int main(int argc, char* argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(500,500);
    glutCreateWindow("OGLWindow");
    init();
    glutDisplayFunc(display);
    glutTimerFunc(100,timerFunc,REDISPLAYTIMERID);
    glutKeyboardFunc(keyboardFunc);
    glutMouseFunc(mouseFunc);
    glutMainLoop();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/freehawkzk/article/details/83060375
009