1. 程式人生 > >OpenGL(十六) 滑鼠、鍵盤互動響應事件

OpenGL(十六) 滑鼠、鍵盤互動響應事件

OpenGL中通過滑鼠和鍵盤跟程式互動的實現需要實現註冊滑鼠和鍵盤響應事件,在一定條件下,該事件被觸發,事件裡的程式被執行,達到互動的目的。

通過glutMouseFunc(&OnMouse)註冊滑鼠事件,OnMouse是滑鼠事件的響應,函式格式是void OnMouse(int button,int state,int x,int y);

通過glutKeyboardFunc(&KeyBoards)註冊鍵盤事件,KeyBoards是鍵盤事件的響應,函式格式是
void KeyBoards(unsigned char key,int x,int y);

一、通過滑鼠左鍵、滾輪鍵、右鍵在視窗上單擊畫點

#include <glut.h> 

void InitEnvironment()
{
	glClearColor(0.6,0.6,0.6,0);
	glClear(GL_COLOR_BUFFER_BIT);
	glPointSize(6);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluOrtho2D(0,400,0,400);
}

void myDisplay(void)    
{ 
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();
}  

void OnMouse(int button,int state,int x,int y)
{
	if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
	{
		glColor3f(1,0,0);
		glBegin(GL_POINTS);
		glVertex2f(x,400-y);
		glEnd();
		glFlush();
	}
	if(button==GLUT_MIDDLE_BUTTON&&state==GLUT_DOWN)
	{
		glColor3f(0,1,0);
		glBegin(GL_POINTS);
		glVertex2f(x,400-y);
		glEnd();
		glFlush();
	}
	if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
	{
		glColor3f(0,0,1);
		glBegin(GL_POINTS);
		glVertex2f(x,400-y);
		glEnd();
		glFlush();
	}
}

int main(int argc, char *argv[])    
{    
	glutInit(&argc, argv);   //初始化GLUT
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);  
	glutInitWindowPosition(500, 200);    
	glutInitWindowSize(400, 400);    
	glutCreateWindow("OpenGL"); 
	InitEnvironment();   //初始化
	glutMouseFunc(&OnMouse);  //註冊滑鼠事件
	glutDisplayFunc(&myDisplay);   //回撥函式 
	glutMainLoop();    //持續顯示,當視窗改變會重新繪製圖形
	return 0;    
}  

在視窗上單擊滑鼠左鍵、滾輪鍵和右鍵分別繪製紅色、綠色和藍色的點:


二、通過滑鼠左鍵單擊控制模型旋轉、右鍵單擊暫停旋轉

#include <glut.h> 
#include <Windows.h>

GLfloat angle=0.0f;

void InitEnvironment()
{
	glEnable(GL_DEPTH);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(65,1,1,50);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(12,12,20,0,0,0,0,1,0);	
}

void myDisplay(void)    
{ 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glRotatef(angle,0,1,0);

	//以下繪製一個立方體
	glBegin(GL_QUADS);
	//底面  
	glColor4f(1,0,0,1);  
	glVertex3f(-5,-5,-5);  
	glVertex3f(5,-5,-5);  
	glColor4f(0,0,1,1);  
	glVertex3f(5,5,-5);  
	glVertex3f(-5,5,-5);  
	//側面A  
	glColor4f(0,0,1,1);  
	glVertex3f(-5,-5,-5);  
	glVertex3f(5,-5,-5);  
	glColor4f(0,1,0,1);    
	glVertex3f(5,-5,5);  
	glVertex3f(-5,-5,5);  
	//側面B  
	glColor4f(0,1,0,1);  
	glVertex3f(5,-5,-5);  
	glVertex3f(5,5,-5);  
	glColor4f(0,1,1,1);  
	glVertex3f(5,5,5);  
	glVertex3f(5,-5,5);  
	//側面C  
	glColor4f(1,1,0,1);   
	glVertex3f(5,5,-5);  
	glVertex3f(-5,5,-5);  
	glColor4f(1,0,1,1);  
	glVertex3f(-5,5,5);  
	glVertex3f(5,5,5);  
	//側面D  
	glColor4f(1,0,1,1);  
	glVertex3f(-5,5,-5);  
	glVertex3f(-5,-5,-5);  
	glColor4f(0,1,0,1);  
	glVertex3f(-5,-5,5);  
	glVertex3f(-5,5,5);  
	//頂面  
	glColor4f(1,1,0,1);  
	glVertex3f(-5,-5,5);  
	glVertex3f(5,-5,5);  
	glColor4f(0,0,1,1);  
	glVertex3f(5,5,5);  
	glVertex3f(-5,5,5);  

	glEnd(); 
	glutSwapBuffers();
	glPopMatrix();
}  

void RotateRect()
{
	angle+=0.5;
	if(angle>=360)
	{
		angle=0.0f;
	}
	Sleep(30);
	myDisplay();
}

void OnMouse(int button,int state,int x,int y)
{
	if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
	{
		glutIdleFunc(RotateRect);
	}

	if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
	{
		glutIdleFunc(NULL);
	}
}

int main(int argc, char *argv[])    
{    
	glutInit(&argc, argv);   //初始化GLUT
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);  
	glutInitWindowPosition(500, 200);    
	glutInitWindowSize(400, 400);    
	glutCreateWindow("OpenGL"); 
	InitEnvironment();   //初始化顯示環境
	glutMouseFunc(&OnMouse);  //註冊滑鼠事件
	glutDisplayFunc(&myDisplay);   //回撥函式 
	glutMainLoop();    //持續顯示,當視窗改變會重新繪製圖形
	return 0;    
}  

繪製了一個立方體模型,單擊左鍵開始旋轉,右鍵暫停:


三、 通過鍵盤控制模型各個方向旋轉和視角變化

#include <glut.h> 
#include <Windows.h>

GLfloat angle=10.0f;
GLfloat xDirection=0.0f;
GLfloat yDirection=0.0f;
GLfloat zDirection=10.0f;

void InitEnvironment()
{
	glEnable(GL_DEPTH);
	glClearColor(1,1,1,0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glColor4f(0,0,1,1);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(65,1,1,50);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);	
}

void KeyBoards(unsigned char key,int x,int y)
{
	switch (key)
	{
	case 'w':
		glMatrixMode(GL_MODELVIEW);
		glRotatef(angle,-1,0,0);
		glutPostRedisplay();
		break;
	case 'a':
		glMatrixMode(GL_MODELVIEW);
		glRotatef(angle,0,0,-1);
		glutPostRedisplay();
		break;
	case 's':
		glMatrixMode(GL_MODELVIEW);
		glRotatef(angle,1,0,0);
		glutPostRedisplay();
		break;
	case 'd':
		glMatrixMode(GL_MODELVIEW);
		glRotatef(angle,0,0,1);
		glutPostRedisplay();
		break;
	case '4':
		xDirection+=0.5;

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();		
		break;
	case '5':
		yDirection+=0.5;
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();
		break;

	case '6':
		zDirection+=0.5;
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();
		break;

	case '1':
		xDirection-=0.5;
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();
		break;
	case '2':
		xDirection-=0.5;
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();
		break;
	case '3':
		xDirection-=0.5;		
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluPerspective(65,1,1,50);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		gluLookAt(xDirection,yDirection,zDirection,0,0,0,0,1,0);
		glutPostRedisplay();		
		break;
	case 27:
		exit(0);
		break;
	}
}

void myDisplay(void)    
{ 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glutWireTeapot(4);
	glutSwapBuffers();
}  

void RotateRect()
{
	angle+=0.5;
	if(angle>=360)
	{
		angle=0.0f;
	}
	Sleep(30);
	myDisplay();
}

void OnMouse(int button,int state,int x,int y)
{
	if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
	{
		glutIdleFunc(RotateRect);
	}

	if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
	{
		glutIdleFunc(NULL);
	}
}

int main(int argc, char *argv[])    
{    
	glutInit(&argc, argv);   //初始化GLUT
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);  
	glutInitWindowPosition(500, 200);    
	glutInitWindowSize(500, 500);    
	glutCreateWindow("OpenGL"); 
	InitEnvironment();   //初始化顯示環境
	glutKeyboardFunc(&KeyBoards);  //註冊鍵盤事件
	glutDisplayFunc(&myDisplay);   //回撥函式 
	glutMainLoop();    //持續顯示,當視窗改變會重新繪製圖形
	return 0;    
}  

通過鍵盤上W、A、S、D鍵控制模型向上、向左、向下、向右旋轉:

W、S鍵控制:


A、D鍵控制:



數字鍵4、5、6控制視角向X、Y、Z正方向移動,1、2、3控制視角向X、Y、Z負方向移動: