计算机图形学杨武影像科学与技术实验室东南大学计算机学院yangwu@seu.edu.cn2第三章之第三节交互程序设计3基本内容学会设计更复杂的交互程序,采用的方法为–选取•从显示结果中选择对象•三种方法–橡皮筋•直线与矩形的交互绘制方法–显示列表•图形的记忆模式4拾取(Picking)从显示结果中识别用户定义的对象原则上说要达到这个目标是很简单的,因为鼠标可以提供位置信息,我们因当能够根据位置确定对应的是哪个对象实际操作中的困难–离位置多近可以认为选择了对象?–流水线式的图形体系是单向的,很难从二维屏幕返回到三维世界5三种方法矩形映射–容易实现当绘制对象时,利用后缓冲区或者其它缓冲区存贮对象的标识击中(hit)列表–最一般性的方法,实现也最困难6很多应用程序利用简单的矩形区域将窗口分割–例如画图/CAD系统通过判断鼠标位置即可容易的得知选择对象利用屏幕区域绘画区域工具栏菜单7通过另外的缓冲区和颜色进行选取对于很少数目的对象,可以给每个对象赋以唯一的颜色(有时是在颜色索引模式中)然后把场景输入颜色缓冲区中,这样就不会看到显示出来的结果然后获到鼠标位置,利用glReadPixels()读取缓冲区中的颜色根据返回的颜色确定是哪个对象再用正常颜色绘制显示8显示输出模式利用glRenderMode(mode)可以设置OpenGL用下述三种模式显示内容–GL_RENDER:正常显示到帧缓冲区中(缺省模式)–GL_FEEDBACK:提供要显示的几何列表,但并不输出到帧缓冲区中–GL_SELECTION:在视景体中的每个几何体创建一个击中记录,这个记录放到名称堆栈中,稍后要被检测9选择模式中用到的函数glSelectBuffer():指定名称缓冲区glInitNames():初始化名称缓冲区glPushName(id):把id放到名称缓冲区中glPopName():将名称缓冲区顶部的名称弹出glLoadName(id):取代在名称缓冲区顶部的名称id是由应用程序设置,用以识别对象10选择模式的应用初始化名称缓冲区进入选择模式(例如:应用鼠标)显示输出场景,场景中对象具有用户指定的标识重新进入正常的显示输出模式–该操作返回击中对象个数检查名称缓冲区的内容(击中记录)–击中记录包含id与深度信息11选择模式与选取正如刚刚讲过的,在选择模式中不用进行选取,因为这时在视景体中的每个对象都会生成一个击中记录改变视图参数,使得只有靠近鼠标指针的对象位于新的视景体中–利用gluPickMatrix(…)12像素的写入模式帧缓冲区应用程序‘逐位逻辑操作13XOR写入模式缺省的写入模式是直接用源像素取代目标像素,即d’=s–不能绘制一条临时直线异或操作(XOR):d’=d⊕s–x⊕y⊕y=x–重画一遍就可以实现删除操作14橡皮筋式绘图切换到XOR写入模式绘制对象–固定线段的一个端点,然后再利用移动回调函数,连续更新第二个端点–移动时,重画原来的直线从而删除它–从固定端点到新端点之间画一条直线–最后,切换回到正常的绘图模式并绘制直线–也适用于其它对象:矩形、圆15橡皮筋型直线初始显示利用鼠标在XOR模式中画一条直线把鼠标移到新的位置第一个点第二个点原来的直线利用XOR重新画一遍新的直线利用XOR画出来16XORinOpenGL在两位之间有16种可能的逻辑操作OpenGL支持所有的这16种操作–必须首先启动逻辑操作•glEnable(GL_COLOR_LOGIC_OP)–然后选择逻辑操作类型•glLogicOp(GL_XOR)•glLogicOp(GL_COPY)(default)17快速模式与记忆模式注意:在标准的OpenGL程序中,一旦某个对象被显示输出,对它没有任何记忆;为了重新显示它,需要再执行一次相应的代码–这就是快速模式(immediatemode)的图形–如果对象相当复杂,而且通过网络传输,那么这就可能导致系统非常慢另外一种模式就是首先定义对象,然后以某种形式把它记忆下来,从而更容易重新显示–这就是记忆模式(retainedmode)的图形–在OpenGL中是通过显示列表实现的18显示列表从概念上类似于图形文件–必须首先定义列表的名称并创建它–向列表中添加内容–关闭列表在客户-服务的体系环境中,显示列表是放在服务器(显示服务器)一方–这样不必通过网络每次发送原来的几何定义就可以重新显示19显示列表中用到的函数创建显示列表GLuintid;voidinit(void){glNewList(id,GL_COMPILE);/*otherOpenGLroutines*/glEndList();}调用已创建的显示列表voiddisplay(void){glCallList(id);}20显示列表中的状态绝大多数OpenGL函数都可以放在显示列表中在显示列表中发生的状态改变在列表执行结束后仍然起作用可以通过刚进入显示列表时调用glPushAttrib和glPushMatrix,执行结束之前调用glPopAttrib和glPopMatrix避免这个问题21层次体系与显示列表•考虑一个汽车模型为底盘创建显示列表为车轮创建显示列表glNewList(CAR,GL_COMPILE);glCallList(CHASSIS);glTranslatef(…);glCallList(WHEEL);glTranslatef(…);glCallList(WHEEL);…glEndList();22GUI发展历史1945Bush,“aswemaythink”中描述了“Memex”设备,理念阶段1963Sutherland,“Sketchpad”计划,构建了交互式图形系统框架Engelbart,“NLS”系统1968NLS系统键盘及鼠标23GUI发展历史1970施乐(Xerox),帕罗奥托研究中心AlanKay提出了Smalltalk,第一个面向对象编程语言StarAlto19731976Apple公司1983,Lisa界面24GUI发展历史19801983,windows原型1987,windows2.01984,Macintosh1987,Arthur1988,IBMOS2/1.01985,Amiga100025GUI发展历史19901990,MicrosoftWindows3.01992,IBMOS2/2.01995,Windows951995,Be,BeOS26GUI发展历史20002001,MicrosoftWindowsxp2000,AppleMacOSX27人机交互设计理念窗口和图标适应不同熟练程度的用户一致性容易记忆容错处理反馈28搬家公司29实例30网上花店31影院公告上映什么电影?什么时间?32重新设计以电影为单位来组织33列车时刻表34交互进展多通道交互虚拟现实与三维交互可穿戴计算与移动手持设备…35作业2绘制一个分形图案,具有拾取和拖动的交互功能。