第三章一个简单的二维光栅图形软件包SRGP(SimpleRasterGraphicsPackage)目的:了解图形学的基本概念与方法主要内容3.1用图形软件包绘图3.2基本的交互处理3.3光栅操作应用模型应用程序SRGP图形硬件设备输出流输入流3.1用图形软件包绘图?图元的声明?图元的属性?填充图元及属性?保存和恢复图元的属性?字符•图元的声明–绘图纸,屏幕,–坐标系–扫描转换:将顶点(参数表示的图形)转换为点阵表示的图形扫描转换顶点(参数)表示的图形用户点阵表示的图形显示系统3.1.1图元的声明•基本图元:点、直线段、折线、多边形、圆弧、字符、标记符号。•数据类型:StructPoint{intx,y;}typedefint*VertexCoordList;typedefPoint*VertexList;VoidPutPixel(intx,inty,intcolor);//画点函数,color:颜色值。VoidLineCoord(intx0,inty0,intx1,inty1);VoidLine(Point*pnt0,Point*pnt1);//画线函数用端点描述直线段更自然、方便,故定义了一个名为Point的数据类型:Typedefstruct{intx,y}Point(1)点、直线段和折线VoidpolylineCoord(intvertexCount,VertexCoordListxArray,VertexCoordListyArray);Voidpolyline(intvertexCount,VertexListvertices)//画折线函数。•vertexCount为顶点个数,xArray,yArray为存储折线顶点的x坐标、y坐标的数组;vertices为Point类型的顶点数组(2)多边形和矩形VoidPolygonCoord(intvertexCount,VertexCoordListxArray,VertexCoordListyArray)VoidPolygon(intVertexCount,VertexListvertices);//画多边形。VoidRectangleCoord(intleftX,intbottomY,intrightX,inttopX)VoidRectanglePoint(Point*leftBottom,Point*rightTop);VoidRectangle(Rectangle*rect)//画矩形Typedefstruct{pointleftBottom,rightTop;}RectangleVoidCircleArc(Point*center,intradius,intstartAngle,intendAngle)//画圆弧VoidEllipseArc(Rectangle*externRect,intstartAngle,intendAngle)//画椭圆(3)圆弧和椭圆弧VoidMarkerCoord(intx,inty);VoidMarker(Point*pt);//端点做标记。VoidPolyMarkerCoord(intvertexCount,VertexCoordListxArray,VertexCoordListyArray)VoidPolyMarker(intvertexCount,VertexListvertices)(4)标记3.1.2图元属性(1)线型和线宽VoidSetLineStyle(enumLineStylelineStyle);VoidSetLineWidth(intlineWidth);枚举变量lineStyple预定义之线型CONTINUOUS、DASHED、DOTTED•图元在显示时被扫描转换成离散的像素写入显存,线型控制可看作有选择地写像素的位屏蔽器(bitmarker).--位屏蔽器为‘0’表示帧缓存中相应的像素值不变(即透明),为‘1’表示用线段的颜色值代替帧缓存中相应的像素值。SetLineWidth(1);LineCoord(55,5,105,295);//lineaSetLineStytle(DASHED);SetLineWidth(5);LineCoord(105,5,155,295);//linebSetLineWidth(10);SetLineStytle(DOTTED);LineCoord(155,5,255,295);//linec•SRGP中,设置颜色属性有三种方式:•三种指定颜色的方式–通过查色表索引值–通过颜色名称–通过红、绿、蓝三分量VoidSetColorByName(cnumColorscolorName);//使用逻辑颜色名,实际对应的颜色取决于系统查色表VoidSetColor(intcolorIndex);//直接使用整数值来指定,colorIndex即是指向查色表某表项的索引值VoidSetColor(intred,intgreen,intblue);//直接赋颜色分量值(对真彩色系统而言)(2)颜色3.1.3填充图元及其属性封闭的图元有二种绘制方式--线画图:只画出边框;--填充图:填充其内部区域;VoidFillRectangle(Rectangle*rec);//矩形VoidFillPolygon(intvertexCount,VertexListVertices);//多边形VoidFillEllipse(Rectangle*extentRect);//椭圆VoidFillEllipseArc(Rectangle*extentRect,intstartAngle,intendAngle);//扇形填充方式设置(控制填充图元的外观)VoidSetFillStyle(enumFillStylefillstyle)FillStyle定义如下:enumFillStyle{SOILD,//以当前前景色均匀填充图元BITMAP_PATTERN_OPAQUE,//以规则排列的位图填充;BITMAP_PATTERN_TRANSPARENT,PIXMAP_PATTERN}//以规则排列的像素图填充;位图:二值图像像素图:多值图像SRGP提供位图/像素图资源表以规则排列的位图填充BITMAP_PATTERN_OPAQUE//不透明方式对应位图中“1”的像素用前景色(即当前设定的颜色)显示;对应位图中“0”的像素用背景色显示。背景色由函数voidSetBackgroundColor(intcolorIndex)设定BITMAP_PATTERN_TRANSPARENT//透明方式对应位图中“1”的像素依然用前景色显示;对应位图中“0”的像素,颜色保持不变。无论是以位图还是像素图填充图元,图元所呈现的颜色总依赖于当前系统查色表的内容,因为位图/像素图中保存的仅仅是颜色的索引值。3.1.4保存和恢复图元的属性目的:为了提高程序的模块化程度……•VoidInquireAttributes(AttributeGroup*group);•VoidSetAttributes(AttributeGroup*group);//AttributeGroup为SRGP定义的结构,其中包括:前景色、背景色、线型、线宽、填充方式、查色表等SRGP支持的所有属性。3.1.5字符•属性:字体(宋体,楷体…)、字形(粗体,斜体…)、字型(7X9,16X24…)、字间距、行间距。•自学P88-90页内容字符的表示与输出•点阵字符的参数VoidOutText(Point*origin,char*text)//产生一个字符串,其中的x坐标标明串中第一个字符的左边界,y坐标确定基线位置。VoidSetFont(intfontindex)//设置当前的字体和字型?基本原则?逻辑输入设备?输入方式取样方式事件驱动方式?设置输入方式属性3.2基本的交互处理3.2.1交互系统设计的基本原则1.提供简单一致的交互操作序列;(menu,button…)2.交互的每一阶段,清晰显示可选项;3.样式简洁,选项有层次、简单;4.给用户适当的反馈(highlight,光标形状…);5.允许用户取消操作(Undo)解决方法:菜单、按钮、加亮、变灰、光标变化等等设备无关性与软件可移植性•SRGP所支持的逻辑输入设备有:定位设备、键盘设备。•逻辑输入设备到实际物理设备的映射由设备驱动程序完成3.2.2逻辑输入设备取样方法、事件驱动。取样输入设备的状态,效率不高,中断驱动:何时处理中断?增加程序设计难度事件驱动:后台监控程序,事件队列。主动处理。基于事件驱动方法的程序结构:初始化输入设备;do{waitEvent(event);switch(event){caseEVENT1:procedure1;break;caseEVENT2:procedure2;break;…;}}while(TRUE);3.2.3输入方式设置输入设备的输入方式VoidSetInputMode(enumDeviceinputDevice,enumInputModeintputMode)枚举变量Device与InputMode的定义为:enumDevice{LOCATOR,//定位设备KEYBOARD,//键盘设备…};enumInputMode{INACTIVE,//非激活状态SAMPLE,//取样方式EVENT};//事件驱动方式3.2.4取样方式•定位设备的输入信息分为三部分:(1)当前光标的位置(2)各个键的状态(UPorDOWN)(3)哪一个键的状态发生了变化•输入信息数据结构:Typedefstruct{Pointposition;//记录光标的位置enum{UP,DOWN}buttonChord[MAX_BUTTON_COUNT];//记录各个键的当前状态,通常为1~3个intbuttonOfMostRecentTransition;//指示哪个键改变了状态}LocatorMeasure;设置为取样方式后,可以这样获取状态信息VoidSampleLocator(LocatorMeasure,*measure)SetInputMode(LOCATOR,SAMPLE)//循环取样直到第一个键的状态为DOWNdo{SampleLocator(&locMeasure);}while(locMeasure.buttonChord[0]==UP);//记录上一次光标位置prevposit.x=locMeasure.position.x;prevposit.y=locMeasure.position.y;//绘图do{SampleLocator(&locMeasure);Line(&prevposit,&(locMeasure.position));prevposit.x=locMeasure.position.x;prevposit.y=locMeasure.position.y;}while(locMeasure.buttonChord[0]==DOWN);3.2.5事件驱动方式•键盘的处理方式:RAW和EDITVoidSetKeyBoardProcessingMode(enumKeyboardModekeyboardMode);当WaitEvent()返回值为KEYBOARD时,获取键盘内容:VoidGetKeyBoard(char*keyMeasure,intbufferSize);keyMeasure用于存放用户输入的字符串,bufferSize指示缓冲区keyMeasure的长度。•定位设备的事件:用户按键、释放键、移动定位设备获取定位设备事件内容:VoidGetLocator(LocatorMeasure*locMeasure);屏蔽其它键的干扰:VoidSetLocatorButtonMask(enumButtonMaskactiveButton);//定位设备反馈方式的设置VoidSetLocatorEchoType(enumEchoTypeechoType)echo