1. 首页
  2. 文档大全

第3章图形学输入与交互

上传者:9****8 2022-07-20 21:48:30上传 PPT文件 671.51KB
第3章图形学输入与交互_第1页 第3章图形学输入与交互_第2页 第3章图形学输入与交互_第3页

《第3章图形学输入与交互》由会员分享,可在线阅读,更多相关《第3章图形学输入与交互(66页珍藏版)》请在文档大全上搜索。

1、第三章输入与交互基本内容常见的输入设备物理设备逻辑设备输入模式事件驱动的输入光滑动画中的双缓存用GLUT进行事件输入编程Sketchpad项目Ivan Sutherland (MIT 1963年)建立了刻划交互式计算机图形学的基本框架: 用户在显示器上看到一个对象用户利用输入设备(光笔、鼠标、跟踪球等)点选该对象对象发生了改变(移动、旋转、变形等)重复上述过程图形输入设备输入设备可以用下述两种属性中的一种进行描述述 物理属性鼠标键盘跟踪球逻辑属性设备通过API返回给程序的内容是什么?位置对象标识模式如何以及何时获取输入?请求(主动)或者事件(被动)物理设备物理设备输入值 类似于数据板等设备直接

2、向操作系统返回位置 类似于鼠标、跟踪球以及游戏操纵杆等设备向操作系统返回一个步进输入(即速度)必须把这些输入累加在一起得到一个绝对位置 鼠标滚轮的旋转 跟踪球的滚动 难以得到绝对位置 输入可能相当敏感逻辑设备 考虑C与C+代码: C+: cinx; C: scanf(”%d”, &x); 输入设备是什么? 代码中并没有指明 可以是键盘、文件、或者其它程序的输出 上述代码要求的是就是逻辑输入 不管物理设备是什么,程序得到一个数(int)作为输入图形逻辑设备 相对于在标准程序中的输入通常只是数字、字 符或者字节而言,图形输入的形式更多 在GKS和PHIGS这两个老的API中,定义了六 种类

3、型的逻辑输入: 定位:返回一个位置 选取:返回对象的标识ID 键盘:返回字符串 轨迹:返回位置数组 求值:返回浮点数 选择:返回n项中的一项X Window的输入 在X Window系统中引入了适用于工作站网络的 客户-服务模型 客户 client: OpenGL程序 图形服务器:具有点选设备和键盘的位图显示设备客户-服务体系输入模式 在输入设备中具有一个触发器(trigger), 它可以向操作系统发送一个信息 鼠标上的按钮 按放键盘上的键 当触发后,输入设备向系统返回信息(相 应的度量) 鼠标返回位置信息 键盘返回ASCII代码请求模式 只有当用户触发了设备后,输入才提供给程序 键盘输入为典

4、型例子 在按回车键(触发器)之前,可以删除(回退)、编辑、修 改输入的信息事件模式 绝大部分系统具有多个输入设备,每个设备都 可能被用户在任意时间触发 每个触发生成一个事件,事件的度量信息放到 事件队列中,用户程序检查该队列事件类型 窗口:改变尺寸、重新显示、缩成图标 鼠标:点击一个或多个按钮,移动 键盘:按下或释放某个键 空闲:“没有事件” 可以定义如果队列中没有其它事件就可以进行 的某种操作回调 回调是事件驱动输入方式的程序界面 为图形系统可以识别的每种类型事件定义 一个回调函数 当相应的事件出现时,就会自动执行用户 指定的函数 GLUT示例 glutMouseFunc(mymouse);

5、GLUT中的回调函数 GLUT识别在各种窗口系统(Windows, X, Macintosh)中都有的一组事件 glutDisplayFunc glutMouseFunc glutReshapeFunc glutKeyboardFunc glutIdleFunc glutMotionFunc glutPassiveMotionFuncGLUT中的事件循环 记住: 在任何利用GLUT的程序中,main()的最 后一行实质语句必须是 glutMainLoop(); 这条语句使得程序进入一个无穷的事件循环 每经过事件循环一次,GLUT进行下述操作 查看事件队列中的事件 对于在队列中的每个事件,如果定

6、义了相应的回调函数, GLUT就执行这个回调函数 如果对该事件没有定义回调函数,那么就忽略该事件显示回调函数 只要GLUT确定需要刷新窗口,那么就会执行 显示回调函数,例如 当第一次打开窗口的时候 当改变了窗口形状的时候 当重新露出了窗口的时候 当用户程序决定需要改变显示内容的时候 在main()中, glutDisplayFunc(mydisplay)确定要执行的显示 回调整函数 每个GLUT程序都必须有一个显示回调函数,必要时可 以设置为空函数标识重新显示 许多事件都会导致调用显示回调函数 这会导致遍历一次事件循环的过程中多次执行显示回调 函数 可以用下列方法避免这个问题 glutPost

7、Redisplay(); 这条语句设置一个标志 当事件循环结束时,GLUT会检查是否设置了上 述标志 如果设置了标志,那么就会执行显示回调函数动画 当通过显示回调函数重新绘制显示结果时,我 们通常会首先清除整个窗口: glClear() 然后再绘制已发生了变化的显示结果 问题:帧缓冲区中的信息在显示器上的显示结 果出现了错位 图形系统可以同时向显存中写入内容和从中读出内容 从而我们会看到部分显示内容 例:single_double.c 旋转的立方体 显卡若启动了硬件加速功能,不会发现上述问题双缓存 不只用一个颜色缓冲区,而是应用两个缓冲区 前缓冲区:显示它的内容,但不向它写入内容 后缓冲区:写

8、入内容,不显示 程序在main()中请求使用双缓存 glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE) 在显示回调函数结束之前,交换两个缓冲区 void mydisplay() glClear(); / 绘制图形 glutSwapBuffers(); 空闲回调的应用当在事件队列中没有事件时,就执行该回调函数glutIdleFunc(myidle)在动画中非常有用void myidle() /改变一些内容t += dt;glutPostRedisplay();void mydisplay() glClear();/ 根据t绘制图形glutSwapBuffers()

9、;全局变量的应用 所有GLUT回调函数的调用形式是固定的 void mydisplay(); void mymouse(GLint button, GLint state, GLint x, GLint y); 为了向回调函数传递信息,必须应用全局变量 float t; /全局变量 void mydisplay() /根据t绘制图形 回调的应用 利用GLUT回调函数设计交互程序 鼠标 键盘 改变窗口形状 在GLUT中定义菜单鼠标回调函数 glutMouseFunc(mymouse) void mymouse(GLint button, GLint state, GLint x, GLint y

10、) 其中button的值可能是 GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON 表示哪个按钮导致了事件发生 state表示相应按钮的状态: GL_UP, GL_DOWN x, y表示在窗口中的位置定位在屏幕上的位置通常是以像素为单位的,原点在左上角 因为显示器自顶向下刷新显示内容 在OpenGL中应用一个世界坐标系,其原点在左下角 在这个坐标系中的y坐标需要从窗口高度中减去回调函数返回的y值:y := h-y获取窗口尺寸 为了完成y坐标的转换,需要知道窗口的 尺寸 在程序执行过程中高度可能发生改变 需要利用一个全局变量跟踪其变化

11、新高度值返回给形状改变回调函数(见后) 也可以用查询函数glGetIntv和 glGetFloatv获取,因为高度是状态的一部 分结束程序 在以前的程序中没有办法通过OpenGL结 束当前程序 可以利用简单的鼠标回调函数做到这一点 void mouse(GLint btn, GLint state, GLint x, GLint y) if(btn=GLUT_RIGHT_BUTTON & state = GLUT_DOWN) exit(0); 鼠标位置的应用 在要构造的例子中,每单击一次鼠标左按 钮,就会在当前鼠标位置处画一个小方框 在这个例子中并没有用到显示回调函数, 但是由于GLU


文档来源:https://www.renrendoc.com/paper/212713620.html

文档标签:

下载地址