詳細講解DirectDraw程式設計基礎(轉)
詳細講解DirectDraw程式設計基礎(轉)[@more@] 本文面向有幾個月學習程式設計經歷的初學者:看過C++的教程,看的懂基本的C++語法;有點點VC使用經驗,知道怎麼去組建一個工程;理解一些windows程式設計的基本概念,比如視窗、訊息迴圈等;還有,不懂的地方會去查資料:)。 看過幾本關於DirectDraw的書,這些書都不錯,在此感謝她們的作者。美中不足的是這些書的部分起點較高,雖然我們仍然能夠清晰的理解一些概念,但在組織這些檔案上會有不少困惑。在此我重申一下書中的概念,也藉此梳理一下自己的思路。廢話少說,言歸正傳。 首先說一些不可不說的東西。我認為它們不可不提,是因為這些東西也許太基礎,高手們往往忽略這些東西對新手的作用。作為一個新手,我覺得掌握程式的框架及組織方法,比多熟悉幾個APIs更迫切一些。Now lets begin: 寫一個遊戲程式,要熟悉其流程,另外要鍛鍊組織程式檔案的能力。對新手來說,我建議按部就班的來處理及分析要寫的程式,不主張這個時候你在搞思維跳躍。這是個良好的習慣,當然也有利於我們儘快掌握程式設計的思想方法。下面來看一個概括的流程及相應的程式框架 (框架顯示不出來。。) 那麼,如何利用上面的流程來構建我們的大體程式框架呢? 我們已經知道一些windows程式設計方面的東西了,也許你還比較瞭解MFC。我們這裡不提倡用MFC,儘管它封裝了好多有用的模式,但對我們編遊戲來說,倒是累贅了。好,接著說。既然採用windowsAPI,可以建立個檔案WinMain.cpp來處理windows程式設計中有關視窗的一些問題。這樣,我們在該檔案中應該完成建立視窗,處理基本訊息(比如按“esc”退出等),控制程式退出等。遊戲過程中視窗的訊息是不是也要在這處理呢?當然,不過遊戲當中的視窗就不僅是windows視窗了,顯示部分要靠DirectDraw來控制,那麼我們只好在WinMain.cpp中呼叫相關的模組來處理。這麼看來,在WinMain.cpp中幾乎囊括了整個流程,不錯,它就控制了程式的整個框架,為你的程式核心提供了一個平臺。平臺有了,那麼下一步,GameMain.cpp要誕生了,這個主要用來控制整個遊戲的各個元件,協調各部分工作,完成遊戲設定初始化,遊戲中訊息迴圈,控制遊戲退出。你的才華就在這兒來盡情的發揮了。一般,遊戲程式會有幾個固定的元件的:顯示,音樂,資訊輸入。在DirectX中提供了很方便的元件DirectDraw,DirectSound和DirectMusic,DirectInput。相應的我們建立MyDirectDraw.cpp,MyDirectAudio.cpp,MyDirectInput.cpp來控制各部分元件的相應功能。 顯然,這3部分都是為GameMain.cpp服務的,被GameMain.cpp呼叫。那麼我們可以看出我們的程式應該包括的檔案及其包含關係為: (圖表顯示不出來了,555) 程式檔案怎麼去組織,應該由這個表可以看出來。這麼一看,我們發現,WinMain.cpp好像是一個投資者,提供開發平臺,他只關注整個專案總的程式,不關注細節。GameMain.cpp好像個專案負責人,整個專案的細節過程由他來策劃,來控制,向上與WinMain.cpp互動,來完成專案,向下協調MyDirectDraw.cpp,MyDirectAudio.cpp,MyDirectInput.cpp之間的工作。MyDirectDraw.cpp,MyDirectAudio.cpp,MyDirectInput.cpp這三個傢伙就是員工了,負責各自的工作,完成相應的功能給GameMain.cpp。 組織程式應該就是這麼個思路,當然具體問題具體分析。那麼我們下面來開始看DirectDraw部分了。 首先,做準備工作,安裝DirectX SDK,在VC中新增dxguid.lib和ddraw.lib(本來不想說這個,看到有個教程,它少加了dxguid.lib,鬱悶了我好一陣子,害人頗深感覺)這樣,directdraw程式才能透過編譯。提一下,dxguid.lib中定義了DirectX中會用到的所有全域性控制程式碼,ddraw.lib是DirectDraw使用的函式庫。 下面就可以寫程式碼了,這裡我們當然主要看MyDirectDraw.cpp該怎麼寫了 為此,我選出了幾個原始碼,做參考研究,它們會與本文一起打包。 我還是習慣先從整體上鳥瞰一下: 一般,在MyDirectDraw.cpp(注意不要忘記引用標頭檔案ddraw.h)中至少要有兩部分:初始化和結束。先看初始化,所謂初始化無非是個準備工作,需要的東西定義建立出來擺在手邊以備後用。來看看初始化函式intMyDirectDrawInit(void)該怎麼寫。首先定義一個指向DirectDraw物件的指標,建立DirectDraw物件,查詢以獲取最新的DirectDraw介面,設定協作等級,設定顯示模式。透過這些步驟可以建立一個黑色的螢幕了,也就是說已經開闢了我們需要的空間了,當然DirectDraw程式的初始化不會這麼簡單。要操作2d圖形,我們還要接著建立主頁面和緩衝頁面以及離屏頁面,總之根據需要,凡是需要在操作前需要準備好的東西都可以放在這裡。那麼結束 int MyDirectDrawShut(void)就應該釋放我們開闢的東西,一般要釋放主頁面指標,和DirectDraw介面等。 大體就是這麼個樣子,go on,該細一點了,呵呵 先定義指標:LPDIRECTDRAW lpDDraw_temp;代表整個顯示系統 建立物件: if (FAILED(DirectDrawCreate(NULL, &lpDDraw_temp, NULL))) { MessageBox(NULL,TEXT("Direct Draw Create error!"), TEXT("Wrong!"),MB_OK); return(0); } 這裡用了一個FAILED宏來檢測是否建立成功,這可以幫我們跟蹤錯誤。 函式DirectDrawCreate(NULL, &lpDDraw_temp, NULL)完成建立,第一個引數是顯示驅動的全域性唯一標誌符,這裡null表示目前的顯示裝置;第二個引數用來接受建立出來的DirectDraw物件地址,這裡用&lpDDraw_temp接受;第三個引數?不要問,就給它null,不想惹麻煩的話。 查詢DirectDraw介面:if(FAILED(lpDDraw_temp->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpDDraw7))) { MessageBox(NULL,TEXT("DirectDraw QueryInterface error!"), TEXT("Wrong!"),MB_OK); return(0); } 透過QueryInterface()方法來獲取新介面,這裡是IDirectDraw7而不是IDirectDraw8,指向IDirectDraw7的指標放在lpDDraw7中,這是個全域性變數,可以這樣定義LPDIRECTDRAW7 lpDDraw7=NULL; 順便說一下,一般情況下你是應該知道你使用的介面的,這和SDK有關,所以說這一步不是必須的。 設定協作等級: if (FAILED(lpDDraw7->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) { MessageBox(NULL,TEXT("DirectDraw SetCooperativeLevel error!"), TEXT("Wrong!"),MB_OK); return(0); } 決定你這個程式和windows的關係,它向windows申請所用資源,比如它要全屏,獨佔等。第一個引數是主視窗控制程式碼,就是你WinMain()中建立的那個了,第二個引數有幾個控制標誌,常用的用法如下: DDSCL_FULLSCREEN:全屏模式,必須和DDSCL_EXCLUSIVE同時使用 DDSCL_EXCLUSIVE:請求獨佔級別,須和DDSCL_FULLSCREEN同時使用 DDSCL_ALLOWREBOOT:允許系統檢測ctrl+alt+del按鍵訊息(這很有用) 我想,這三個就夠用了,其他的就先不用管了 設定顯示模式:if(FAILED(lpDDraw7->SetDisplayMode(800, 600, 16,0,0))) { MessageBox(NULL,TEXT("DirectDraw SetDisplayMode error!"), TEXT("Wrong!"),MB_OK); return(0); } 遊戲中要使用的顯示模式可能和使用者當前顯示模式不一樣,要在此統一設定SetDisplayMode()強制使用它設定的模式,它的前三個引數很容易懂吧,第四個,用0表示使用預設的重新整理率,第五個引數這裡是0,有書上說必須用DDSDM_STANDVGAMODE(可以理解,只是不知道這個0什麼意思,我想應該是default的意思吧。 到此為止,我想已經建立出來我們需要的空間了,以後,隨著我們要求的提高,再逐步完善初始化函式,now看看結束函式: 釋放介面: if (lpDDraw7) { lpDDraw7->Release(); lpDDraw7 = NULL; } 以後還要釋放主頁面,緩衝頁面等,需要注意一點的是一定要釋放你申請的資源,這是個好習慣,更應該注意的一點是先建立的一定要後釋放,因為後建立的可能是在先建立的環境下工作的。 到此為止,我們只是做好了最基礎的準備工作,什麼還都不能做呢 想做點什麼嗎?歇會吧,說點不得不說的題外話: 那麼我們來看看顏色吧。有關色彩,分這麼幾種,256色(8位的),16位增強色,24位真彩和32位真彩。256色估計很少用了,16位目前還是主流,所以我們著重看一下16位增強色,通常16位增強色有兩種格式:5.5.5和5.6.5,一般用RGB表示法表示。其中: 5.5.5格式,最高位為Alpha位,表示是不是透明,其餘15位表示顏色,紅綠藍各5位,這種格式可以表示32786種顏色。透過宏 #define _RGB16BIT555(r,g,b)((b%32)+((g%32)<<5)+((r%32)<<10))來轉變成5.5.5格式 對5.6.5格式,顯然,紅藍各5位,綠6位,這樣可以表示65536種顏色,同樣,宏 #define _RGB16BIT565(r,g,b) ((b%32)+((g%64)<<6)+((r%32)<<11))來轉變成5.6.5格式 中間的移位我也搞不清楚是怎麼回事,姑且先不看了,看的越多可能越胡塗哦 那麼到底該用哪種格式?看機器了,大部分可以用5.6.5,當然你可以檢測一下,至於怎麼檢測嘛,我就不說了,查查相關資料就可以了。24位呢?紅綠藍各8位唄,32位?添個Alpha位,其餘同24位。好了顏色就說到這裡。 下面想幹嘛?想在螢幕上搞點顏色出來,參看附的原始碼code1 你會不會發現我們還應該在上面的基礎上添點什麼?
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-951818/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring 面向切面程式設計AOP 詳細講解Spring程式設計
- 詳細講解23種設計模式設計模式
- Linux之19——Shell程式設計基礎詳解Linux程式設計
- Python程式設計入門基礎語法詳解Python程式設計
- shell程式設計-sed命令詳解(超詳細)程式設計
- 最詳細的測試用例設計方法講解
- MFC下CSocket程式設計詳解(轉)程式設計
- 【自動化基礎】allure描述用例詳細講解及實戰
- Python程式設計入門——基礎語法詳解(經典)Python程式設計
- 演算法--揹包九講(詳細講解+程式碼)演算法
- 史上最詳細 VUE2.0 全套 demo 講解 基礎4(條件渲染)Vue
- Linux Shell 程式設計基礎詳解——吐血整理,牆裂推薦!Linux程式設計
- dart類詳細講解Dart
- Java基礎之字串String詳細解釋Java字串
- 好程式設計師大資料培訓分享Hive基礎知識講解程式設計師大資料Hive
- Go Struct超詳細講解GoStruct
- 指標的詳細講解指標
- 機器學習之決策樹詳細講解及程式碼講解機器學習
- BSN-DDC 基礎網路 DDC SDK 詳細設計(八):示例
- 【詳細】Python基礎(一)Python
- PHP 詳細面試總結 (三 Redis 基礎詳解)PHP面試Redis
- javaScript基礎講解JavaScript
- Kotlin 物件導向程式設計 (OOP) 基礎:類、物件與繼承詳解Kotlin物件程式設計OOP繼承
- Python程式設計入門:接地氣的決策樹演算法基礎講解Python程式設計演算法
- Socket程式設計基礎程式設計
- Go程式設計基礎Go程式設計
- Shell程式設計-基礎程式設計
- python程式設計基礎Python程式設計
- shell程式設計基礎程式設計
- Tarjan演算法及其應用 總結+詳細講解+詳細程式碼註釋演算法
- Java中的static詳細講解Java
- react的詳細知識講解!React
- 詳細講解函式呼叫原理函式
- MyBatis-Plus詳細講解(一)MyBatis
- 《轉生成為前端程式設計師01-基礎篇》前端程式設計師
- 好程式設計師Python培訓分享Django中介軟體基礎用法詳解程式設計師PythonDjango
- 好程式設計師Python培訓之Django中介軟體基礎用法詳解程式設計師PythonDjango
- 影片解碼基礎講解
- Jmeter系列(6)- test plan測試計劃詳細講解JMeter