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