WINDOWS圖像編程 |
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
WINDOWS圖像編程 圖形設備介面(GDI,Graphics Device Interface)的主要目標之一是支援在輸出設備(如視頻顯示器、印表機和繪圖儀)上的與設備無關的圖形。 GDI通過將應用程式與不同輸出設備特性相隔離,使Windows應用程式能夠毫無問題地在Windows支援的任何圖形輸出設備上運行。
Windows中的圖形基本上是由從GDI.EXE模組中輸出的函數處理的(儘管一些繪製函數實際上具有USER.EXE的入口點),GDI.EXE模組調用在不同驅動程式文件中的常式,其中有一個.DRV驅動程式文件用於控制顯示幕幕,並且可能有一個或多個其他的.DRV驅動程式文件用來控制印表機或繪圖儀。
Windows GDI使用兩種坐標系統。使用虛擬坐標系統可以使程式不依賴於具體的硬體,使用設備坐標系統可以使程式和硬體緊密相聯。
GDI含有在Windows應用程式內部執行、且與設備無關的圖形操作函數,這些函數可産生各種各樣的線、正文和點陣圖,它們可以輸出到許多不同的輸出設備上。GDI允許一個應用程式産生筆、刷子、字體和點陣圖,以供特定的輸出操作使用。下面列出GDI中幾組比較常用的函數:
·設備上下文函數
·橢圓和多邊形函數
·繪圖工具函數
·點陣圖函數
·繪圖屬性函數
·正文函救
·映射函數。
·座標函數
·元文件(metafile)函數
·區域函數
·裁剪(clipping)函數·
視窗應用程式輸出圖形的操作步驟如下:
①取得指定視窗的當前顯示設備上下丈,顯示設備上下文實際上是一個資料結構,它包括該視窗的參數及各種圖形、文字屬性的現行設定值,它們對以後的圖形、文字輸 出命令起控制作用。
②選擇用戶坐標系及映射方式。
③設定用戶坐標系中的觀察視窗和設備坐標系中的顯示視區。
④輸出圖形、文字和圖像。
⑤釋放所使用的顯示設備上下文。 當想要在圖形輸出設備(例如螢幕或印表機)上繪製圖形時,必須首先獲得設備上下文的控制碼。先給出這個控制碼,Windows才允許程式使用設備,在GDI函數中將控制碼作爲一個參數傳入,向Windows標明需要使用的設備。
設備上下文中包含許多屬性,當GDI在不同的設備上工作時都要用到這些屬性。使用這些屬性可使GDI只關心起始和終止座標的大小,而不必關心有關物件的其他屬性,如顔色、背景等等,因爲這些都是設備上下文的一部分。當需要修改這些屬性時,只需調用一個修改設備上下文中屬性的參數,以後的程式中都使用修改後的設備上下文屬性。設備上下文是連接Windows應用程式、設備驅動程式以及輸出設備的紐帶。
獲取設備上下文控制碼有多種方法。最一般的方法是當處理一條消息時獲得了設備上下文、並在退出視窗之前釋放它。一般的處理方法如下:
在處理WM_PAINT消息時
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps)
EndPaint (hwnd,&ps);
其資料結構爲:
HDC hWnd;
PAINTSTRUCT ps;
而在windows.h中定義了PAINTSTRUCT的資料結構。
type struct tagPAINTSTRUCT {
HDC hdC;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL flncUpdate;
BYTE rgbReserved[16];
}PAINTSTRUCT;
其中,hdc用於標識顯式上下文,fErase指出背景是否重畫,rcPaint是塗色矩形,其餘的域均爲保留。這裏的hdc是BeginPaint返回的設備上下文控制碼,有了從DeginPaint獲取的設備上下文控制碼,就可以也只能在ps指出的rcPaint的矩形內繪圖,EndPaint調用使這一區域有效。
第二種方法如下所示,使用這種方法獲取和釋放設備上下文可以在整個用戶區內畫圖,圖形在整個用戶區域內都有效:
hdC=GetDc (hwnd );
…畫圖操作…
ReleaseDC (hwnd , hdc );
使用下面第三種方法獲取和釋放設備上下文,可以在整個視窗內畫圖,圖形在整個視窗內有效:
hdC=GetWindowDc(hwnd);
…畫圖操作…
ReleaseDc(hwnd,hdc);
使用下面第四種方法獲取和釋放設備上下文,可以在整個顯示器區域內畫圖,圖形在整個顯示器區域內部有效:
hdc=CreateDC (lpszDriver ,lpszDevice ,lpszOutput , lpData);
…畫圖操作…
ReleaseDC(hdc);
其中lpszDriver指向設備驅動程式的DOS檔案名(不帶副檔名),lpszDevice指向專用設備名(例如Epson Fx-80),lpszOutput指向物理輸出介質(文件或輸出埠)的DOS檔案名或設備名,lpData指向含有設備驅動程式的設備專用的初始化資料的DEVMODE資料結構。例如:
hdc=CreateDC("DISPLAY",NULL,NULL,NULL);
使用螢幕畫圖,而:
hdc= CreateDC ("IBMGRX","IBM Graphics","LPT1",NULL );
在印表機上輸出圖形,這裏的lpData置爲預設值,可以在WIN.INI中找到初始化值。
如果不需要獲取設備上下文,即不需要在設備上下文中操作,只需瞭解有關設備上下文的資訊,可以用如下語句:
hdcInfo = CreateDC (lpszDriver, lpszDevice,lpszOutput, lpData );
……
DeteteDC (hdcInfo);
另外,還可以使用設備上下文來對點陣圖的記憶體進行控制,如下所示:
hdcMem = CreateCompatibleDC (hdc)
OeleteDc(hdcMem );
一個元文件是以二進位形式編碼的GDI調用集合,可通過獲取一個元文件設備上下文來建立一個文件:
hdcMeta=CreateMetaFile(lpszFilename);
……
hmf=CloseMetaFile(hdCMeta);
在元文件設備上下文有效期間,使用hdcMeta所進行的任何GDI調用都成爲元文件的一部分,當調用CloseMetaFile時,設備上下文控制碼變化無效,函數返回元文件(hmf)的控制碼。
一個設備上下文通常涉及物理設備,如視頻顯示器、印表機等,所以需要獲取有關該設備的資訊,如顯示器大小和彩色能力等。可以通過調用GetDeviceCaps函數來獲取這樣的資訊:
nValue=GetDeviceCaps (hdc,nIndex);
這裏的hdc標識設備上下文,nIndex確定返回值,它可以是window.h中所定義的28個識別字中的一個,例如nIndex=DRIVEVERSION,則該函數返回的是版本號。 真正影響在用戶區域上繪製過程的設備上下文屬性是“映射方式”,與映射方式屬性密切相關的還有如下四個設備上下義屬性:窗口原點、視窗原點、窗口範圍和視窗範圍。
Windows定義了八種映射方式,即: 這裏的TWIP指的是1/1440英寸,in.代表英寸。
可以調用函數setMapMode(hdc,MapMode)來設置這八種映射方式中的一種。hdc用來標識設備上下文,nMapMode可以取MM_TEXT、MM_LOMETRIC、MM_HIMETRIC等八個值中的一個。在設置了映射方式之後,到下一次設置映射方式之前,Windows一直使用這種映射方式。如果想要獲取當前的映射方式,可用:
nMapMode= GetMapMode (hdc)
在設置了映射方式之後,就規定了邏輯單位的大小和增量的方式,在GDI畫圖函數中,可以不必考慮這些內容而直接使用邏輯數位,如:
SetMapMode(hdc ,MM_TEXT);
TextOut(hdc,8 ,16,szBuffer ,nLength)
即正文從用戶區域左起第八個象素,頂邊起第16個象素的位置開始寫操作。不管映射方式如何,Windows函數中所有座標規定爲-32768 到 32767之間的帶符號短整救。
注意映射方式只是一個設備上下文屬性,因此映射方式唯一起作用的是將映射方式作爲設備上下文控制碼屬性,而將該控制碼當作參數的GDI函數,因此象GetSystemMetrics這樣的非GDI函數,將繼續以設備單位(象素值)返回尺寸值。 用GDI的SetPixel函數可以繪製一特定顔色的象素:
rgbActualColor =SetPixel (hdc,x,y,rgbColor);
這裏hdc標識設備上下文,x ,y表示點座標,rgbColor爲一無符號的長整數,其結構爲:
COLORREF rgbColor;
其中低位元位元組爲紅基色的相對亮度值,第二個位元組包含綠基色的相對亮度值,第三個位元組包含藍基色的相對亮度值,高位位元組必須爲零。可以使用RGB函數來獲取rgbColor。
rgbColor =RGB(byRed ,byGreen,byBlue);
這裏的byRed、byGreen、byBlue取值範圍爲0~255,分別代表紅色、綠色、藍色的亮度。給出正確的參數之後,SetPixel返回的是調色板中最靠近所需彩色的顔色。還可以使用如下方法來取得一個特定象素的顔色:
rgbCotor= GetPixel(hdc,x,y); 畫線函數主要有三種, LineTo、Polyline 和 Arc。還有五個設備上下文屬性會影響這些函數畫出的線的外觀:筆的當前位置(僅對LineTo有影響)、筆、背景方式(對非實心筆有影響)、背景顔色(對 OPAQUE背景方式)以及繪製方式。
在這些設備上下文的屬性中,筆的當前位置影響畫線的起點,筆影響線的粗細等形狀,背景方式影響非實心筆畫出的線的模板圖形,背景顔色影響線模板背景色,繪製方式影響實心線、虛線等線屬性。
以下是典型的畫線操作步驟:
MoveTo(hdc,xStart,yStart);
LineTo(hdc ,xEnd ,yEnd);
上面兩句畫出一條從(xStart,yStart)到(xEnd,yEnd)的直線。
可以使用語句:
dwPoint = GetCurrentPosition (hdc);
獲得筆的當前位置。這裏,dwPoint返回值是一個無符號長整數(或雙倍長字),其中低位字含有X座標,高位字含有Y座標。
可以使用MAKEPOINT函數將dwPoint轉換爲POINT結構;
point = MAKEPOINT (dwPoint);
point的類型爲POINT:
typedef struct togPOINT {kk1}
int x;
int y;
}POINT;
Polyline用於繪製折線,例:
Polyline(hdc,&pt,5)
將陣列pt中的5個點之間用線段相連。
Arc用於畫橢圓的周邊:
Arc (hdc,xLeft,yTop,xRight,yBottom,xStart,yStart,XEnd,yEnd );
畫出的橢圓以左上角爲(xLeft,yTop),右下角爲(xRight,yBottom)的矩形爲界,圓弧開始於橢圓和(xStart,yStart)與橢圓中心的連線的交點處,沿著橢圓周邊的過時針方向繪製,並終止於橢圓和(xEnd,yEnd)與橢圓中小的連線的交點處。
當調用LineTo、Polyline和Arc時,Windows使用當前在設備上下文中選擇的筆來畫線,筆決定了線的顔色、密度和型式,而線型可以是實線、點線或短劃(虛)線,缺省設備上下文中的筆叫做BLACK_PEN,不管映射方式如何選支筆以一個象素的寬度畫黑色的實線, BLACK_PEN是Windows提供的三支“備用筆”之一,其他兩支是WHITE_PEN和NULL_PEN,NULL_PEN是一支什麽都不畫的空筆,當然用戶也可以自己建立定制的筆。
可以通過一個控制碼來引用所需的筆:
HPEN hPen;
hPen =GetStockObject(WHITE_PEN);
SelectObjeCt (hdc ,hPen) ;
調用GetStockObject獲得一支備用筆(WHITE_PEN)的控制碼,調用SelectObject使這支筆成爲設備上下文中當前選擇的用CreatePen或CreatePenIndirect函數建立一支“邏輯筆”,這邏輯筆只是一支筆的描述。
hPen = CreatePen (nPenStyle ,nWidth ,rgbColor );
其中nPenStyle參數確定筆是繪製實線還是由點或短劃組成的線。該參數可取下列識別字之一: PS_SOLID、PS_DASH、Ps_DOT、PS_DASHDOT、 PS_DASHDOT DOT。nWidth表示筆寬(採用邏輯單位),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 =CreatePen(PS_SOLID,1,0L);
hpen2=CreatePen(PS_SOLID,3,RGB(255,0,255)),
selectObject (hdc ,hpenl )
//LineTo調用
SelectObject (hdc , hpen2 )
//Polyline調用
DeleteObject(hpenl);
DeleteObject(hpen2);
在點線筆和短劃筆的空隙間的著色取決於設備上下文中定義的背景方式和背景顔色這兩種屬性。缺省的背景方式是 OPAQUE ,即用背景顔色來填充空隙,缺省的背景顔色是白色。可用:
SetBkColor (hdc,rgbColor );
來改變填充空隙的背景顔色。可用:
SetBkMode(hdc,mode);
來改變背景方式,這裏的mode可爲OPAQUE或TRANSPARENT。
在設備上下文中可設置口種新的繪製方式。nDrawMode參數定義繪製方式。可用下列函數獲得當前繪製方式:
nDrowMode = GetRop2 (hdc);
使用這種繪製方式實際上是在筆的象素和目標顯示表面的象素之間執行一種逐位布耳運算。 下面列出了Windows的六個函數,用於繪製帶有邊框的填充區域:
Rectangle, 帶有方形角的矩形
Ellipse, 橢圓
RoundRect, 帶有圓形角的矩形
Chord, 在橢圓周邊上的弧,其斷 . 點用一條弦相連接
Pie, 在橢圓周邊上的餅形楔
Polygon, 多邊形
PolyPolygon, 多個多邊形
圖形要用設備上下文中選擇的當前刷子進行填充, 例:
HBRUSH hBrush;
hBrush=GetStockObject(GRAY_BRUSH)
SelectObject (hdc,hBrush)
對於矩形填充物件,使用:
Rectangle(hdc,xLeft,yTop,xRight,yBottom);
點(xLeft,yTop)是矩形的左上角,而(xRight,yBottom)是右下角(這兩點均以邏輯座標給出)。同時還要考慮這兩點座標的合理性,例如,在MM_TEXT映射方式下,xRight必須大於xLeft,yBottom必須大於yTop。
對於橢圓填充物件,使用:
Ellipse(hdc,xLeft,yTop,xRight,yBottom);
畫圓角矩形的填充物件,使用:
RoundRect (hdc,xLeft,yTop,xRight,yBottom,xCornerEllipse,yCornerEllipse);
rgbColor爲指定刷子的前景顔色,即陰影線的顔色。
③第三種方法:
hBrush = CreatePatternBrush ( hBitmap ) ;
本函數建立一把具有由hBitmap參數指定圖案的邏輯刷子,該刷子以後可被任何支援光柵操作的設備所選用。hBitmap標識點陣圖,該點陣圖可用函數CreateBitmap、CreateBitmapIndirect、LoadBitmap或CreateCompatibleBitmap創建。用於填充圖案的點陣圖的最小尺寸爲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 " BitmOPName.Bmp"
(假設SDKPAINT中産生的點陣圖名爲BitmapName.Bmp),然後將點陣圖裝入:
hBitmap = LoadBitmap (hInstance , lpszBitmap ) ;
這裏hBitmap即爲點陣圖控制碼。
②第二種獲取點陣圖控制碼的方法是:
hBitmap= createBitmop(nWidth,nHeight ,nPlanes ,nBitsPixel,lpBits);
本函數可生成一個具有指定的寬度、高度和位元圖案(bit pattern)並與設備有關的記憶體點陣圖。其中的參數nWidth指定點陣圖的寬度(以象素爲單位),nHeight指定點陣圖的高度(也以象素爲單位),nPlanes指定點陣圖中的彩色位元平面的個數,每個彩色位元平面有nWidthXnHeight XnBitsPixel位元。
nBitsPixel指定每個顯示象素的顔色位元數。lpBits指向一個含有初始點陣圖位值的短整型陣列,它的值與BITMAP結構中的bmBits值相類似,有關BITMAP結構的內容已在前面
的章節中提到。
③第三種獲取點陣圖控制碼的方法:
hBitmap= CreateCompatibleBitmap (hdc,nWidth,nHeight);
本函數生成一個與由hdc參數指定的設備相相容的點陣圖,此點陣圖具有與其他設備相同數值的彩色位元平面或相同的每象素位數的格式。它的彩色資訊同樣由hdc指定的設備所確定。hdc標識設備上下文,nWidth和nHeight分別指定點陣圖的寬和高(以位數表示)。
④第四種獲取點陣圖控制碼的方法:
hBitmop = CreateBitmapIndirect (&bitmap):
本函數生成一個具有由lpBitmap參數所指定的資料結構給出的寬度、高度和點陣圖圖案的點陣圖。這裏的bitmap的結構爲BITMAP類型。
當擁有一個點陣圖控制碼之後,還可以調用:
GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&bitmap);
來獲得有關點陣圖的資訊,這裏返回的bitmap爲一個BITMAP類型的結構。
還可以調用:
GetBitmapBits (hBitmap,dwCount,lpBits);
將點陣圖hBitmap的dwCount個位元組複製到位址爲lpBits的陣列中。同樣還可以使用
SetBitmopBits (hBitmap,dwCount,lpBits);
將 lpBits 標識的彩色位元值放置到 hBitmap 標識的點陣圖中去。
當Windows用刷子填充一個區域時,它在水平和垂直兩個方向上重復地使用8×8點陣圖,刷子的外觀可能會有細微的變化,這取決於Windows如何將點陣圖的左上角與顯示表面對齊,設備上下文中將這種對齊的屬性稱爲“刷子原點”。
大多數情況下,繪圖時不必如此精細地調整刷子原點;但在某種情況下,爲了産生某種特定的視覺效果,需要這麽做。可以通過下面步驟來達到這個效果:
①對刷子調用UnrealizeObject(但不能對備用刷子調用UnrealizeObject);
UnrealizeObject(hObject );
此函數表示GDI在下次給定的刷子被選中時,使它的原點重定。
②用SetBrushOrg設置刷子原點:
BrushOrg=SetBrushOrg(hDc,x ,y);。
此函數用於設置當前選人給定的設備上下文中的刷子的原點。其中,hDc標識設備上下文,x規定新原點的x 座標(採用設備座標),該值範圍必須在0~7之間,y規定新原點的y座標(採用設備座標),該值範圍必須在0~7之間,該函數返回一個雙字,先前的x座標放在低位字,先前的y座標放在高位字。 除了畫點、畫線、區域填充這些繪圖函數之外,Windows還包括幾個附加的繪圖函數,用以處理RECT(矩形)結構和“區域”,區域是螢幕的一個由矩形、其他多邊形和橢圓組合而成的部分。
FillRect(hdc ,&rect,hBrush);
此函數是用選定的刷子填充給定的矩形,FillRect函數填充整個矩形,還包括左邊線和頂邊線,但不包括右邊線和底邊線。hdc標識設備上下文,rect爲RECT資料結構類型,此資料結構存放要填充的矩形的邏輯座標。hBrush用來標識填充此矩形的刷子。
FrameRect (hdc ,&rect);
本函數在 lpRect 參數指定的矩形周圍畫出一個邊框,FrameRect 函數採用給定的刷子繪製邊框,邊框的高和寬總是用邏輯單位表示。hdc標識視窗的設備上下文, rect 標明左上角和右下角的邏輯座標,hBrush標識畫矩形邊框用的刷子。
InvertRect (hdc,&rect);
該函數反視頻顯示給定矩形的內容。
前面提到的rect可用以下語句取得:
SetRect(&rect,xLeft,yTop,xRight,yBottom);
區域用以描述顯示器上的一個由矩形、其他多邊形和橢圓組合而成的部分、可以用區域進行繪製或裁剪。
可用:
hRgn=CreateRgn(xLeft,yTop,xRight,yBottom);
或
hRgn = CreateRectRgnIndirect (&rect );
來建立矩形區域,也可以用:
hRgn= CreatEllipseRgn (xLeft,yTop,xRight,yBOttom);
或:
hRgn =CreateEllipseRgnIndirect (&rect);
來建立橢圓形區域;還可以用:
hRgn=CreatePolygonRgn (Upoint,nCount,nPolyFillMode);
來建立多邊形區域,用:
hRgn=CreateRoundRectRgn(xl,yl,x2,y2,x3,y3);
來建立一個帶有圓角的矩形區域,(xl,y1)表示區域左上角,(x2,y2)表示區域右下角,x3和y3分別用於指定産生圓角的橢圓的寬度和高度。
各個特定區域的控制碼産生之後,
還可以使用:
nRgnType= CombineRgn (hDestRgn,hSrcRgnl,hSrcRgn2,nCombine);
通過組合兩個已存在區域而産生一個新的區域。組合區域的方法由nCombine參數加以說明:
這裏的hSrcRgnl和hSrcRgn2標識兩個已存在的區域,hDestRgn標識將被新區域替換的作爲目標的已存在區域。
一個區域用完後,可用DeleteObject(hRgn)刪除它。 FloodFiLL (hdc,xStart,yStart,rgbColor);
本函數用當前刷子填充顯示表面的一個區域,該區域假定由rgbColor多數指定的顔色邊界確定,FloodFill函數由xStart,yStart參數指定的,點開始向各個方向進行填充,直到顔色邊界爲止。
ExtFLoodFill(hdc,xStart,yStart,rgbColor,wFill );
此函數用當前刷子填充顯示表面上的某一區域,若wFill被設置成FLOODFILLBORDER,此區域將完全用rgbColor設定的顔色作爲邊界,ExtFloodFill從(xStart,yStart)點開始向各個方向填充,直到該顔色邊界爲止。若wFill被設置成FLOODFILLSURFACE,則ExtFLOODFILL函數從(xStart,yStart)點開始,向各個方向對所有包含由rgbColor參數設定的顔色的相鄰區域進行填充。
DrowIcon(hdc,xStort,yStart,hIcon) ;
本函數在指定設備上畫一個圖示。(xStart,yStart)爲圖示的左上角,hIcon標識要畫的圖示,它與hBitmap一樣,可以由SDKPAINT畫出,在. rc文件中定義,用LoadIcon獲得。
ScrollWindow (hwnd,xScroll,yScroll,&rectScroll,&rectClip) ;
本函數通過移動一個視窗用戶區域的內容來滾動該視窗,沿X軸移動xScroll個單位,沿Y軸移動yScroll個單位,rectScroll表示用戶區域要滾動的那一部分內容,rectClip表示要滾動的裁剪矩形。
ScrollDC(hdc,dx,dy,lprcScroll,lprcClip, hrgnUpdate,lprcUpdate);
此函數水平地和垂直地滾動由位構成的矩形。lprcScroll指向要滾動的矩形,dx表示水平滾動單位,dy表示垂直滾動單位,lprcClip指向裁剪矩形,hrgnUpdate返回滾動過程沒有覆蓋的區域,lprcUpdate返回需要重畫的最大矩形區域。 OpenGL是近幾年發展起來的一個性能卓越的三維圖形標準,它是在SGI等多家 世界聞名的電腦公司的倡導下,以SGI的GL三維圖形庫爲基礎制定的一個通用共用的開放式三維圖形標準。目前,包括Microsoft、SGI、IBM、DEC、SUN、HP等大公司都採用了OpenGL做爲三維圖形標準,許多軟體廠商也紛紛以OpenGL 爲基礎開發出自己的産品,其中比較著名的産品包括動畫製作軟體Soft Image 和3D Studio MAX、仿真軟體Open Inventor、VR軟體World Tool Kit、CAM軟體ProEngineer、GIS軟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個,它們是最基本的函數,其字首是gl,OpenGL實用庫(OpenGL utility library , GLU)的函數功能更高一些,如繪製複雜的曲線曲面、高級座標變換、多邊形分割等,共有43個,字首爲glu;OpenGL輔助庫(OpenGL auxiliary library ,GLAUX)的函數是一些特殊的函數,包括簡單的視窗管理、輸入事件處理、某些複雜三維物體繪製等函數,共有31個,字首爲aux。
此外,還有六個WGL函數非常重要,專門用於OpenGL和Windows 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應用圖形操作描述表內有OpenGL與Windows 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
0,0,0,0,0,0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buff
0,0,0,0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0,0,0 // layer masks ignored
};
在這個結構裏,前兩個變數的含義十分明顯。第三個變數dwFlags的值是
PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL ,
表明應用程式使用OpenGL函數來繪製視窗
第四個:
PFD_DOUBLEBUFFER,
表明當前採用RGBA顔色模式,第五個採用24位元真彩色,既1.67千萬種顔色,如果是256色系統則自動實現顔色抖動;因爲沒有使用alpha緩存和累計緩存,所以從變數cAlphaBits到cAccumAlphaBits都設置爲0;深度緩存設置爲32位,這個緩存能解決三維場景的消隱問題;變數cAuxBuffers設置爲0,在Windows 95下不支援輔助緩存;Windows 95下針對OpenGL變數ilayerType只能設置爲PFD_MAIN_PLANE,但在其他平臺也許支援PFD_MAIN_PLANE或PFD_MAIN_UNDERLAYPLANE;接下來bReserved變數只能設爲0,而最後三個變數Windows 95都不支援,故全設置爲0。
5.設置圖元結構
當初始化PIXELFORMATDESCRIPTOR結構後,就要設置圖元格式。下面舉例說明如何設置圖元格式。
CClientDC clientDC(this);
int PixelFormat = ChoosePixelFormat(clientDC.m_hDC,&pfd);
BOOL result=SetPixelFormat(clientDC.m_hDC,PixelFormat,&pfd);
第一行語句說明如何得到一個應用窗口客戶區的設置描述表。
第一行調用ChoosePixelFormat( )選擇一個圖元格式,並將圖元格式索引號返回給pixelFormat變數;函數中第一個參數是選擇圖元格式的設備描述表的控制碼,第二個參數是PIXELFORMATDESCRIPTOR結構的位址。如果調用失敗則返回0;否則返回圖元格式索引號。
第三行調用SetPixelFormat( )設置圖元格式,三個參數分別是設備描述表的控制碼、圖元格式索引號和PIXELFORMATDESCRIPTOR結構的位址。如果調用成功則返回TRUE,否則返回FALSE。
6.創建圖形操作描述表
正如前所述,必須創建圖形操作描述表並啓用它後,才能調用OpenGL函數在視窗內進行各種圖形操作。一般來說,利用 MFC 中增補的管理圖形操作描述表方法來編程比較方便。即在視類 (CView) 的消息 OnCreat( ) 中創建圖形操作描述表。 *********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together!
希望能大家敞開心胸,將知識寶庫結合一起
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |