1. 程式人生 > >【OpenGL】-009 GLUT中處理鍵盤滑鼠事件

【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;
}