Windows图像编程概要

图形设备接口(GDIGraphics Device Interface)的主要目标之一是支持在输出设备(如视频显示器、打印机和绘图仪)上的与设备无关的图形。 GDI通过将应用程序与不同输出设备特性相隔离,使Windows应用程序能够毫无问题地在Windows支持的任何图形输出设备上运行。Windows中的图形基本上是由从GDIEXE模块中输出的函数处理的(尽管一些绘制函数实际上具有USEREXE的入口点),GDIEXE模块调用在不同驱动程序文件中的例程,其中有一个.DRV驱动程序文件用于控制显示屏幕,并且可能有一个或多个其他的.DRV驱动程序文件用来控制打印机或绘图仪。Windows GDI使用两种坐标系统。使用虚拟坐标系统可以使程序不依赖于具体的硬件,使用设备坐标系统可以使程序和硬件紧密相联。GDI含有在Windows应用程序内部执行、且与设备无关的图形操作函数,这些函数可产生各种各样的线、正文和位图,它们可以输出到许多不同的输出设备上。GDI允许一个应用程序产生笔、刷子、字体和位图,以供特定的输出操作使用。下面列出GDI中几组比较常用的函数:

·设备上下文函数

·椭圆和多边形函数

·绘图工具函数

·位图函数

·绘图属性函数

·正文函救

·映射函数。

·坐标函数

·元文件(metafile)函数

·区域函数

·裁剪(clipping)函数·

窗口应用程序输出图形的操作步骤如下:

①取得指定窗口的当前显示设备上下文,显示设备上下文实际上是一个数据结构,它包括该窗口的参数及各种图形、文字属性的现行设定值,它们对以后的图形、文字输出命令起控制作用。

②选择用户坐标系及映射方式。

③设定用户坐标系中的观察窗口和设备坐标系中的显示视区。

④输出图形、文字和图象。

⑤释放所使用的显示设备上下文。

当想要在图形输出设备(例如屏幕或打印机)上绘制图形时,必须首先获得设备上下文的句柄。先给出这个句柄,Windows才允许程序使用设备,在GDI函数中将句柄作为一个参数传入,向Windows标明需要使用的设备。设备上下文中包含许多属性,当GDI在不同的设备上工作时都要用到这些属性。使用这些属性可使GDI只关心起始和终止坐标的大小,而不必关心有关对象的其他属性,如颜色、背景等等,因为这些都是设备上下文的一部分。当需要修改这些属性时,只需调用一个修改设备上下文中属性的参数,以后的程序中都使用修改后的设备上下文属性。设备上下文是连接Windows应用程序、设备驱动程序以及输出设备的纽带。获取设备上下文句柄有多种方法。最一般的方法是当处理一条消息时获得了设备

上下文、并在退出窗口之前释放它。一般的处理方法如下:

在处理WM_PAINT消息时

case WM_PAINT

hdc=BeginPainthwnd&ps

         //代码

EndPaint hwnd&ps);

其数据结构为:

HDC hWnd

PAINTSTRUCT ps

而在windowsh中定义了PAINTSTRUCT的数据结构。

type struct tagPAINTSTRUCT {

HDC hdC

BOOL fErase

RECT rcPaint

BOOL fRestore

BOOL flncUpdate

BYTE rgbReserved[16]

PAINTSTRUCT

其中,hdc用于标识显式上下文,fErase指出背景是否重画,rcPaint是涂色矩形,其余的域均为保留。这里的hdcBeginPaint返回的设备上下文句柄,有了从BeginPaint获取的设备上下文句柄,就可以也只能在ps指出的rcPaint的矩形内绘图,EndPaint调用使这一区域有效。

第二种方法如下所示,使用这种方法获取和释放设备上下文可以在整个用户区内画图,图形在整个用户区域内都有效:

hdCGetDc hwnd );

…画图操作…

ReleaseDC hwnd hdc );

使用下面第三种方法获取和释放设备上下文,可以在整个窗口内画图,图形在整个窗口内有效:

hdC=GetWindowDchwnd);

…画图操作…

ReleaseDchwndhdc);

使用下面第四种方法获取和释放设备上下文,可以在整个显示器区域内画图,图形在整个显示器区域内部有效:

hdcCreateDC lpszDriver lpszDevice lpszOutput lpData);

…画图操作…

ReleaseDChdc);

其中lpszDriver指向设备驱动程序的DOS文件名(不带扩展名),lpszDevice指向专用设备名(例如Epson Fx-80),lpszOutput指向物理输出介质(文件或输出端口)的DOS文件名或设备名,lpData指向含有设备驱动程序的设备专用的初始化数据的DEVMODE数据结构。例如:

hdcCreateDC"DISPLAY"NULLNULLNULL);

使用屏幕画图,而:

hdc= CreateDC "IBMGRX""IBM Graphics""LPT1"NULL );

在打印机上输出图形,这里的lpData置为默认值,可以在WININI中找到初始化值。如果不需要获取设备上下文,即不需要在设备上下文中操作,只需了解有关设备上

下文的信息,可以用如下语句:

hdcInfo CreateDC lpszDriver lpszDevicelpszOutput lpData );

 

……

DeteteDC hdcInfo);

另外,还可以使用设备上下文来对位图的内存进行控制,如下所示:

hdcMem CreateCompatibleDC hdc

DeleteDchdcMem );

一个元文件是以二进制形式编码的GDI调用集合,可通过获取一个元文件设备上下文来建立一个文件:

hdcMeta=CreateMetaFilelpszFilename);

……

hmf=CloseMetaFilehdCMeta);

在元文件设备上下文有效期间,使用hdcMeta所进行的任何GDI调用都成为元文件的一部分,当调用CloseMetaFile时,设备上下文句柄变化无效,函数返回元文件(hmf)的句柄。一个设备上下文通常涉及物理设备,如视频显示器、打印机等,所以需要获取有关该设备的信息,如显示器大小和彩色能力等。可以通过调用GetDeviceCaps函数来获取这样的信息:nValue=GetDeviceCaps hdcnIndex);

这里的hdc标识设备上下文,nIndex确定返回值,它可以是windowh中所定义的28个标识符中的一个,例如nIndex=DRIVEVERSION,则该函数返回的是版本号。真正影响在用户区域上绘制过程的设备上下文属性是“映射方式”,与映射方式属性密切相关的还有如下四个设备上下义属性:窗口原点、视窗原点、窗口范围和视窗范围。Windows定义了八种映射方式。可以调用函数setMapModehdcMapMode)来设置这八种映射方式中的一种。hdc用来标识设备上下文,nMapMode可以取MM_TEXTMM_LOMETRICMM_HIMETRIC等八个中的一个。在设置了映射方式之后,到下一次设置映射方式之前,Windows一直使用

这种映射方式。如果想要获取当前的映射方式,可用:

nMapMode GetMapMode hdc

在设置了映射方式之后,就规定了逻辑单位的大小和增量的方式,在GDI画图函数中,可以不必考虑这些内容而直接使用逻辑数字,如:

SetMapModehdc MM_TEXT);

TextOuthdc8 16szBuffer nLength

即正文从用户区域左起第八个象素,顶边起第16个象素的位置开始写操作。不管映射方式如何,Windows函数中所有坐标规定为-32768 32767之间的带符号短整救。注意映射方式只是一个设备上下文属性,因此映射方式唯一起作用的是将映射方式作为设备上下文句柄属性,而将该句柄当作参数的GDI函数,因此象GetSystemMetrics这样的非GDI函数,将继续以设备单位(象素值)返回尺寸值。

GDISetPixel函数可以绘制一特定颜色的象素:

rgbActualColor SetPixel hdcxyrgbColor);

这里hdc标识设备上下文,x y表示点坐标,rgbColor为一无符号的长整数,其结构为:COLORREF rgbColor

其中低位字节为红基色的相对亮度值,第二个字节包含绿基色的相对亮度值,第三个字节包含蓝基色的相对亮度值,高位字节必须为零。可以使用RGB函数来获取rgbColor

rgbColor RGBbyRed byGreenbyBlue);

这里的byRedbyGreenbyBlue取值范围为0255,分别代表红色、绿色、蓝色的亮度。给出正确的参数之后,SetPixel返回的是调色板中最靠近所需彩色的颜色。还可以使用如下方法来取得一个特定象素的颜色:

rgbCotor= GetPixelhdcxy);

画线函数主要有三种, LineToPolyline Arc。还有五个设备上下文属性会影响这些函数画出的线的外观:笔的当前位置(仅对LineTo有影响)、笔、背景方式(对非实心笔有影响)、背景颜色(对 OPAQUE背景方式)以及绘制方式。在这些设备上下文的属性中,笔的当前位置影响画线的起点,笔影响线的粗细等形状,背景方式影响非实心笔画出的线的模板图形,背景颜色影响线模板背景色,绘制方式影响实心线、虚线等线属性。

以下是典型的画线操作步骤:

MoveTohdcxStartyStart);

LineTohdc xEnd yEnd);

上面两句画出一条从(xStartyStart)到(xEndyEnd)的直线。

可以使用语句:

dwPoint GetCurrentPosition hdc);

获得笔的当前位置。这里,dwPoint返回值是一个无符号长整数(或双倍长字),其中低位字含有X坐标,高位字含有Y坐标。可以使用MAKEPOINT函数将dwPoint转换为POINT结构;

point = MAKEPOINT dwPoint);

point的类型为POINT:

typedef struct togPOINT {kk1}

int x

int y

POINT

Polyline用于绘制折线,例:

Polylinehdc&pt5

将数组pt中的5个点之间用线段相连。                

Arc用于画椭圆的周边:

Arc hdcxLeftyTopxRightyBottomxStartyStartXEndyEnd );

画出的椭圆以左上角为(xLeftyTop),右下角为(xRightyBottom)的矩形为界,圆弧开始于椭圆和(xStartyStart)与椭圆中心的连线的交点处,沿着椭圆周边的过时针方向绘制,并终止于椭圆和(xEndyEnd)与椭圆中小的连线的交点处。当调用LineToPolylineArc时,Windows使用当前在设备上下文中选择的笔来画线,笔决定了线的颜色、密度和型式,而线型可以是实线、点线或短划(虚)线,缺省设备上下文中的笔叫做BLACK_PEN,不管映射方式如何选支笔以一个象素的宽度画黑色的实线, BLACK_PENWindows提供的三支“备用笔”之一,其他两支是WHITE_PENNULL_PENNULL_PEN是一支什么都不画的空笔,当然用户也可以自己建立定制的笔。可以通过一个句柄来引用所需的笔:

HPEN hPen

hPen GetStockObjectWHITE_PEN);

SelectObjecthdc hPen

调用GetStockObject获得一支备用笔(WHITE_PEN)的句柄,调用SelectObject使这支笔成为设备上下文中当前选择的,用CreatePenCreatePenIndirect函数建立一支“逻辑笔”,这逻辑笔只是一支笔的描述。

hPen = CreatePen nPenStyle nWidth rgbColor );

其中nPenStyle参数确定笔是绘制实线还是由点或短划组成的线。该参数可取下

列标识符之一: PS_SOLIDPS_DASHPs_DOTPS_DASHDOT PS_DASHDOT DOTnWidth表示笔宽(采用逻辑单位),rgbColor表示笔的颜色,如果函数执行成功,则返回值标识一支逻辑笔,否则返回值为NULL。另外还有一种方法来建立逻辑笔:

typedef struct tagLOGPEN { kk1}

POINT lopnWidth

COLORREF lopnColor

LOGPEN

以上是Windows h中对LOGPEN结构的定义。lopnStyle规定笔的型式,lopnWidth规定笔的宽度,lopnColor规定笔的颜色。然后将logpen定义为LOGPEN类型:LOGPEN logpen;再使用hPen CreatePenlndirect (&logpen);就可以建立自定义的笔了。因为用以上两种方式建立的笔不是设备上下文有关的,所以可以同时建立多支笔,并用多支笔画图。

hpenl CreatePenPS_SOLID10L);

hpen2CreatePenPS_SOLID3RGB2550255)),

selectObject hdc hpenl

//LineTo调用

SelectObject hdc hpen2

//Polyline调用

DeleteObjecthpenl);

DeleteObjecthpen2);

在点线笔和短划笔的空隙间的着色取决于设备上下文中定义的背景方式和背景颜色这两种属性。缺省的背景方式是 OPAQUE ,即用背景颜色来填充空隙,缺省的背景颜色是白色。可用:

SetBkColor hdcrgbColor );

来改变填充空隙的背景颜色。可用:

SetBkModehdcmode);

来改变背景方式,这里的mode可为OPAQUETRANSPARENT

在设备上下文中可设置口种新的绘制方式。nDrawMode参数定义绘制方式。可用下

列函数获得当前绘制方式

nDrowMode GetRop2 hdc);

使用这种绘制方式实际上是在笔的象素和目标显示表面的象素之间执行一种逐位布尔运算。

下面列出了Windows的六个函数,用于绘制带有边框的填充区域:

Rectangle 带有方形角的矩形

Ellipse 椭圆

RoundRect 带有圆形角的矩形

Chord 在椭圆周边上的弧,其断 . 点用一条弦相连接

Pie 在椭圆周边上的饼形楔

Polygon 多边形

PolyPolygon 多个多边形

图形要用设备上下文中选择的当前刷子进行填充, 例:

HBRUSH hBrush

hBrushGetStockObjectGRAY_BRUSH

SelectObject hdchBrush

对于矩形填充对象,使用:

RectanglehdcxLeftyTopxRightyBottom);

点(xLeftyTop)是矩形的左上角,而(xRightyBottom)是右下角(这两点均以逻辑坐标给出)。同时还要考虑这两点坐标的合理性,例如,在MM_TEXT映射方式下,xRight必须大于xLeftyBottom必须大于yTop

对于椭圆填充对象,使用:

EllipsehdcxLeftyTopxRightyBottom);

画圆角矩形的填充对象,使用:

RoundRect hdcxLeftyTopxRightyBottomxCornerEllipseyCornerEllipse);

rgbColor为指定刷子的前景颜色,即阴影线的颜色。

③第三种方法:

hBrush = CreatePatternBrush ( hBitmap )

本函数建立一把具有由hBitmap参数指定图案的逻辑刷子,该刷子以后可被任何支持光栅操作的设备所选用。hBitmap标识位图,该位图可用函数CreateBitmapCreateBitmapIndirectLoadBitmapCreateCompatibleBitmap创建。用于填充图案的位图的最小尺寸为8×8

④第四种方法:

hBrush = CreateBrushIndirect ( &logbrush )

变量logbrush为一个LOGBRUSH(“逻辑刷”)类型的结构。建立了逻辑刷子之后,可以使用:SelectObject (hdc hBrush )

将逻辑刷送入设备上下文中。如果使用结束,可以用:

DeletObject (hBrush )

删除一把已建立的刷子,如果在程序中需要获取有关于刷子的信息,则可以调用:

GetObject (hBrush sizeof (LOGBRUSH ) (LPSTR ) & (logBrush ) )

其中logbrush为一个LOGBRUSH类型的结构。

前面提到使用位图作为逻辑刷子的图案,这样就需要一个位图的句柄。位图必须至少是8象素高和8象素宽,如果位图太大,Windows就取位图的左上部分作为刷子。获取位图句柄也有四种方法。

①获取位图句柄的第一种方法是:

首先用Windows提供的SDKPAINT生成一个位图文件(扩展名为.BMP),并把文件名包括在资源文件(.rc文件)中的一个BITMAP语句中,如:lpszBitmap BITMAP " BitmOPNameBmp"(假设SDKPAINT中产生的位图名为BitmapNameBmp),然后将位图装入:

hBitmap = LoadBitmap (hInstance lpszBitmap )

这里hBitmap即为位图句柄。

②第二种获取位图句柄的方法是:

hBitmap= createBitmapnWidthnHeight nPlanes nBitsPixellpBits);

本函数可生成一个具有指定的宽度、高度和位图案(bit pattern)并与设备有

关的内存位图。其中的参数nWidth指定位图的宽度(以象素为单位),nHeight

指定位图的高度(也以象素为单位),nPlanes指定位图中的彩色位平面的个数,

每个彩色位平面有nWidthXnHeight XnBitsPixel位。

nBitsPixel指定每个显示象素的颜色位数。lpBits指向一个含有初始位图位值的

短整型数组,它的值与BITMAP结构中的bmBits值相类似,有关BITMAP结构的内容

已在前面的章节中提到。

③第三种获取位图句柄的方法:

hBitmap= CreateCompatibleBitmap hdcnWidthnHeight);

本函数生成一个与由hdc参数指定的设备相兼容的位图,此位图具有与其他设备

相同数值的彩色位平面或相同的每象素位数的格式。它的彩色信息同样由hdc

定的设备所确定。hdc标识设备上下文,nWidthnHeight分别指定位图的宽和高

(以位数表示)。

④第四种获取位图句柄的方法:

hBitmop CreateBitmapIndirect (&bitmap):

本函数生成一个具有由lpBitmap参数所指定的数据结构给出的宽度、高度和位图图案的位图。这里的bitmap的结构为BITMAP类型。当拥有一个位图句柄之后,还可以调用:GetObjecthBitmapsizeofBITMAP),(LPSTR)&bitmap);来获得有关位图的信息,这里返回的bitmap为一个BITMAP类型的结构。还可以调用:GetBitmapBits hBitmapdwCountlpBits);

将位图hBitmapdwCount个字节复制到地址为lpBits的数组中。同样还可以使用

SetBitmopBits hBitmapdwCountlpBits);将 lpBits 标识的彩色位值放置到 hBitmap 标识的位图中去。

Windows用刷子填充一个区域时,它在水平和垂直两个方向上重复地使用8×8位图,刷子的外观可能会有细微的变化,这取决于Windows如何将位图的左上角与显示表面对齐,设备上下文中将这种对齐的属性称为“刷子原点”。大多数情况下,绘图时不必如此精细地调整刷子原点;但在某种情况下,为了产生某种特定的视觉效果,需要这么做。可以通过下面步骤来达到这个效果:

①对刷子调用UnrealizeObject(但不能对备用刷子调用UnrealizeObject);UnrealizeObjecthObject );此函数表示GDI在下次给定的刷子被选中时,使它的原点复位。

②用SetBrushOrg设置刷子原点:

BrushOrgSetBrushOrghDcx y);。

此函数用于设置当前选人给定的设备上下文中的刷子的原点。其中,hDc标识设

备上下文,x规定新原点的x 坐标(采用设备坐标),该值范围必须在07之间,

y规定新原点的y坐标(采用设备坐标),该值范围必须在07之间,该函数返回

一个双字,先前的x坐标放在低位字,先前的y坐标放在高位字。

除了画点、画线、区域填充这些绘图函数之外,Windows还包括几个附加的绘

 

图函数,用以处理RECT(矩形)结构和“区域”,区域是屏幕的一个由矩形、

其他多边形和椭圆组合而成的部分。

FillRecthdc ,&recthBrush);

此函数是用选定的刷子填充给定的矩形,FillRect函数填充整个矩形,还包括

左边线和顶边线,但不包括右边线和底边线。hdc标识设备上下文,rectRECT

数据结构类型,此数据结构存放要填充的矩形的逻辑坐标。hBrush用来标识填充

此矩形的刷子。

FrameRect hdc ,&rect);

本函数在 lpRect 参数指定的矩形周围画出一个边框,FrameRect 函数采用给定

 

的刷子绘制边框,边框的高和宽总是用逻辑单位表示。hdc标识窗口的设备上下

文, rect 标明左上角和右下角的逻辑坐标,hBrush标识画矩形边框用的刷子。

InvertRect hdc,&rect);

该函数反视频显示给定矩形的内容。

前面提到的rect可用以下语句取得:

SetRect(&rectxLeftyTopxRightyBottom);

区域用以描述显示器上的一个由矩形、其他多边形和椭圆组合而成的部分、可以

用区域进行绘制或裁剪。

可用:

hRgnCreateRgnxLeftyTopxRightyBottom);

 

hRgn CreateRectRgnIndirect (&rect );

来建立矩形区域,也可以用:

hRgn= CreatEllipseRgn xLeftyTopxRightyBOttom);

或:

hRgn CreateEllipseRgnIndirect (&rect);

来建立椭圆形区域;还可以用:

hRgnCreatePolygonRgn UpointnCountnPolyFillMode);

来建立多边形区域,用:

hRgnCreateRoundRectRgnxlylx2y2x3y3);

来建立一个带有圆角的矩形区域,(xly1)表示区域左上角,(x2y2)表示

 

区域右下角,x3y3分别用于指定产生圆角的椭圆的宽度和高度。

各个特定区域的句柄产生之后,

还可以使用:

nRgnType= CombineRgn hDestRgnhSrcRgnlhSrcRgn2nCombine);

通过组合两个已存在区域而产生一个新的区域。组合区域的方法由nCombine参数

加以说明:

这里的hSrcRgnlhSrcRgn2标识两个已存在的区域,hDestRgn标识将被新区域替

换的作为目标的已存在区域。

一个区域用完后,可用DeleteObjecthRgn)删除它。

FloodFiLL hdcxStartyStartrgbColor);

 

本函数用当前刷子填充显示表面的一个区域,该区域假定由rgbColor多数指定的

颜色边界确定,FloodFill函数由xStartyStart参数指定的,点开始向各个方向

进行填充,直到颜色边界为止。

ExtFLoodFillhdcxStartyStartrgbColorwFill );

此函数用当前刷子填充显示表面上的某一区域,若wFill被设置成

FLOODFILLBORDER

此区域将完全用rgbColor设定的颜色作为边界,ExtFloodFill从(xStart

yStart

点开始向各个方向填充,直到该颜色边界为止。若wFill被设置成

FLOODFILLSURFACE

 

ExtFLOODFILL函数从(xStartyStart)点开始,向各个方向对所有包含由

rgbColor参数设定的颜色的相邻区域进行填充。

DrowIconhdcxStortyStarthIcon

本函数在指定设备上画一个图标。(xStartyStart)为图标的左上角,hIcon

识要画的图标,它与hBitmap一样,可以由SDKPAINT画出,在. rc文件中定义,

LoadIcon获得。

ScrollWindow hwndxScrollyScroll&rectScroll,&rectClip

本函数通过移动一个窗口用户区域的内容来滚动该窗口,沿X轴移动xScroll个单

位,

 

沿Y轴移动yScroll个单位,rectScroll表示用户区域要滚动的那一部分内容,

rectClip表示要滚动的裁剪矩形。

ScrollDChdcdxdylprcScrolllprcClip hrgnUpdatelprcUpdate

此函数水平地和垂直地滚动由位构成的矩形。lprcScroll指向要滚动的矩形,

dx表示水平滚动单位,dy表示垂直滚动单位,lprcClip指向裁剪矩形,

hrgnUpdate

返回滚动过程没有覆盖的区域,lprcUpdate返回需要重画的最大矩形区域。

OpenGL是近几年发展起来的一个性能卓越的三维图形标准,它是在SGI等多家

 

界闻名的计算机公司的倡导下,以SGIGL三维图形库为基础制定的一个通用共享

的开放式三维图形标准。目前,包括MicrosoftSGIIBMDECSUNHP等大公

司都采用了OpenGL做为三维图形标准,许多软件厂商也纷纷以OpenGL 为基础开发

出自己的产品,其中比较著名的产品包括动画制作软件Soft Image 3D Studio

MAX

仿真软件Open InventorVR软件World Tool KitCAM软件ProEngineerGIS

ARC/INFO等等。值得一提的是,随着Microsoft公司在Windows NT和最新的

Windows 95

 

中提供了OpenGL标准及OpenGL三维图形加速卡(如北京黎明电子技术公司的

AGC-3D

系列三维图形加速卡)的推出,OpenGL将在微机中有广泛地应用,同时也为广大

户提供了在微机上使用以前只能在高性能图形工作站上运行的各种软件的机会。

OpenGL实际上是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以

为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual

C++

紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠

性。

OpenGL使用简便,效率高。它具有七大功能:

 

1) 建模 OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了

复杂的三维物体(球、锥、多面体、茶壶等)以及复杂曲线和曲面 (如Bezier

Nurbs等曲线或曲面)绘制函数。

2) 变换 OpenGL图形库的变换包括基本变换和投影变换。基本变换有平移、旋转

变比镜像四种变换,投影变换有平行投影(又称正射投影)和透视投影两种变换

其变换方法与机器人运动学中的坐标变换方法完全一致,有利于减少算法的运行

间,提高三维图形的显示速度。

 

3) 颜色模式设置 OpenGL颜色模式有两种,即RGBA模式和颜色索引(Color Index)

4) 光照和材质设置OpenGL光有辐射光(Emitted Light)、环境光(Ambient Light)

漫反射光(Diffuse Light)和镜面光(Specular Light)

材质是用光反射率来表示。场景(Scene)中物体最终反映到人眼的颜色是光的红

绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。

5) 纹理映射(Texture Mapping) 利用OpenGL纹理映射功能可以十分逼真地表达

物体表面细节。

6) 位图显示和图象增强 图象功能除了基本的拷贝和像素读写外,还提供融合

 

(Blending)、反走样(Antialiasing)和雾(fog)的特殊图象效果处理。

以上这三条可使被仿真物更具真实感,增强图形显示的效果。

7) 双缓存(Double Buffering)动画 双缓存即前台缓存和后台缓存,简而言之,

后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。

此外,利用OpenGL还能实现深度暗示(Depth Cue)、运动模糊(Motion Blur)

特殊效果。从而实现了消隐算法。

OpenGL图形库一共有100多个函数。其中核心函数有115个,它们是最基本的函数

 

其前缀是glOpenGL实用库(OpenGL utility library GLU)的函数功能更高

一些,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,共有43个,前缀

gluOpenGL辅助库(OpenGL auxiliary library GLAUX)的函数是一些特殊

的函数,包括简单的窗口管理、输入事件处理、某些复杂三维物体绘制等函数,

共有31个,前缀为aux

此外,还有六个WGL函数非常重要,专门用于OpenGLWindows 95窗口系统的联接

其前缀为wgl,主要用于创建和选择图形操作描述表(rendering contexts)以及在

 

窗口内任一位置显示字符位图。这些功能是Windows 95 OpenGL的唯一补充。

另外,还有五个Win32函数用来处理像素格式(pixel formats)和双缓存。由于它

们是对Win32系统的扩展,因此不能应用在其它OpenGL平台上。

OpenGL for Windows 95的设计与OpenGL for UNIX的程序设计有一点小区别,关

键就在于如何将OpenGL与不同的操作系统下的窗口系统联系起来。

如果调用OpenGL辅助库窗口管理函数,则不用考虑这些问题。下面简要介绍在

Windows 95 OpenGL 的程序设计关键。

 

1.图形操作描述

Windows 95下窗口程序必须首先处理设备描述表(Device Contexts DC)

DC包括许多如何在窗口上显示图形的信息,既指定画笔和刷子的颜色,设置绘

图模式、调色板、映射模式以及其它图形属性。同样,OpenGL for Windows 95

的程序也必须使用DC,这与其它Windows 95程序类似。但是,OpenGL for

 Windows 95必须处理特殊的DC图形操作描述表,这是DC中专为OpenGL使用的一

种。一个OpenGL应用图形操作描述表内有OpenGLWindows 95窗口系统相关的各

种信息。一个OpenGL应用首先必须创建一个图形操作描述表,然后再启动它,最

 

后在所定义的窗口内按常规方式调用OpenGL函数绘制图形。

一个图形操作描述表不同于其它DC,它们调用每个GDI函数都需要一个句柄,而图

形操作描述表方式下只需一个句柄就可以任意调用OpenGL函数。也就是说,只要

当前启用了某个图形操作描述表,那么在未删除图形操作描述表之前可以调用任

OpenGL函数,进行各种操作。

2.像素格式

在创建一个图形操作表之前,首先必须设置像素格式。像素格式含有设备绘图界

面的属性,这些属性包括绘图界面是用RGBA模式还是颜色表模式,像素缓存是用

 

单缓存还是双缓存,以及颜色位数、深度缓存和模板缓存所用的位数,还有其它

一些属性信息。

3.像素格式结构

每个OpenGL显示设备都支持一种指定的像素格式。一般用一个名为

PIXELFORMATDESCRIPTOR的结构来表示某个特殊的像素格式,这个结构包含26

属性信息。Win32定义PIXELFORMATDESCRIPTOR如下所示:

typedef struct tagPIXELFORMATDESCRIPTOR

{ kk1}

// pfd

WORD nSize

WORD nVersion

DWORD dwFlags

BYTE iPixelType

 

BYTE cColorBits

BYTE cRedBits

BYTE cRedShift

BYTE cGreenBits

BYTE cGreenShift

BYTE cBlueBits

BYTE cBlueShift

BYTE cAlphaBits

BYTE cAlphaShift

BYTE cAccumBits

BYTE cAccumRedBits

BYTE cAccumGreenBits

BYTE cAccumBlueBits

BYTE cAccumAlphaBits

BYTE cDepthBits

BYTE cStencilBits

BYTE cAuxBuffers

BYTE iLayerType

 

BYTE bReserved

DWORD dwLayerMask

DWORD dwVisibleMask

DWORD dwDamageMask

} PIXELFORMATDESCRIPTOR

4.初始化PIXELFORMATDESCRIPTOR结构

PIXELFORMATDESCRIPTOR中每个变量值的具体含义和设置可以参考有关资料,

下面举出一个PIXELFORMATDESCRIPTOR初始化例子来简要说明相关变量的意义。

定义PIXELFORMATDESCRIPTOR结构的pfd如下:

PIXELFORMATDESCRIPTOR pfd = { kk1}

sizeof(PIXELFORMATDESCRIPTOR), . //size of this pfd 1

 

PFD_DRAW_TO_WINDOW| // support window

PFD_SUPPORT_OPENGL| // support OpenGL

PFD_DOUBLEBUFFER, // double buffered

PFD_TYPE_RGBA, // RGBA type

24, // 24-bit color depth

000000 // color bits ignored

0, // no alpha buffer

0, // shift bit ignored

0, // no accumulation buff

0,000 // accum bits ignored

32, // 32-bit z-buffer

0 // no stencil buffer

0, // no auxiliary buffer

PFD_MAIN_PLANE, // main layer

0, // reserved

000 // layer masks ignored

 

}

在这个结构里,前两个变量的含义十分明显。第三个变量dwFlags的值是

PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL

表明应用程序使用OpenGL函数来绘制窗

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值