游戲編程導(dǎo)論 Chapter-04_第1頁
游戲編程導(dǎo)論 Chapter-04_第2頁
游戲編程導(dǎo)論 Chapter-04_第3頁
游戲編程導(dǎo)論 Chapter-04_第4頁
游戲編程導(dǎo)論 Chapter-04_第5頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、第4章 Windows圖形編程內(nèi)容提綱 4.1與位圖相關(guān)的概念4.2Windows圖形技術(shù)4.2.1 圖形技術(shù)簡介4.2.2 圖形設(shè)備接口4.3GDI圖形操作4.3.1 位圖與設(shè)備環(huán)境4.3.2 設(shè)備相關(guān)的位圖4.3.3 設(shè)備無關(guān)的位圖4.4GDI繪圖函數(shù)4.5GDI+圖形操作4.6綜合應(yīng)用實例第4章 Windows圖形編程Windows游戲編程離不開圖形操作,可以說游戲效果表現(xiàn)的核心就是圖形顯示。微軟為了簡化對文本及圖形的操作,在Windows操作系統(tǒng)中提供了與設(shè)備無關(guān)的通用圖形編程接口,即圖形設(shè)備接口(Graphics Device Interface, GDI)。當(dāng)您掌握了本書內(nèi)容后,可

2、以進一步學(xué)習(xí)DirectX或OpenGL。4.1 與位圖相關(guān)的概念位圖(Bitmap)概念:位圖也稱為光柵圖(Raster Graphics Image),它的圖像是由像素(Pixel)組成,每個像素都被分配一個特定位置和一種顏色值,圖形操作實際上就是處理像素點。像素點的多少決定了位圖的清晰度。根據(jù)記錄位圖信息所需要的數(shù)據(jù)位數(shù)可以分為1位、4位、8位、16位、24位及32位等。位數(shù)越多記錄的顏色信息越豐富,當(dāng)然記錄信息所需要的空間也就越大,讀取和操作位圖時的數(shù)據(jù)量也越大。常見的位圖格式有bmp、jpg、gif、tif、png等等。4.1 與位圖相關(guān)的概念4.1.1 色彩模式1. RGB色彩模式

3、最常見的位圖顏色的編碼方法,使用紅(Red)、綠(Green)、藍(lán)(Blue)三原色的光學(xué)強度來表示一種顏色,每種顏色的光學(xué)強度都是在0255范圍內(nèi)。RGB是屏幕顯示的最佳顏色,所以RGB模式的位圖可以直接用于屏幕顯示RGB色彩模式可以在屏幕上表現(xiàn) 256256256 = 16777216種顏色。2. CMYK色彩模式使用青色(Cyan)、品紅色也稱洋紅色(Magenta)、黃色(Yellow)、黑色(blacK)四種顏色的含量來表示一種顏色。該模式適合彩色印刷。游戲中的色彩模式采用RGB模式。3. Indexed色彩模式Indexed色彩模式,也稱為索引顏色模式。該模式一般采用索引顏色(In

4、dexed Color)或顏色表(Color Table)來表示顏色信息。此模式只能存儲8位色彩深度(最多256種顏色)的信息。4.1 與位圖相關(guān)的概念4.1.2 色彩深度色彩深度(Color Depth)又叫色彩位數(shù)(Bit),是表示圖像中有多少顏色信息可用于顯示或打印的度量。常用的顏色深度有:1位、4位、8位、16位、24位和32位等。1位只能表示單色,每個像素的顏色只能是黑或白; 4位可表示2的4次方中顏色,即16色;8位可表示2的8次方種顏色,或256級灰階,每個像素可能是256種顏色中的任意一種,也就是索引顏色;16位可表示65536級灰階或顏色,16位色又稱之為增強色;24位和32

5、位所表示的顏色叫真彩色,其中24位可以包含1670萬(2的24次方)種顏色,而32位從理論上講可以表示2的32次方種顏色;有時32位的圖像可能是一個包含Alpha通道的24位圖像或采用CMYK色彩模式的圖像。4.1 與位圖相關(guān)的概念4.1.3 Alpha通道Alpha通道用于記錄圖片像素透明度的信息。一些32位的圖像實際上就是24位圖像,只是增加了Alpha通道。如果一個像素的Alpha通道數(shù)值為0,那它就是完全透明的;255則意味著一個完全不透明的像素。在0和255之間的值則使得像素可以透過背景顯示出來,具有透過玻璃的半透明性效果。含有Alpha通道的常用圖像格式是PNG圖像格式,它使用RG

6、BA色彩模式表示圖像的色彩信息和透明度信息。4.1 與位圖相關(guān)的概念4.1.4 RGB顏色的描述Windows采用4個8 位的二進制數(shù)(即一個字節(jié))共32位(即4個字節(jié))來描述一個特定像素的RGB值,每個8位二進制數(shù)的值域范圍為 0255。對RGB顏色的操作都是通過COLORREF 這個數(shù)據(jù)類型進行的,其值采用下面這個16進制的格式:0 x00bbggrr。最低位表示紅色分量值;第二位表示綠色分量;第三位表示藍(lán)色分量;最高位在COLORREF類型中必須為0;每個字節(jié)的最大值均為255;如果要為COLORREF類型賦值,通常使用RGB()宏來完成;獲得一個COLORREF 類型的變量中各顏色的分

7、量值,可以分別使用GetRValue()、 GetGValue()、 GetBValue()這三個宏來獲得。4.2 Windows圖形技術(shù)4.2.1 圖形技術(shù)簡介目前在 Windows 環(huán)境下,主要有三種圖形開發(fā)技術(shù):GDI/GDI+DirectXOpenGL。GDI一直是Windows操作系統(tǒng)固有的圖形編程接口,它是一個二維圖形庫。目前已經(jīng)升級到了GDI+;GDI/GDI+最大的遺憾就是無法利用現(xiàn)代GPU提供的強大圖形處理能力。4.2 Windows圖形技術(shù)DirectX專門用于高性能多媒體程序及游戲程序開發(fā)的編程技術(shù)。由C+編程語言實現(xiàn),遵循微軟的COM標(biāo)準(zhǔn);被廣泛用于Windows操作系

8、統(tǒng)、Xbox和Xbox 360游戲平臺的游戲開發(fā);由眾多API組成:分為DirectDraw、DirectSound、DirectInput和DirectPlay四大組成部分;最新版本為DirectX 11.1支持最新的Windows 8操作系統(tǒng);學(xué)習(xí)DirectX需要對C+有比較深入的了解,由于DirectX的接口采用COM方式,對于COM不了解的初學(xué)者來說學(xué)習(xí)會有點難度。4.2 Windows圖形技術(shù)OpenGL(Open Graphics Library),是一個功能強大的專業(yè)圖形編程接口,可以跨操作平臺、跨編程語言,能夠用于二維和三維的圖形編程。OpenGL由約350個不同函數(shù)調(diào)用構(gòu)成

9、,可以繪制簡單的二維圖形,也可以繪制復(fù)雜的三維圖形;OpenGL能夠較好地利用顯卡的圖形處理能力;它最新版本為OpenGL4.4;與DirectX相比,OpenGL的發(fā)展顯得比較緩慢,DirectX已經(jīng)在各個方面都超過了OpenGL。三種圖形開發(fā)技術(shù)相比較,GDI/GDI+相對比較適合初學(xué)者學(xué)習(xí),其所提供的圖形繪制能力和動畫處理能力,對于小型游戲的開發(fā),基本能夠滿足要求。4.2 Windows圖形技術(shù)4.2.2 圖形設(shè)備接口本書采用GDI作為圖形編程的基礎(chǔ)。GDI為所有的繪圖設(shè)備提供了一個共同的虛擬設(shè)備。繪圖時你只要獲得這個虛擬設(shè)備,而無須關(guān)心任何硬件的細(xì)節(jié)及它們的區(qū)別。圖形設(shè)備接口目前已經(jīng)升

10、級到GDI+。GDI+不能獨立工作,底層依然是GDI的實現(xiàn);GDI+不能取代GDI,要依賴GDI才能工作;GDI+進一步簡化了Windows下的繪圖操作,增加了新的特征,如漸變畫刷、矩陣和矩陣變換、Alpha混色等,最重要的是增加了對多種圖像文件格式的支持;GDI+的繪圖效率比GDI要顯得低一些,很多情況下會將GDI和GDI+混合使用。4.2 Windows圖形技術(shù)使用GDI時首先要獲取DC(Device Context, 設(shè)備內(nèi)容、設(shè)備環(huán)境或設(shè)備上下文)它是一個存儲所有與繪圖相關(guān)信息的數(shù)據(jù)結(jié)構(gòu);每個設(shè)備環(huán)境都必須與一個窗口相關(guān)聯(lián),要在窗口上進行繪圖,首先要獲取該窗口對應(yīng)的設(shè)備句柄;要操縱繪圖

11、內(nèi)容,除了獲取HDC對象外,還需要一個可以進行內(nèi)容繪制的HBITMAP對象它是一個位圖對象的句柄;通過SelectObject()函數(shù)把HBITMAP對象選入HDC對象中,然后通過HDC這個設(shè)備環(huán)境進行的所有繪圖操作都會在這個位圖上表現(xiàn)出來。4.2 Windows圖形技術(shù)例如:T_Engine中實現(xiàn)的內(nèi)存緩沖繪圖的代碼片段HBITMAP bufferBitmap;/ 內(nèi)存緩沖位圖HDC bufferDC;/ 內(nèi)存緩沖設(shè)備bufferDC = CreateCompatibleDC(GetDC(m_hWnd);bufferBitmap = CreateCompatibleBitmap(GetDC(

12、m_hWnd), wndWidth, wndHeight);SelectObject(bufferDC, bufferBitmap);GamePaint(bufferDC); /在內(nèi)存中繪制內(nèi)容HDC hDC = GetDC(m_hWnd); /獲取游戲窗口句柄及繪圖設(shè)備/將內(nèi)存設(shè)備中繪制的內(nèi)容繪到屏幕上BitBlt(hDC, 0, 0, WIN_WIDTH, WIN_HEIGHT, bufferDC, 0, 0, SRCCOPY);ReleaseDC(m_hWnd, hDC);/釋放設(shè)備4.2 Windows圖形技術(shù)使用GDI+首先要獲得圖形環(huán)境(Graphics Context),或稱為圖

13、形上下文或圖形內(nèi)容等。圖形環(huán)境也要與一個指定的窗口相關(guān)聯(lián),其中也包含與圖形繪制相關(guān)的信息。圖形環(huán)境不包含畫筆、畫刷、字體等對象,具體的繪圖任務(wù)由不同的繪圖對象類承擔(dān);如果要繪制一個矩形輪廓,則要使用Graphics圖形環(huán)境的DrawRectangle()函數(shù);如果要定義矩形輪廓的線條顏色及粗細(xì),還要使用Pen對象;如果要填充一個矩形,可以使用Graphics圖像環(huán)境的FillRectangle ()函數(shù);如果要定義填充顏色的話,則需要定義一個SolidBrush畫刷對象4.3 GDI圖形操作4.3.1 位圖與設(shè)備環(huán)境在Windows中,GDI繪圖操作都是在設(shè)備環(huán)境中進行的。進行繪圖操作之前,必

14、須首先設(shè)置相應(yīng)設(shè)備可用的繪圖屬性,然后獲取其設(shè)備環(huán)境句柄。位圖用來保存和顯示圖像,設(shè)備環(huán)境中的繪圖操作,其結(jié)果就保存在被選入設(shè)備的位圖中。要獲取當(dāng)前顯示設(shè)備的設(shè)備環(huán)境句柄,可以調(diào)用GetDC()函數(shù)。其函數(shù)原型定義如下: HDC GetDC( HWND hWnd);設(shè)備環(huán)境使用完畢,需要使用ReleaseDC()函數(shù)進行釋放。該函數(shù)原型定義為: int ReleaseDC(HWND hWnd, HDC hDC);4.3 GDI圖形操作設(shè)備環(huán)境句柄既可以指向?qū)嶋H設(shè)備,也可以指向虛擬設(shè)備。虛擬設(shè)備都是在內(nèi)存中模擬實現(xiàn)的,所以也可以稱之為內(nèi)存設(shè)備環(huán)境。在實際的游戲繪圖操作中,為了避免因為清除屏幕帶來

15、的閃爍問題,往往利用內(nèi)存設(shè)備環(huán)境來解決問題。其原理就是按照當(dāng)前的顯示設(shè)備環(huán)境構(gòu)造一個對應(yīng)的內(nèi)存設(shè)備環(huán)境,然后所有的繪圖操作,包括清除操作,首先在內(nèi)存設(shè)備環(huán)境中進行,然后將完成后的繪制結(jié)果拷貝到屏幕上。這種虛擬的內(nèi)存設(shè)備環(huán)境的繪圖操作往往要借助于與設(shè)備相關(guān)的位圖才能完成。根據(jù)位圖與設(shè)備的關(guān)系,可以把位圖分為:設(shè)備相關(guān)位圖(Device-Dependent Bitmap, DDB)設(shè)備無關(guān)位圖(Device-Independent Bitmap , DIB)。4.3 GDI圖形操作4.3.2 設(shè)備相關(guān)的位圖設(shè)備相關(guān)的位圖就是與當(dāng)前所使用的具體設(shè)備信息直接關(guān)聯(lián)的位圖。這種類型的位圖,其顏色模式必需與

16、輸出設(shè)備一致。如果當(dāng)前的顯示設(shè)備只支持256色模式,那么要輸出的DDB也必須是256色,位圖的每個像素用一個字節(jié)表示。DDB一般只能存在于內(nèi)存中、顯存中或系統(tǒng)內(nèi)存中。DDB一個重要用途就是用于緩沖繪圖。4.3 GDI圖形操作對于復(fù)雜圖形的繪制,一般都是在內(nèi)存模擬的設(shè)備環(huán)境中事先繪制好,然后再將繪圖結(jié)果快速地拷貝到實際設(shè)備的顯示表面。清除工作不是在當(dāng)前屏幕中進行,就在視覺上避免了屏幕被清除時造成的短暫閃爍問題。同時,由于每一次新圖形都是事先在內(nèi)存設(shè)備中的DDB上繪制好的,也就是事先進行了緩沖,這樣就大大加快了繪制速度,從而提高了圖形處理的效率。這就是所謂的雙緩沖繪圖機制,它在游戲編程中被廣泛使用

17、。T_Engine中定義的HDC類型的變量bufferDC和HBITMAP類型的變量bufferBitmap,就是為了實現(xiàn)雙緩沖繪圖而定義的。bufferDC就是在內(nèi)存中創(chuàng)建的設(shè)備環(huán)境而bufferBitmap就是充當(dāng)緩沖繪圖作用的DDB。DDB還可以充當(dāng)臨時處理空間。例如如果要對加載的原始位圖進行一定的處理,如將原始位圖的局部拷貝到屏幕上或其他位圖中,有時還要對拷貝的位圖進行轉(zhuǎn)換處理,如獲取位圖的鏡像等,也需要首先在DDB上進行,然后再將處理結(jié)果運用到目的設(shè)備或目的位圖中。4.3 GDI圖形操作1. 設(shè)備相關(guān)位圖的創(chuàng)建創(chuàng)建DDB使用Windows GDI 函數(shù)CreateCompatible

18、Bitmap()其原型定義如下:HBITMAP CreateCompatibleBitmap (HDC hdc, /指向指定設(shè)備的句柄; int nWidth,/要創(chuàng)建的位圖的寬(單位是像素) int nHeight );/要創(chuàng)建的位圖的高(單位是像素)DDB常與內(nèi)存設(shè)備一起使用。內(nèi)存設(shè)備的創(chuàng)建使用GDI函數(shù)CreateCompatibleDC()。該函數(shù)的原型定義: HDC CreateCompatibleDC( HDC hdc ); 4.3 GDI圖形操作要將DDB與內(nèi)存設(shè)備聯(lián)系起來,使用 函數(shù)SelectObject()其功能就是將一個對象選進內(nèi)存設(shè)備,支持的對象包括位圖、筆刷、字體、畫

19、筆以及區(qū)域。函數(shù)的原型定義如下:HGDIOBJ SelectObject( HDC hdc,/ 指向設(shè)備的句柄 HGDIOBJ hgdiobj );/ 要選進設(shè)備的對象內(nèi)存設(shè)備使用完畢必須及時進行清除,釋放占用的資源,使用GDI函數(shù)DeleteDC()刪除設(shè)備。該函數(shù)的定義是: BOOL DeleteDC( HDC hdc );選進內(nèi)存設(shè)備的對象使用完畢,使用DeleteObject()函數(shù)刪除。該函數(shù)的原型是: BOOL DeleteObject( HGDIOBJ hObject );4.3 GDI圖形操作如果要對創(chuàng)建的DDB進行顏色的填充。這時,需要用到CreateSolidBrush()

20、函數(shù)以及FillRect()函數(shù)。CreateSolidBrush()函數(shù)用于創(chuàng)建一個單色筆刷對象,F(xiàn)illRect()函數(shù)則對指定設(shè)備中的指定矩形區(qū)域使用指定的筆刷進行填充。CreateSolidBrush()函數(shù)的原型如下:HBRUSH CreateSolidBrush( COLORREF crColor );FillRect()函數(shù)的原型定義是:int FillRect( HDC hDC, CONST RECT *lprc, HBRUSH hbr );4.3 GDI圖形操作2. DDB空白位圖的創(chuàng)建實例在內(nèi)存中創(chuàng)建一個用于臨時交換用的空白位圖,然后將中間結(jié)果繪制其中,進行一定的處理后,例

21、如使用指定的顏色進行填充,再拷貝到其它設(shè)備中或屏幕上。將函數(shù)命名為CreateBlankBMP(),該函數(shù)的原型聲明如下:HBITMAP CreateBlankBMP (HDC hDC, int ibWidth, int ibHeight, COLORREF crColor );4.3 GDI圖形操作CreateBlankBMP函數(shù)的實現(xiàn)代碼:HBITMAP CreateBlankBMP ( HDC hDC, int ibWidth, int ibHeight, COLORREF crColor ) /創(chuàng)建一個空的位圖HBITMAP bitmap = CreateCompatibleBitma

22、p(hDC, ibWidth, ibHeight);if (bitmap = NULL) return FALSE;/創(chuàng)建一個內(nèi)存設(shè)備用來繪制位圖HDC memDC = CreateCompatibleDC(hDC);/創(chuàng)建一個單色畫刷,用于填充所創(chuàng)建的空位圖HBRUSH hBrush = CreateSolidBrush(crColor);/將創(chuàng)建的空位圖替換內(nèi)存設(shè)備中的原來對象HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, bitmap);/用制定的顏色填充位圖RECT rcBitmap = 0, 0, ibWidth, ibHeight

23、 ;FillRect(memDC, &rcBitmap, hBrush);/還原:使用原來對象替換內(nèi)存設(shè)備中的位圖對象SelectObject(memDC, hOldBitmap);/刪除內(nèi)存設(shè)備DeleteDC(memDC);/刪除筆刷DeleteObject(hBrush);return bitmap;4.3 GDI圖形操作4.3.3 設(shè)備無關(guān)的位圖設(shè)備無關(guān)的位圖(Device-Independent Bitmap, DIB)主要體現(xiàn)顏色模式與設(shè)備無關(guān)。一幅256色的DIB圖像即可以在真彩色顯示模式下顯示,也可以在16色模式下顯示;DIB擁有自身的顏色表,其像素的顏色可以不受系統(tǒng)調(diào)色板影響

24、而保持穩(wěn)定性;DIB可以用來永久性地保存圖像。圖像可以保存為*.BMP格式,有時也可以保存為*.DIB文件格式。4.3 GDI圖形操作1. DIB位圖信息描述DIB位圖信息采用BITMAPINFO結(jié)構(gòu)體來描述;該結(jié)構(gòu)體中包含兩個組成部分:一個是BITMAPINFOHEADER結(jié)構(gòu)體,描述位圖頭部信息;另一個是定義位圖像素信息的RGBQUAD結(jié)構(gòu)類型的字節(jié)數(shù)組。BITMAPINFO結(jié)構(gòu)體的原型定義如下:typedef struct tagBITMAPINFO BITMAPINFOHEADER bmiHeader; RGBQUADbmiColors1; BITMAPINFO;BITMAPINFOH

25、EADER結(jié)構(gòu)體的定義請參見教程。RGBQUAD結(jié)構(gòu)體的定義請參見教程。 4.3 GDI圖形操作2. DIB位圖文件描述DIB位圖文件可以分為四部分:位圖文件頭,以BITMAPFILEHEADER結(jié)構(gòu)體表示(定義請參見教程);位圖信息頭,以BITMAPINFOHEADER結(jié)構(gòu)體表示(定義請參見教程) ;調(diào)色板,以RGBQUAD表示(定義請參見教程) ;調(diào)色板針對的是有調(diào)色板的位圖,也就是單色、16色和256色的位圖。如果不以調(diào)色板方式存儲的位圖,此項信息沒有。實際的圖像數(shù)據(jù),以像素陣列的形式表示。對于用到調(diào)色板的位圖,實際的圖像數(shù)據(jù)為該像素的顏色在調(diào)色板中的索引值;對于真彩色圖,圖像數(shù)據(jù)則為實

26、際的R、G、B值。要用3個字節(jié)表示1個像素的顏色R、G、B值。 4.3 GDI圖形操作3. DIB位圖的加載與信息讀取1) 加載DIB位圖調(diào)用GDI函數(shù)LoadImage()加載一個與設(shè)備無關(guān)的位圖;該函數(shù)可以加載圖標(biāo)、光標(biāo)以及位圖;該函數(shù)只能加載bmp格式的位圖。其原型定義為:HANDLE LoadImage ( HINSTANCE hinst,LPCTSTR lpszName,UINT uType,int cxDesired,int cyDesired,UINT fuLoad );4.3 GDI圖形操作2) 讀取DIB位圖信息調(diào)用GetObject()函數(shù)可以讀取成功加載的位圖信息;如位的

27、信息、像素信息、圖像的寬、高等。其原型定義如下:int GetObject( HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject );4.3 GDI圖形操作3) 獲取DIB位圖讀取的信息調(diào)用GetObject()函數(shù)獲取DIB信息時,該函數(shù)會將讀取的DIB信息寫入一個特定的結(jié)構(gòu)體中,這個結(jié)構(gòu)體就是DIBSECTION;它用來記錄DIB相關(guān)信息。其原型定義如下:typedef struct tagDIBSECTION BITMAP dsBm; BITMAPINFOHEADER dsBmih; DWORD dsBitfields3; HANDLE dsh

28、Section; DWORD dsOffset; DIBSECTION;4.3 GDI圖形操作4. 編寫DIB位圖加載及信息讀取函數(shù)該函數(shù)命名為LoadBmp(),該函數(shù)的原型聲明如下:BOOL LoadBmp ( LPTSTR path ); 在函數(shù)代碼實現(xiàn)之前,要聲明一個HBITMAP類型的變量來保存加載后的位圖句柄,聲明兩個整型變量來保存位圖的寬高。變量聲明的代碼如下:HBITMAP hBitmap;/保存已加載的位圖的句柄int bmpWidth, bmpHeight;/已加載位圖的寬、高4.3 GDI圖形操作LoadBmp函數(shù)的具體實現(xiàn)如下:BOOL LoadBmp ( LPTSTR

29、 path )hBitmap = (HBITMAP)LoadImage(GetModuleHandle(0), path, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);if (!hBitmap) return FALSE; / 如果位圖加載失敗DIBSECTION dib;/ 如果位圖信息讀取失敗if (GetObject(hBitmap, sizeof(DIBSECTION), &dib) != sizeof(DIBSECTION) DeleteObject(hBitmap);hBitmap = 0;return FA

30、LSE;bmpWidth = dib.dsBmih.biWidth;bmpHeight =dib.dsBmih.biHeight;return TRUE;4.3 GDI圖形操作5. DIB空白位圖的創(chuàng)建實例創(chuàng)建與設(shè)備無關(guān)的位圖使用GDI函數(shù)CreateDIBSection()其原型定義如下:HBITMAP CreateDIBSection( HDC hdc, CONST BITMAPINFO *pbmi, UINT iUsage, VOID *ppvBits, HANDLE hSection, DWORD dwOffset );重寫創(chuàng)建空白DDB位圖的CreateBlankBMP函數(shù)實現(xiàn)可以創(chuàng)

31、建空白24位DIB位圖的功能。函數(shù)的原型定義如下:HBITMAP CreateBlankBMP (int ibWidth, int ibHeight, COLORREF crColor );本聲明去掉了原來第一個設(shè)備環(huán)境句柄參數(shù)本聲明第一和第二個參數(shù)為要創(chuàng)建的空白DIB位圖的寬和高第三個參數(shù)是位圖填充使用的顏色,同樣使用RGB宏進行指定4.3 GDI圖形操作CreateBlankBMP函數(shù)的實現(xiàn)代碼: HBITMAP GdiTest:CreateBlankBMP(int ibWidth, int ibHeight, COLORREF crColor)void* Bits;/ 指向保存位圖位值的

32、地址BITMAPINFOHEADER Header;/ 位圖頭信息Header.biSize= sizeof(BITMAPINFOHEADER);Header.biWidth= ibWidth;Header.biHeight= ibHeight;Header.biBitCount= 24;Header.biPlanes= 1;Header.biCompression = BI_RGB;HBITMAP hbmp = CreateDIBSection( NULL, (BITMAPINFO*)&Header, DIB_RGB_COLORS, &Bits, NULL, 0); if(hbmp != N

33、ULL) /使用指定顏色填充空白位圖4.3 GDI圖形操作/創(chuàng)建一個內(nèi)存設(shè)備用來繪制位圖HDC memDC = CreateCompatibleDC(GetDC(NULL);/創(chuàng)建一個單色畫刷,用于填充所創(chuàng)建的空位圖HBRUSH hBrush = CreateSolidBrush(crColor);/將創(chuàng)建的空位圖替換內(nèi)存設(shè)備中的原來對象HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, hbmp);/用指定的顏色填充位圖RECT rcBitmap = 0, 0, ibWidth, ibHeight ;FillRect(memDC, &rcBit

34、map, hBrush);/ 恢復(fù)原有的位圖對象SelectObject(memDC, hOldBitmap);DeleteDC(memDC); /刪除內(nèi)存設(shè)備DeleteObject(hBrush); /刪除筆刷return hbmp;4.4 GDI繪圖函數(shù)GDI為圖形操作提供了豐富的操作函數(shù),了解并熟悉GDI常用的繪圖函數(shù)是圖形操作的基礎(chǔ)。4.4.1 BitBlt()函數(shù)函數(shù)功能:把參數(shù)hdcSrc表示的源設(shè)備中的位圖復(fù)制到參數(shù)hdcDest表示的目標(biāo)設(shè)備中,兩個設(shè)備可以是內(nèi)存設(shè)備,也可以是同一個設(shè)備,該函數(shù)是GDI中使用頻率很高的一個函數(shù),函數(shù)的繪圖效率也很高,常用于設(shè)備間位圖的快速拷貝

35、。本書的游戲引擎也是利用它把內(nèi)存設(shè)備中合成的游戲畫面繪制到實際屏幕上。其原型聲明為:BOOL BitBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop );4.4 GDI繪圖函數(shù)4.4.2 StretchBlt()函數(shù)函數(shù)功能:是把位圖從源矩形拷貝到目的矩形中,如果源目的和目的矩形的尺寸不同,那么將縮放位圖的功能以適應(yīng)目的矩形的大小函數(shù)的大部分參數(shù)與BitBlt()函數(shù)相同,但多了兩個參數(shù)nWidthSrc和nHeight

36、Src用來指定源矩形的寬和高,利用這兩個源矩形的寬、高參數(shù)該函數(shù)可以將源圖像的局部圖像拷貝到目的設(shè)備中函數(shù)原型聲明為:BOOL StretchBlt( HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);4.4 GDI繪圖函數(shù)4.4.3 AlphaBlend()函數(shù)在GDI中,大部分圖形操作函數(shù)都不處理圖像

37、的透明度信息,即使是帶Alpha通道的32位圖像時,其Alpha通道值也會被忽略。因為在描述RGB顏色值的COLORREF 數(shù)據(jù)類型中盡管有4個字節(jié)的長度,足以處理Alpha通道值及R、G、B的值。但其只處理了R、G、B的值。根據(jù)微軟技術(shù)文檔,COLORREF類型的最高位必須為0。在GDI的眾多函數(shù)中,只有AlphaBlend()函數(shù)可以做到以指定透明度來顯示位圖。該函數(shù)原型如下:BOOL AlphaBlend(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int hHeightDest,HDC hdcSrc,

38、 int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,BLENDFUNCTION blendFunction);BLENDFUNCTION結(jié)構(gòu)體的原型定義請參見教程4.5 GDI+圖形操作GDI繪圖效率高,但僅支持bmp格式圖像,而且無法處理位圖中的透明度信息;將GDI和GDI+結(jié)合應(yīng)用,可以做到既有GDI的繪圖效率,又能支持多種圖像格式。4.5 GDI+圖形操作4.5.1 GDI+簡介GDI+是以GDI為基礎(chǔ)構(gòu)建的更高一層的圖形子系統(tǒng),它有兩種封裝方式:C+封裝托管代碼封裝:供.NET框架使用C+封裝中包含54個C+

39、的類,這些類中共有大約600個函數(shù)。函數(shù)實現(xiàn)被封裝在Gdiplus.dll文件中,函數(shù)聲明保存在Gdiplusflat.h文件中。GDI+基于圖形環(huán)境(Graphics Context);圖形環(huán)境通過Graphics類對象來操作。設(shè)備環(huán)境和圖形環(huán)境在功能上是類似的,都要與顯示窗口關(guān)聯(lián)。4.5 GDI+圖形操作GDI+采用面向?qū)ο蟮木幊谭椒?,GDI+圖形操作前,首先要定義并構(gòu)建一個Graphics類對象,這也就是所謂的圖形環(huán)境。GDI+的畫筆、畫刷、路徑、圖像、字體等對象并沒有包含在Graphics類中,它們是作為獨立的類存在。要使用繪圖對象,你要創(chuàng)建它們,然后將他們作為參數(shù)傳遞給Graphic

40、s類中要調(diào)用的方法。GDI+的圖形環(huán)境不與特定的畫筆、畫刷等對象綁定在一起,同樣的函數(shù)可以使用不同的畫筆或者畫刷對象。4.5 GDI+圖形操作4.5.2 Graphics類GDI+的核心類是Graphics類它與特定的設(shè)備環(huán)境相關(guān)聯(lián)在設(shè)備環(huán)境和圖形內(nèi)容之間充當(dāng)媒介提供了將對象繪制到顯示設(shè)備的方法。Graphics類四個構(gòu)造函數(shù):Graphics:Graphics(Image*)Graphics:Graphics(HDC)Graphics:Graphics(HDC, HANDLE)Graphics:Graphics(HWND, BOOL)4.5 GDI+圖形操作Graphics提供的繪圖操作可以

41、分為三類:1)矢量圖形繪制:包括:圓弧、曲線、Bezier曲線、橢圓、圖像、線條、矩形等圖形的繪制;2)圖像處理與顯示:如位圖繪制、位圖旋轉(zhuǎn)、鏡像處理等Graphics類中提供了多達18個DrawImage()的重載函數(shù),可以滿足各種情況的圖像繪制需求;3)文字顯示:可以對文字進行字體、字號、顏色以及風(fēng)格等的設(shè)定。Graphics類中并沒有包含畫筆、畫刷、路徑、圖像、字體等對象要使用Graphics類提供的繪圖函數(shù),還要創(chuàng)建相應(yīng)的繪圖對象,并將它作為參數(shù)傳入要調(diào)用的函數(shù)中例如:文字顯示函數(shù)DrawString(),需要配合使用Font類、StringFormat類以及Brush類的對象來設(shè)定顯

42、示文字的字體、格式及顏色等。4.5 GDI+圖形操作4.5.3 Image類與Bitmap類在GDI+中,用于圖像加載、保存和處理的類有三個,分別是:Image 類Bitmap類Metafile類(用于矢量圖像處理)1. Image類Image類支持的圖像文件格式包括:bmp、gif、jpeg、png、tiff、exif、icon等;并封裝了對這些格式圖像的加載、格式轉(zhuǎn)換以及簡單的圖像處理功能Image類最常用的構(gòu)造方式:Image(const WCHAR* filename, BOOL useEmbeddedColorManagement = FALSE);4.5 GDI+圖形操作例如:讀取

43、并顯示位圖文件,下面幾行代碼就可以完成:Graphics g(hdc);Image* pImg = new Image(L.resbing.jpg);g.DrawImage(pImg, 0, 0);delete pImg;pImg = NULL;g.ReleaseHDC(hdc);4.5 GDI+圖形操作2. Bitmap類Bitmap類是從Image類派生的一個圖像類;它擴展了Image類的功能,類中封裝了位圖操作的常用函數(shù),如位圖縮放、旋轉(zhuǎn)、復(fù)制等;Bitmap類繼承了Image類對多種格式位圖文件的支持。Bitmap類中包含多達10個重載的構(gòu)造函數(shù),提供了足夠豐富的方式來獲取Bitmap

44、類對象。例如下面的代碼:Graphics g(hdc);Bitmap* pBmp = Bitmap:FromFile(L.resbing.jpg);g.DrawImage(pBmp, 0, 0);g.ReleaseHDC(hdc);4.5 GDI+圖形操作把上面代碼中的FromFile()函數(shù)調(diào)用替換為如下構(gòu)造函數(shù)方式,效果也是一樣。 Bitmap* pBmp = new Bitmap(L.resbing.jpg);Bitmap類提供了對位圖像素進行讀寫操作的功能。GetPixel()函數(shù)可以獲取當(dāng)前位圖中指定像素的顏色數(shù)據(jù);SetPixel()函數(shù)可以修改當(dāng)前位圖中指定像素的顏色數(shù)據(jù)。利用這

45、兩個函數(shù)可以對位圖圖像進行柔化、銳化或其它處理。Bitmap類還提供了高速訪問位圖文件流的函數(shù):LockBits()函數(shù)和UnlockBits()函數(shù)可以高效地對位圖文件流進行操作。下面利用這兩個函數(shù),實現(xiàn)一個將HBITMAP句柄轉(zhuǎn)換為Bitmap對象的實用轉(zhuǎn)換函數(shù)。4.5 GDI+圖形操作【例4-1】HBITMAP_To_Bitmap()函數(shù)的實現(xiàn)。Bitmap類中已經(jīng)有一個類似功能的FromHBITMAP()函數(shù)如果位圖句柄是通過GetHBITMAP()函數(shù)獲得的,原位圖中的透明像素會變成調(diào)用該函數(shù)時設(shè)定的背景色,失去了透明信息。因為GDI使用的RGB顏色模式,而GDI+使用ARGB顏色模

46、式。HBITMAP_To_Bitmap ()可保留透明信息,其原型定義如下:Bitmap* HBITMAP_To_Bitmap(HBITMAP hbmp, HDC hdc);實現(xiàn)該函數(shù)功能的關(guān)鍵就是LockBits()函數(shù)和UnlockBits()函數(shù)。LockBits()函數(shù)鎖定位圖矩形區(qū)域,提供可以用指定格式進行讀寫操作的臨時緩沖區(qū)。UnlockBits()函數(shù)就可以拷貝任何寫入到臨時緩沖區(qū)的像素數(shù)據(jù)到位圖對象中。具體函數(shù)實現(xiàn)請參見教程。4.5 GDI+圖形操作4.5.4 圖像顯示Graphics類的DrawImage()函數(shù)是圖像顯示的核心函數(shù),該函數(shù)有多達30個重載函數(shù)。以下是3個常用

47、的重載函數(shù):Status DrawImage( Image* image, INT x, INT y);Status DrawImage( Image* image, const Rect& rect);Status DrawImage( Image* image, INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit);4.5 GDI+圖形操作4.5.5 圖像旋轉(zhuǎn)與翻轉(zhuǎn)GDI+提供了豐富的圖像旋轉(zhuǎn)與翻轉(zhuǎn)處理方式如:旋轉(zhuǎn)90度、180度、270度還可以在旋轉(zhuǎn)時選擇是否作垂直或水平翻轉(zhuǎn)等。Image類的RotateFlip()函數(shù)就是為圖像旋轉(zhuǎn)與翻轉(zhuǎn)處理設(shè)計的。該函數(shù)的原型定義如下: Status RotateFlip(RotateFlipType rotateFlipType);這個函數(shù)只有一個名為RotateFlipType枚舉類型的參數(shù),該枚舉類型定義了多種圖像旋轉(zhuǎn)與翻轉(zhuǎn)處理常量,具體請參見教程表4-1。利用Rotate

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論