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负方向移动:

OpenGL(十六) 鼠标、键盘交互响应事件的更多相关文章

  1. OpenGL键盘交互响应事件

    GLUT允许我们编写程序,在里面加入键盘输入控制,包括了普通键,和其他特殊键(如F1,UP).在这一章里我们将学习如何去检测哪个键被按下,可以从GLUT里得到些什么信息,和如何处理键盘输入.   处理 ...

  2. OpenGL 鼠标交互响应事件

    OpenGL 鼠标.键盘交互响应事件 先来一个样例: uses gl,glu,glut; procedure InitEnvironment;cdecl; begin glClearColor();/ ...

  3. 关于c# winform 键盘响应右边键盘消息响应事件的上下左右方向键没有反应

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11835642.html 记录一下这个小坑,c# winform 键盘响应右边键盘的上下左右方向 ...

  4. Unity3D笔记十六 输入输出-键盘事件、鼠标事件

    输入与控制操作Unity为开发者提供了Input类库,其中包括键盘事件.鼠标事件和触摸事件等一切跨平台所需要的控制事件. 一.键盘事件 1.按下事件 Input.GetKeyDown():如果按键被按 ...

  5. 第二十六课:jQuery对事件对象的修复

    因为原生的event对象,在不同浏览器下,有不同的属性和方法,因此需要用jQuery进行兼容. jQuery在这里分两步走,首先创建一个伪事件类jQuery.Event(jQuery里面自定义的事件类 ...

  6. Mac OS使用技巧之十六:系统失去响应怎么办?

    再好的系统,再快的本本,也会在执行时由于种种原因出现卡顿或者死机等失去响应的情况.Mac用户也会时不时碰到这样的情况,最常见的表现为鼠标变为七彩圆圈.通常等上一会儿系统会自己恢复.假设迟迟没有响应的话 ...

  7. js获取键盘按键响应事件(兼容各浏览器)

    <script type="text/javascript" language="JavaScript" charset="UTF-8" ...

  8. Android开发(十六)——Android listview onItemClick事件失效的原因

    参考: Android listview onItemClick事件失效的原因.http://blog.csdn.net/wangchun8926/article/details/8793178

  9. mfc 鼠标、键盘响应事件

    一.基本目标 1.有一个基本的MFC程序,点击“关闭”则“关闭”这个程序,这点没什么好讲的,把自带的“取消”按钮,右键->属性的Caption改成“关闭”二字就可以了 2.鼠标在对话框中移动,则 ...

随机推荐

  1. 数学之路-python计算实战(7)-机器视觉-图像产生加性零均值高斯噪声

    图像产生加性零均值高斯噪声.在灰度图上加上噪声,加上噪声的方式是每一个点的灰度值加上一个噪声值.噪声值的产生方式为Box-Muller算法生成高斯噪声. 在计算机模拟中,常常须要生成正态分布的数值.最 ...

  2. ios开发多线程一:了解-NSOperation的基本使用

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  3. 创建ListView的基本步骤 分类: H1_ANDROID 2013-10-31 23:25 1276人阅读 评论(0) 收藏

    参考<疯狂android讲义>第2.5节P94 1.创建一个或者多个ListView <LinearLayout xmlns:android="http://schemas ...

  4. ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了

    前言 平时喜欢写东西,看博客,一直对编码有些懵,今天下午也不知道看到了什么,突然想了解下,就找到了这个文章,看完真的豁然开朗,这个必须留下来做纪念. 点击打开链接 1.ASCII 我们知道,计算机内部 ...

  5. Java编程思想第四版 *第五章 个人练习

    练习3:(1)创建一个带默认构造器(即无參构造器)的类.在构造器中打印一条消息.为这个类创建一个对象.P116 public class Test{ public Test(){ System.out ...

  6. 安装innotop

    安装方法一: 下载地址:https://github.com/innotop/innotop yum install -y perl-TermReadKey yum install -y perl-D ...

  7. want cry -- 137,139,445

    通过wireshark抓包发现smb的请求报文,目的端口为445,没有应答报文 之前设置了“阻止连接”导致smb访问被拒绝.修改为要求对连接进行加密 就可以访问

  8. 新版Sublime text3注册码被移除的解决办法

    Sublime Text是风靡世界的文本编辑器,支持多种编程语言,启动时间短,打开文件速度快,插件丰富,让很多程序员爱不释手.但是,对于未注册的Sublime Text, 经常在保存的时候会弹出一个烦 ...

  9. Xmem

    http://blog.csdn.net/jthink_/article/details/43302615

  10. ASP.net 中 OutputCache 指令各个参数的作用。

    使用@ OutputCache指令 使用@ OutputCache指令,能够实现对页面输出缓存的一般性需要.@ OutputCache指令在ASP.NET页或者页中包含的用户控件的头部声明.这种方式非 ...