您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 其它文档 > 3.1输入与交互 计算机图形学 OpenGL 课件
计算机图形学杨武影像科学与技术实验室东南大学计算机学院yangwu@seu.edu.cn2第三章输入与交互3第三章之第一节简介4基本内容常见的输入设备–物理设备–逻辑设备–输入模式事件驱动的输入光滑动画中的双缓存用GLUT进行事件输入编程5Sketchpad项目IvanSutherland(MIT1963)建立了刻画交互式计算机图形学的基本交互框架:–用户在显示器上看到一个对象–用户利用输入设备(光笔、鼠标、跟踪球等)点选该对象–对象发生了改变(移动、旋转、变形等)–重复上述过程6图形输入设备输入设备可以用下述两种属性中的一种进行描述物理属性–鼠标键盘跟踪球逻辑属性–设备通过API返回给程序的内容是什么?•位置•对象标识7物理设备mousetrackballlightpendatatabletjoystickspaceball8输入值数据板等类似设备直接向操作系统返回位置类似于鼠标、跟踪球以及游戏操纵杆等设备向操作系统返回一个步进输入(即速度)–必须把这些输入累加在一起得到一个绝对位置•鼠标滚轮的旋转•跟踪球的滚动•难以得到绝对位置•输入可能相当敏感9逻辑设备考虑C与C++代码–C++:cinx;–C:scanf(“%d”,&x);输入设备是什么?–键盘、文件、…–不管物理设备是什么,程序得到一个数(int)作为输入10图形逻辑设备在GKS和PHIGS中,定义了六种逻辑输入:–定位:返回一个位置–拾取:返回对象的标识ID–字符串:返回字符串–笔划:返回位置数组–定值:返回浮点数–选择:返回n项中的一项11输入模式如何以及何时获取输入?–触发器(trigger)•向操作系统发送一个信息•鼠标上的按钮、键盘上的键–测量值•当触发后,输入设备向系统返回信息•鼠标返回位置信息•键盘返回ASCII代码–请求(主动)或者事件(被动)12请求模式只有当用户触发了设备后,输入才提供给程序典型例子:键盘输入13采样模式程序需要输入函数调用时,输入设备立刻返回测量值–要求之前已经将输入数据存入缓存14事件模式绝大部分系统具有多个输入设备,每个设备都可能被用户在任意时间触发每个触发生成一个事件,事件的测量值放到事件队列中,用户程序检查该队列15事件类型窗口:改变尺寸、重新显示、缩成图标鼠标:点击一个或多个按钮,移动键盘:按下或释放某个键空闲:“没有事件”–可以定义如果队列中没有其它事件就可以进行的某种操作16回调回调是事件驱动输入方式的程序界面为图形系统可以识别的每种类型事件定义一个回调函数当相应的事件出现时,就会自动执行用户指定的函数GLUT示例:glutMouseFunc(mymouse)鼠标回调函数17GLUT中的回调函数GLUT识别在各种窗口系统(Windows,X,Macintosh)中都有的一组事件–glutDisplayFunc–glutMouseFunc–glutReshapeFunc–glutKeyboardFunc–glutIdleFunc–glutMotionFunc,glutPassiveMotionFunc18GLUT中的事件循环记住:在任何利用GLUT的程序中,main()的最后一行实质语句必须是glutMainLoop();这条语句使得程序进入一个无穷的事件循环每经过事件循环一次,GLUT进行下述操作–查看事件队列中的事件–对于在队列中的每个事件,如果定义了相应的回调函数,GLUT就执行这个回调函数–如果对该事件没有定义回调函数,那么就忽略该事件19显示回调函数只要GLUT确定需要刷新窗口,那么就会执行显示回调函数,例如–第一次打开窗口–窗口形状改变–重新露出窗口–用户程序决定需要改变显示内容在main()中–glutDisplayFunc(mydisplay)确定要执行的显示回调函数–每个GLUT程序都必须有一个显示回调函数,必要时可以设置为空函数20标识重新显示许多事件都会导致调用显示回调函数–这会导致遍历一次事件循环的过程中多次执行显示回调函数可以用下列方法避免这个问题glutPostRedisplay();这条语句设置一个标志当事件循环结束时,GLUT会检查是否设置了上述标志如果设置了标志,那么就会执行显示回调函数21空闲回调的应用当在事件队列中没有事件时,就执行该回调函数–glutIdleFunc(myidle)–动画中非常有用voidmyidle(){/*changesomething*/t+=dtglutPostRedisplay();}voidmydisplay(){glClear();/*根据t绘制图形*/glutSwapBuffers();}22全局变量的应用所有GLUT回调函数的调用形式是固定的–voidmydisplay()–voidmymouse(GLintbutton,GLintstate,GLintx,GLinty)为了向回调函数传递信息,必须应用全局变量floatt;/*全局变量*/voidmydisplay(){/*根据t绘制图形*/}23动画当通过显示回调函数重新绘制显示结果时,我们通常会首先清除整个窗口:–glClear()然后再绘制已发生了变化的显示结果问题:帧缓冲区中的信息在显示器上的显示结果出现了错位–图形系统可以同时向显存中写入内容和从中读出内容24双缓存不只用一个颜色缓冲区,而是应用两个缓冲区–前缓冲区::显示它的内容,但不向它写入内容–后缓冲区:写入内容,不显示程序在main()中请求使用双缓存–glutInitDisplayMode(GL_RGB|GL_DOUBLE)–在显示回调函数结束之前,交换两个缓冲区voidmydisplay(){glClear();/*绘制图形*/glutSwapBuffers();}
本文标题:3.1输入与交互 计算机图形学 OpenGL 课件
链接地址:https://www.777doc.com/doc-5499736 .html