zoukankan      html  css  js  c++  java
  • 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负方向移动:



  • 相关阅读:
    php 后端跨域请求
    IIS服务器文件跨域问题(几乎可以解决大多数跨域问题)
    JavaScript中的execCommand
    [原创] 利用前端+php批量生成html文件,传入新文本,输出新的html文件
    javascript 生成 uuid
    zabbix安装 检测环境 PHP bcmath off
    mysql中间件-amoeba
    MySQL备份
    ELK日志分析
    SAMBA配置文件详解
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9411911.html
Copyright © 2011-2022 走看看