GLUT 教程
              鼠标
在前几节,我们看了怎么使用GLUT的keyboard函数,来增加一个OpenGL程序的交互性。现在,是时候研究下鼠标了。GLUT的鼠标接口提供一些列的选项来增加鼠标的交互性。也就是检测鼠标单击,和鼠标移动。
检测鼠标 Clicks
和键盘处理一样,GLUT为你的注册函数(也就是处理鼠标clicks事件的函数)提供了一个方法。函数glutMouseFunc,这个函数一般在程序初始化阶段被调用。函数原型如下:
void glutMouseFunc(void(*func)(int button,int state,int x,int y));
参数:
func:处理鼠标click事件的函数的函数名。
从上面可以看到到,处理鼠标click事件的函数,一定有4个参数。第一个参数表明哪个鼠标键被按下或松开,这个变量可以是下面的三个值中的一个:
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
第二个参数表明,函数被调用发生时,鼠标的状态,也就是是被按下,或松开,可能取值如下:
GLUT_DOWN
GLUT_UP
当函数被调用时,state的值是GLUT_DOWN,那么程序可能会假定将会有个GLUT_UP事件,甚至鼠标移动到窗口外面,也如此。然而,如果程序调用glutMouseFunc传递NULL作为参数,那么GLUT将不会改变鼠标的状态。
剩下的两个参数(x,y)提供了鼠标当前的窗口坐标(以左上角为原点)。
检测动作( motion
GLUT提供鼠标motion检测能力。有两种GLUT处理的motion:active motion和passive motion。Active motion是指鼠标移动并且有一个鼠标键被按下。Passive motion是指当鼠标移动时,并有没鼠标键按下。如果一个程序正在追踪鼠标,那么鼠标移动期间,没一帧将产生一个结果。
和以前一样,你必须注册将处理鼠标事件的函数(定义函数)。GLUT让我们可以指定两个不同的函数,一个追踪passive motion,另一个追踪active motion
它们的函数原型,如下:
void glutMotionFunc(void(*func)(int x,int y));
void glutPassiveMotionFunc(void (*func)(int x,int y));
参数:
Func:处理各自类型motion的函数名。
处理motion的参数函数的参数(x,y)是鼠标在窗口的坐标。以左上角为原点。
检测鼠标进入或离开窗口
GLUT还能检测鼠标鼠标离开,进入窗口区域。一个回调函数可以被定义去处理这两个事件。GLUT里,调用这个函数的是glutEntryFunc,函数原型如下:
void glutEntryFunc(void(*func)(int state));
参数:
Func:处理这些事件的函数名。
上面函数的参数中,state有两个值:
GLUT_LEFT
GLUT_ENTERED
表明,是离开,还是进入窗口。
把它们放一起
首先我们要做的是在GLUT里定义哪些函数将负责处理鼠标事件。因此我们将重写我们的main函数,让它包含所有必须的回调注册函数。我们将在程序里描述其他一些教程里没说清楚的地方。
void main(int argc, char **argv) {
         glutInit(&argc, argv);
         glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
         glutInitWindowPosition(100,100);
         glutInitWindowSize(320,320);
         glutCreateWindow("SnowMen");
         glutDisplayFunc(renderScene);
         glutIdleFunc(renderScene);
         glutReshapeFunc(changeSize);
 
         //adding here the mouse processing callbacks
         glutMouseFunc(processMouse);
         glutMotionFunc(processMouseActiveMotion);
         glutPassiveMotionFunc(processMousePassiveMotion);
         glutEntryFunc(processMouseEntry);
         
         glutMainLoop();
}
OK,现在做点有趣的。我们将定义那些将做一些不可思议事件的回调函数。当一个鼠标键和alt键都被按下,我们将改变三角形的颜色。鼠标左键使三角形变成红色,中间的将三角形变成绿色,鼠标右键将三角形变成蓝色。函数如下:
void processMouse(int button, int state, int x, int y) {
 
 
         specialKey = glutGetModifiers();
         // 当鼠标键和alt键都被按下
         if ((state == GLUT_DOWN) && 
                          (specialKey == GLUT_ACTIVE_ALT)) {
 
                 // set the color to pure red for the left button
                 if (button == GLUT_LEFT_BUTTON) {
                          red = 1.0; green = 0.0; blue = 0.0;
                 }
                 // set the color to pure green for the middle button
                 else if (button == GLUT_MIDDLE_BUTTON) {
                          red = 0.0; green = 1.0; blue = 0.0;
                 }
                 // set the color to pure blue for the right button
                 else {
                          red = 0.0; green = 0.0; blue = 1.0;
                 }
         }
}
接下来有一个精细的颜色拾取方法。当一个鼠标键被按下,但alt键被被按下。我们把blue设为0.0,并且让red和green分量的值取决于鼠标在窗口中的位置。。函数如下:
void processMouseActiveMotion(int x, int y) {
 
         // the ALT key was used in the previous function
         if (specialKey != GLUT_ACTIVE_ALT) {
                 // setting red to be relative to the mouse 
                 // position inside the window
                 if (x < 0)
                          red = 0.0;
                 else if (x > width)
                          red = 1.0;
                 else
                          red = ((float) x)/height;
                 // setting green to be relative to the mouse 
                 // position inside the window
                 if (y < 0)
                          green = 0.0;
                 else if (y > width)
                          green = 1.0;
                 else
                          green = ((float) y)/height;
                 // removing the blue component.
                 blue = 0.0;
         }
}
下面给passive motion添加一些动作。当shift键被按下,鼠标将在x轴上有一个旋转。我们不得不修改renderScene函数。函数如下:
float angleX = 0.0;
...
void renderScene(void) {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glPushMatrix();
         glRotatef(angle,0.0,1.0,0.0);
         
         // This is the line we added for the
         // rotation on the X axis;
         glRotatef(angleX,1.0,0.0,0.0);
         
         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();
         angle++;
         glutSwapBuffers();
}
现在我们的有个函数处理passive motion事件。函数将改变angleX的值。
void processMousePassiveMotion(int x, int y) {
 
         // User must press the SHIFT key to change the 
         // rotation in the X axis
         if (specialKey != GLUT_ACTIVE_SHIFT) {
 
                 // setting the angle to be relative to the mouse 
                 // position inside the window
                 if (x < 0)
                          angleX = 0.0;
                 else if (x > width)
                          angleX = 180.0;
                 else
                          angleX = 180.0 * ((float) x)/height;
         }
}
最后鼠标离开窗口将使动画停止,为了做到这,我们也需要改变函数renderScene。
// initially define the increase of the angle by 1.0;
float deltaAngle = 1.0;
...
void renderScene(void) {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glPushMatrix();
         glRotatef(angle,0.0,1.0,0.0);
         glRotatef(angleX,1.0,0.0,0.0);
         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();
         // this is the new line
         // previously it was: angle++;
         angle+=deltaAngle;
         glutSwapBuffers();
}
processMouseEntry是最后一个函数。注意,这个在微软操作系统下可能工作的不是很好。
void processMouseEntry(int state) {
         if (state == GLUT_LEFT)
                 deltaAngle = 0.0;
         else
                 deltaAngle = 1.0;
}
VC6.0工程可以在这里下载(glut8.zip)。
 
(到这里位置,键盘,鼠标方面的控制讲完了,下面就是菜单了。)
(原文地址:http://www.lighthouse3d.com/opengl/glut/index.php?9)
 

OpenGL---GLUT教程(九) GLUT鼠标相关推荐

  1. c语言GLUT头文件下载,GLUT教程.pdf

    GLUT教程 GLUT教程 (一) 简介 为了用 GLUT 写一个 C 语言程序你需要有三个文件: 1:glut.h-这个头文件是要包含到你的代码里的去的.一般把这个文件放到.include/gl 文 ...

  2. OpenGL中常用的 GLUT 函数

    GLUT函数说明 一.初始化 void glutInit(int* argc,char** argv) 这个函数用来初始化GLUT库.对应 main 函数的形式应是: int main(int arg ...

  3. OpenGL 关于旧版glut和新版本glfw和glad的环境配置

    目录 一.OpenGL的环境: 1.OpenGL 2.gult:OpenGL工具库 OpenGL Utility Toolkit 3.glew 4.glfw 5.glad(2018.9) 二.旧版本 ...

  4. GLUT教程 - glutPostRedisplay函数

    http://www.cnblogs.com/live41/p/3395899.html [译]GLUT教程 - glutPostRedisplay函数 Lighthouse3d.com >&g ...

  5. OpenGL,glx,glaux,glut,freeglut,glew,glfw,mesa

    转自:http://www.lai18.com/content/1297257.html 一.OpenGL OpenGL函数库相关的API有核心库(gl),实用库(glu),辅助库(aux).实用工具 ...

  6. opengl库区分:glut、freeglut、glfw、glew、gl3w、glad

    opengl原生库 gl* 随opengl一起发布 opengl实用库 glu* 随opengl一起发布 opengl实用工具库glut glut* 需要下载配置安装(太老了!) opengl实用工具 ...

  7. OpenGL之路(一)OpenGL、gl、glu、glut的区别 + glut环境的搭建

    OpenGL中的gl库是核心库,glu是实用库,glut是实用工具库,gl是核心,glu是对gl的部分封装,glut是OpenGL的跨平台工具库,gl中包含了最基本的3D函数,而glu似乎对gl的辅助 ...

  8. OpenGL入门教程(转)

    OpenGL入门学习 说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640 ...

  9. NeHe OpenGL第二十九课:Blt函数

    NeHe OpenGL第二十九课:Blt函数 Blitter 函数: 类似于DirectDraw的blit函数,过时的技术,我们有实现了它.它非常的简单,就是把一块纹理贴到另一块纹理上. 这篇文章是有 ...

  10. NeHe OpenGL第十九课:粒子系统

    NeHe OpenGL第十九课:粒子系统 粒子系统: 你是否希望创建爆炸,喷泉,流星之类的效果.这一课将告诉你如何创建一个简单的例子系统,并用它来创建一种喷射的效果. 欢迎来到第十九课.你已经学习了很 ...

最新文章

  1. canvas 轮播图片
  2. Linux下的静态链接库和动态链接库编程
  3. 台湾游戏企业抢滩大陆 研发成竞争核心
  4. Access和sql server的语法区别
  5. oracle存储过程导出查询结果,ORACLE如何实现函数、包、存储过程的导入和导出
  6. 【大数据24小时】“天智一号”卫星将在太空计算数据;“电子身份证”亮相支付宝...
  7. Python学习2--体脂率计算
  8. 【多媒体基础知识】 --- 什么是流媒体技术
  9. SpringBoot @EnableAutoConfiguration exclude属性失效
  10. 阿里云服务器租用费用清单表(CPU内存带宽磁盘)
  11. 从欧盟与韩国实践看智慧城市的开放式治理创新模式
  12. IT资讯精选(2022-09-11)
  13. 京东,想说爱你,并不容易!
  14. UE4鼠标滚轮轴缩放事件设置无效
  15. 【音视频处理】为什么MP3不是无损音乐?音频参数详解,码率、采样率、音频帧、位深度、声道、编码格式的关系
  16. 第十六章:开发工具-traceback:异常和栈轨迹-底层异常API
  17. 代码传奇 | 身价10亿的程序员 雷军当年也为他打工——WPS之父 求伯君
  18. 油菜花系统服务器能删除内容吗,油菜花能吃吗,油菜花有什么用
  19. [转]鸡头,风尾,如何抉择,年终前跳槽的思考
  20. 软件开发外包管理的“一二四”

热门文章

  1. onmouseover、onmouseenter、onmouseleave、onmouseout的区别
  2. 伯努利分布期望,方差推导
  3. 要想文章上Google搜索引擎首页,SEO 要做好下面7个点优化
  4. 什么是交换?路由?路由交换?
  5. Uncaught TypeError: Cannot read property ‘dispatch‘ of undefined
  6. Python学习笔记(1)---B站黑马程序员
  7. 配置SqlServer发送邮件
  8. 关于pip下载很慢很慢
  9. STC89C52电子时钟
  10. 阶乘末尾 0 的个数.c