博客转自:http://blog.csdn.net/xie_zi/article/details/1911891
GLUT允许我们编写程序,在里面加入键盘输入控制,包括了普通键,和其他特殊键(如F1,UP)。在这一章里我们将学习如何去检测哪个键被按下,可以从GLUT里得到些什么信息,和如何处理键盘输入。到现在,你应该注意到了,只要你想控制一个事件的处理,你就必须提前告诉GLUT,哪个函数将完成这个任务。到现在为止,我们已经使用GLUT告诉窗口系统,当窗口重绘时我们想调用哪个渲染函数,但系统空闲时,哪个函数被调用。和当窗口大小改变时,哪个函数又将被调用。相似的,我们必须做同样的事来处理按键消息。
我们必须使用GLUT通知窗口系统,当某个键被按下时,哪个函数将完成所要求的操作。我们同样是调用一个函数注册相关的回调函数。当你按下一个键后,GLUT提供了两个函数为这个键盘消息注册回调。第一个是glutKeyboardFunc。这个函数是告诉窗口系统,哪一个函数将会被调用来处理普通按键消息。普通键是指字母,数字,和其他可以用ASCII代码表示的键。函数原型如下:
void glutKeyboardFunc(void(*func)(unsigned char key,int x,int y));
void processNormalKeys(unsigned char key,int x,int y) { if(key==27) Exit(0); }
下面让我们控制特殊键的按键消息。GLUT提供函数glutSpecialFunc以便当有特殊键按下的消息时,你能注册你的函数。函数原型如下:
void glutSpecialFunc(void (*func)(int key,int x,int y));
下面我们写一个函数,当一些特殊键按下的时候,改变我们的三角形的颜色。这个函数使在按下F1键时三角形为红色,按下F2键时为绿色,按下F3键时为蓝色。
void processSpecialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_F1: red = 1.0; green = 0.0; blue = 0.0; break; case GLUT_KEY_F2: red = 0.0; green = 1.0; blue = 0.0; break; case GLUT_KEY_F3: red = 0.0; green = 0.0; blue = 1.0; break; } }
上面的GLUT_KEY_*在glut.h里已经被预定义为常量。这组常量如下:
GLUT_KEY_F1 F1 function key
GLUT_KEY_F2 F2 function key
GLUT_KEY_F3 F3 function key
GLUT_KEY_F4 F4 function key
GLUT_KEY_F5 F5 function key
GLUT_KEY_F6 F6 function key
GLUT_KEY_F7 F7 function key
GLUT_KEY_F8 F8 function key
GLUT_KEY_F9 F9 function key
GLUT_KEY_F10 F10 function key
GLUT_KEY_F11 F11 function key
GLUT_KEY_F12 F12 function key
GLUT_KEY_LEFT Left function key
GLUT_KEY_RIGHT Up function key
GLUT_KEY_UP Right function key
GLUT_KEY_DOWN Down function key
GLUT_KEY_PAGE_UP Page Up function key
GLUT_KEY_PAGE_DOWN Page Down function key
GLUT_KEY_HOME Home function key
GLUT_KEY_END End function key
GLUT_KEY_INSERT Insert function key
为了让上面processSpecialKeys函数能过编译通过,我们还必须定义,red,green,blue三个变量。此外为了得到我们想要的结果,我们还必须修改renderScene函数。
//所有的变量被初始化为1,表明三角形最开始是白色的。 float red = 1.0, blue = 1.0, green = 1.0; void renderSence() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //保存当前模型视图矩阵。 glPushMatrix(); glRotatef(rotateAngle, 0.0, 1.0, 0.0); //glColor3f设置绘制三角形的颜色。 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(); glutSwapBuffers(); rotateAngle +=0.01; //glFlush(); }
完整的代码如下
#include <gl/glut.h> //旋转角度 float rotateAngle = 0.0; //所有的变量被初始化为1,表明三角形最开始是白色的。 float red = 1.0, blue = 1.0, green = 1.0; void renderSence() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //保存当前模型视图矩阵。 glPushMatrix(); glRotatef(rotateAngle, 0.0, 1.0, 0.0); //glColor3f设置绘制三角形的颜色。 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(); glutSwapBuffers(); rotateAngle +=0.01; //glFlush(); } void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) exit(0); } void processSpecialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_F1: red = 1.0; green = 0.0; blue = 0.0; break; case GLUT_KEY_F2: red = 0.0; green = 1.0; blue = 0.0; break; case GLUT_KEY_F3: red = 0.0; green = 0.0; blue = 1.0; break; } } void reShape(int width , int height) { //防止除数即高度为0 //(你可以设置窗口宽度为0) if (height == 0) height = 1; float ratio = 1.0* width / height; // 单位化投影矩阵。 glMatrixMode(GL_PROJECTION); glLoadIdentity(); //设置视口大小为增个窗口大小 glViewport(0, 0, width, height); // 设置正确的投影矩阵 gluPerspective(45, ratio, 1, 1000); //下面是设置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, -1.0, 0.0f, 1.0f, 0.0f); } int main(int argc, char** argv) { glutInit(&argc, argv); //glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200, 200); glutInitWindowSize(600,600); glutCreateWindow("GLUT Tutorials"); glutDisplayFunc(renderSence); glutReshapeFunc(reShape); // 这里让程序空闲时调用renderScene, glutIdleFunc(renderSence); //special function registration glutSpecialFunc(processSpecialKeys); glutKeyboardFunc(processNormalKeys); glEnable(GL_DEPTH_TEST); glutMainLoop(); return 0; }
特殊按键 CTRL,ALT和SHIFT
一些时候我们想知道要是一个组合键(modifier key)也就是CTRL,ALT或者SHIFT被按下该如何处理。GLUT提供了一个函数来检测时候有组合键被按下。这个函数仅仅只能在处理按键消息或者鼠标消息函数里被调用。函数原型如下:
int glutGetModifiers(void);
void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) exit(0); else if (key=='r') { int mod = glutGetModifiers(); if (mod == GLUT_ACTIVE_ALT) red = 0.0; else red = 1.0; } }
注意如果我们按下R 键,将不会有什么发生,因为R与r键的ASCII码不同。即这是两个不同的键。最后就是如何检测按键CTRL+ALT+F1?。这种情况下,我们必须同时 检测两个组合键,为了完成操作我们需要使用或操作符。下面的代码段,使你按下CTRL+ALT+F1时颜色改变为红色。
void processSpecialKeys(int key, int x, int y) { int mod; switch(key) { case GLUT_KEY_F1 : mod = glutGetModifiers(); if (mod == (GLUT_ACTIVE_CTRL|GLUT_ACTIVE_ALT)) { red = 1.0; green = 0.0; blue = 0.0; } break; case GLUT_KEY_F2 : red = 0.0; green = 1.0; blue = 0.0; break; case GLUT_KEY_F3 : red = 0.0; green = 0.0; blue = 1.0; break; } }