繪圖是屬于GDI的對(duì)象之一,在一套游戲開(kāi)發(fā)過(guò)程中,常常需要運(yùn)用大量的位圖來(lái)構(gòu)建游戲的所有畫(huà)面。
以游戲程序來(lái)說(shuō),由于使用的位圖數(shù)量相當(dāng)多,因此都會(huì)先將位圖存成文件,等到程序需要時(shí)再將文件加載到窗口中。
將位圖從文件中加載到繪制窗口中必須經(jīng)過(guò)以下幾個(gè)步驟:
①?gòu)奈募屑虞d位圖(BITMAP)對(duì)象。
②建立一個(gè)與窗口DC兼容的內(nèi)存DC。
③內(nèi)存DC使用步驟1所建立的位圖對(duì)象。
④將內(nèi)存DC的內(nèi)容粘帖到窗口DC中,完成顯像的操作。
以上是大致的流程,接下來(lái)一步步地說(shuō)明如何完成這些操作
步驟一:加載位圖
要從文件加載位圖,常使用LoadImage()函數(shù)
HANDLE LoadImage( HINSTANCE 來(lái)源實(shí)體, //加載位圖
LPCTSTR 名稱(chēng),
UINT 位圖類(lèi)型,
int 加載寬度,
int 加載高度,
UINT 加載方式,);
詳細(xì)說(shuō)明如下:
|
參數(shù)
|
說(shuō)明
|
|
HINSTANCE
|
包含位圖所在的實(shí)體,若要加載的位圖存在于硬盤(pán)或者資源文件中,則將此項(xiàng)參數(shù)設(shè)為”NULL”
|
|
LPCTSTR
|
要加載位圖所在的路徑與文件名或者資源名稱(chēng)
|
|
UINT
|
加載位圖的類(lèi)型,有下列3種:
◆IMAGE_BITMAP:加載的位圖為一般圖文件,擴(kuò)展名為“.bmp”
◆IMAGE_CURSOR:加載的位圖為光標(biāo)圖標(biāo),擴(kuò)展名為“.cur”
◆IMAGE_ICON:加載的位圖為圖標(biāo),擴(kuò)展名為“.ico”
|
|
int
|
位圖加載的寬度,單位為像素
|
|
int
|
位圖加載的高度,單位為像素
|
|
UINT
|
設(shè)定位圖的加載方式,若是從文件中加載位圖,則設(shè)為“LR_LOADFROMFILE
|
步驟二:建立與窗口DC兼容的內(nèi)存DC
內(nèi)存DC并不是真正的設(shè)備的DC,在這里把它揭示為一個(gè)緩沖區(qū)或許會(huì)更恰當(dāng)些。內(nèi)存DC用來(lái)暫存加載的位圖,由于最終會(huì)把存儲(chǔ)在這個(gè)內(nèi)存DC上的位圖貼到真正的窗口的DC上,因此這個(gè)內(nèi)存DC必須跟窗口DC的性質(zhì)兼容。可調(diào)用CreateCompatibleDC()函數(shù)來(lái)建立內(nèi)存DC。
HDC CreateCompatibleDC(HDC hdc); // 建立兼容DC
函數(shù)中輸入的唯一參數(shù)就是要與內(nèi)存DC兼容的目的DC。跟窗口DC一樣,內(nèi)存DC使用后也必須進(jìn)行釋放的操作,釋放內(nèi)存DC所調(diào)用的函數(shù)為DeleteDC()。
DeleteDC(HDC DC名稱(chēng)); //釋放DC
步驟三:選用位圖對(duì)象
位圖對(duì)象是GDI的6種對(duì)象之一,內(nèi)存DC選用位圖對(duì)象的方法和前面介紹的選用畫(huà)筆或畫(huà)刷的方式相同,都是通過(guò)調(diào)用SelectObject()函數(shù)來(lái)實(shí)現(xiàn)。
步驟四:貼圖
把內(nèi)存DC中的位圖復(fù)制到顯示的DC上,這個(gè)操作被稱(chēng)為“貼圖”。函數(shù)是BitBlt():
BOOL BitBlt ( HDC 目的DC,
int 目的DC X坐標(biāo),
int 目的DC Y坐標(biāo),
int 貼到目的DC的寬度,
int 貼到目的DC的高度,
HDC 來(lái)源DC,
int 來(lái)源DC X坐標(biāo),
int 來(lái)源DC Y坐標(biāo),
DWORD 貼圖方式)
BitBlt()函數(shù)最后一個(gè)參數(shù)所輸入的是稱(chēng)為“Raster”的運(yùn)算值,這個(gè)值是用來(lái)設(shè)定內(nèi)存DC到目的DC的貼圖方式。范例中輸入的Raster值是SRCCOPY,表示貼圖后的位圖與原來(lái)的位圖完全一樣,下表列出了可使用的Raster值及說(shuō)明。
|
Raster值
|
說(shuō)明
|
|
BLACKNESS
|
將來(lái)源位圖轉(zhuǎn)換為黑色
|
|
DSTINVERT
|
將目的地DC做“NOT”運(yùn)算
|
|
MERGECOPY
|
將選擇的筆刷與來(lái)源位圖做“AND”運(yùn)算
|
|
MERGEPAINT
|
先將來(lái)源位圖做“NOT”運(yùn)算,再與目的地DC做“OR”運(yùn)算
|
|
NOTSRCCOPY
|
將來(lái)源位圖做“NOT”運(yùn)算
|
|
NOTSRCERASE
|
先將來(lái)源位圖與目的地DC做“OR”運(yùn)算,再將其做“NOT”運(yùn)算
|
|
PATCOPY
|
將選擇的筆刷貼到目的地DC上
|
|
PATINVERT
|
將目的地DC與選擇的筆刷做“XOR”運(yùn)算
|
|
PATPAINT
|
先將來(lái)源位圖做“NOT”運(yùn)算,再與筆刷做“OR”運(yùn)算,最后再與目的地DC做“OR”運(yùn)算
|
|
SRCAND
|
將來(lái)源位圖與目的地DC做“AND”運(yùn)算
|
|
SRCCOPY
|
將來(lái)源位圖貼到目的地DC上
|
|
SRCERASE
|
先將目的地DC做“NOT”運(yùn)算,再與來(lái)源位圖做“AND”運(yùn)算
|
|
SRCINVERT
|
將來(lái)源位圖與目的地DC做“XOR”運(yùn)算
|
|
SRCPAINT
|
將來(lái)源位圖與目的地DC做“OR”運(yùn)算
|
|
WHITENESS
|
將來(lái)源位圖轉(zhuǎn)換為白色
|
范例ch2_5:從文件中加載位圖,并顯示在窗口上。
下載地址:ch2_5(上傳到windows live空間,可能需要MSN賬號(hào)登陸)
說(shuō)明:程序源代碼中有相關(guān)的注釋。
程序運(yùn)行結(jié)果如下圖:

PS:如想獲得更多關(guān)于Visual C++游戲開(kāi)發(fā)的內(nèi)容,可點(diǎn)擊隨筆:《Visual C++游戲編程基礎(chǔ)》學(xué)習(xí)筆記——索引隨筆。