?? directdraw
字號:
DirectDraw 游戲編程基礎(1)
游戲使計算機的發展超越了晶體管時代
微軟公司供稿
內 容
1. 簡介
2. 使用 DirectX 3 SDK的基本環境
3. DirectDraw API
4. DirectDraw, OLE, 和COM接口
5. DirectDraw 起步
6. DirectDraw 的基本知識 (DDEX1)
7. 例一的擴展(DDEX2和DDEX3)
8. 生成簡單的動畫(DDEX4和 DDEX5)
9. 檢驗Duel例子
10. 關于最優化(Optimizations)和規范化(Customizations)
11. 下一步你應該干什么
簡 介
DirectDraw是微軟新近發行的DirectX 3軟件開發工具箱(SDK)中的一部分。對那些不甚了解的人來說,DirectX 3 SDK是原來稱為游戲SDK的最新版本。和在游戲SDK中一樣,DirectX 3 SDK包含了一組動態鏈接庫,用來圖形加速,3D圖形服務,聲音加速,擴展連接,游戲桿操縱以及CD-ROM自動化。
關于DirectX 3 SDK可以有很多的話題討論,本篇只涉及如何用DirectDraw來編寫游戲中的圖形部分。盡管需要一些有關OLE和構件模型(COM)接口的基礎知識,整個過程還是相當簡單的。而且,所需的有關OLE和COM接口的知識也將在此討論到。
讀完本篇后,您就可以用DirectDraw來寫簡單的游戲了。在這里,我只想討論如何使用最基本的DirectDraw函數。所舉的例子僅涉及到全屏和翻頁,不討論如何在窗口中使用DirectDraw,在3維圖中使用文字,使用視頻剪接或是用Direct3D生成表面。如果對這些內容感興趣,可以參閱有關的文檔。
使用 DirectX 3 SDK的基本環境
DirectX 3 SDK可以在Windows 95或Windows NT4.0中使用。基于本文的目的,假定使用的環境是IBM PC和Windows 95.另外,還需要安裝DirectX 3 SDK,以便編譯連接應用。
同時,使用的C或 C++ 編譯器應能生成32位的應用。您也可以使用其他的語言,但這里并不想涉及。當然您還應當具有Windows的編程技術。
如果使用的是C編譯器,則還必須包含Win32 SDK。Win32 SDK包含了生成可執行程序時的一些庫。
DirectDraw API
DirectDraw是整個軟件開發工具箱的一個構件。DirectDraw是為速度而設計的,它繞過與Windows的圖形設備相連的多個層次,直接與硬件的底層打交道。這很適合游戲編程來,因為它著重于快速產生平穩的圖形。
但DirectDraw最重要的一點在于它對不同的顯示適配器具有一個共同的接口。您不必管您的程序它是否會工作。DirectDraw利用包含在硬件抽象層(HAL)中的信息來決定顯示適配器的功能。(HAL是由顯示適配器廠商提供的)HAL為不同的硬件廠商和使用.DirectDraw的開發者提供了共同的接口。
然而,DirectDraw并不只限于利用顯示適配器的硬件功能。如果您的程序指定了某一種特定的顯示適配器,例如XXXX hardware blitter,但用戶并沒有該硬件,程序就會使用DirectDraw的硬件仿真層(HEL)。在這種情況下,DirectDraw利用內建的硬件仿真來仿真缺少的硬件。
圖一說明了DirectDraw和其他Windows顯示構件的聯系。
圖1. DirectDraw和其他Windows顯示構件
DirectDraw API由DirectDraw對象組成,它表示具體的顯示適配器。另外,DirectDraw API還包括表示surface的DirectDrawSurface對象,表示surface調色板的DirectDrawPalette對象和表示剪接列表的DirectDrawClipper對象。可以用DirectDraw對象來創建DirectDrawSurface和DirectDrawPalette對象。(也可用DirectDraw對象來創建DirectDrawClipper對象,但該剪接對象也可被獨立地創建。這就涉及到另外的話題了。)創建全屏游戲要用到的只是DirectDraw,DirectDrawSurface和DirectDrawPalette對象。
要了解這些對象是如何工作的,必須對OLE和COM接口有基本的了解。COM接口是所有DirectDraw編程的基礎。下一節將討論COM接口,如果您熟悉OLE,則可跳過它。
DirectDraw, OLE, 和COM接口
DirectDraw是圍繞著OLE和COM接口來設計的。如果您不熟悉OLE編程,那將很難開始用DirectDraw編程,這是最基本的一點。盡管在很多書上解釋了很多概念,介紹OLE和COM接口是如何工作的,但要用好DirectDraw其實只要了解有限的一些。
首先看看OLE和COM的定義。OLE是微軟為在不同的進程和機器間共享信息和服務而引進的基于對象的技術。COM指的是構件對象模型,在OLE編程中,它是接口模型。知道這些概念后就可不理它們了,因為這對我們編程并不重要。我們要繼續深入的是為用好DirectDraw所需了解的COM接口的最少的知識。
從本質上說,COM接口由三個成員組成:對象,接口和方法。對象實質上是一個黑箱,不需要管它里面是什么,因為我們只是通過接口來與它打交道。而要完成這一過程,通過的則是方法。如果您有一些硬件知識的話,可以把一個對象想象成一集成電路。與集成電路(對象)通訊是通過管腳(接口)來發送或接收信號(方法)。
所有的COM接口都是從OLE的Iunknown接口派生來的。通過保持Direcdraw對象的引用次數,Iunknown接口維護對象的生存期。另外,它提供了決定對象可用接口的方法。Iunknown接口由三種方法組成:AddRef,Release和QueryInterface。
AddRef和Release負責保持對象的引用計數。當創建了一個對象的實例時,對象的引用計數設為1。只要函數返回了對象接口的指針,該函數必須通過得到的指針調用AddRef,將引用計數增加1。(另外,當另一個應用與該對象相連時,引用計數也要加1。對我們來說,這一點并不重要,因為我們并不將其他的應用連到游戲上。)
當用完一個接口后,要通過指針來調用Release,將引用計數減1。要收回一個對象時,它的引用計數必須為0。當對象的引用計數為0時,對象將被消除,它所有的接口都無效了。
第三個方法,QueryInterface,查詢對象是否支持指定的接口。如果對象支持,則返回指向接口的指針。
AddRef,QueryInterface,和Release是如何與DirectDraw相連的呢?首先,我們沒有理由在只用DirectDraw的簡單游戲中使用AddRef和QueryInterface。DirectDraw創建了函數來負責增加引用計數并返回指向接口的指針。但您仍要對沒一個隱式創建的接口指針執行Release操作。如果沒有維護好對象的引用計數,將很容易引起內存泄露。在后面編碼的例子中,將介紹如何進行。(也可在將應用與另一應用使用的DirectDraw對象相連時,使用AddRef和QueryInterface。同樣,如果使用Direct3D,就不得不用QueryInterface來返回指向Direct3D接口的指針。這些內容都不在此討論。)
下面看一個使用IDirectDraw接口方法的C程序行。
Ddrval = lpDD->lpVtbl->SetDisplayMode( lpDD, ScreenX, ScreenY, ScreenBpp );
程序用了SetDisplayMode方法來設置顯示模式,返回值表示成功或失敗。在此重要的一點是如何取得指向方法的指針,不能直接訪問IDirectDraw接口方法。當一對象實例化時,它生成一個虛函數表,稱為vtable,它包含了指向該對象接口方法的所有指針。在上例中,指向DirectDraw對象的指針(lpDD)指向了指向vtable的指針(lpVtbl),vtable中包含了對象所有方法的指針,具體地說,本例中指向了SetDisplayMode方法。應用和方法接口間的聯系可以清楚地看成這樣:
下一個例子看看如何用C++來做:
ddrval = lpDD->SetDisplayMode( ScreenX, ScreenY, ScreenBpp );
注意vtable不再顯式地使用,C++自動地將對象(lpDD)作為第一個參數。不需要this指針,因為C++用指向當前對象的指針(本例中為lpDD)隱式地執行該方法。
如果想要了解更多的關于OLE和COM接口的知識,可以參閱Kraig Brockschmidt寫的“Inside OLE”(可在MSDN中得到)。這是我所知的關于OLE和COM的最好的書。我推薦您去閱讀該書的第一部分和第二部分的前半部分,以對COM接口有一個清楚的了解。這對您很好地理解DirectDraw和COM接口間的關系就已足夠了。
開始使用DirectDraw
前面已經說過應當安裝了DirectX SDK和C或C++編譯器。在這我們假定使用的是Microsoft Visual C++ 4.0,并已安裝在缺省的目錄下。如果使用的是其他的編譯器或軟件安裝在其他的目錄下,則必須對下面的例子做相應的修改。
由于所涉及的是DirectDraw的基本知識,因此這里使用的例子都是關于DirectX 3 SDK的簡單例子。它們示例了如何設置DirectDraw以及使用DirectDraw方法來執行簡單的操作。學完這些例子后,你將能比較容易地理解DirectX 3 SDK光盤上所帶的更為復雜的例子。
在正式開始前,還必須設置好編譯環境,這取決于你將如何使用Visual C++來編譯這些例子。我將示范如何用Microsoft Developer Studio來設置這些環境,或是在命令行下使用NMAKE。
安裝微軟開發工作室(Micorsoft Developer Studio):
Visual C++為那些喜歡使用接口的程序員提供了微軟開發工作室(Microsoft Developer studio)。在開始編輯例程Directx 3 SDK前,需要打開一個新project 工作區,然后插入適當的文件,再設置一系列的環境變量參數,以使編輯器能夠找到正確的庫文件和頭文件。下面我們要討論例程DDEX1。以下所列步驟說明如何創建DDEX1:
當你打開Microsoft Developer Studio 后,可使用以下步驟來創建project工作區:
1. 在菜單 File 中,選擇選項New。
2. 在新對話框中,選擇 Project Workspace(項目工作區),然后單擊 OK。
3. 在Type list 中選擇選項 Application。
4. 在Location box(搜索框),你可以通過選擇一個路徑來查找你所需的項目
5. 在 Name 文本框中,鍵入DDEX1。
6. 單擊Create后,一個名為DDEX1 Classes 的新文件夾出現在工作區窗口的
左部。
這樣你就創建好了一個項目工作區,使用以下步驟使你在該工作區插入一個適當的文件:
1. 在菜單 Insert 中,單擊選項 Files Into Project。
2. 瀏覽目錄:DXSDK\SDK\SAMPLES\DDEX1,并選擇該目錄下的所有文件。
3. 單擊 Add 選項,則工作區窗口左側的文件夾就會變成DDEX1。
4. 單擊folder name(文件夾)左側的"+",可查看到DDEX1文件夾中的文件列表。
為了能夠正確地編輯和鏈接 DirectDraw 例程,還需完成以下步驟為頭文件設置正確的路徑:
1. 在菜單 Tools 中,單擊 Options,則Options對話框就會被擊活。
2. 選擇 Directories 選項。
3. 在列出的目錄中,選擇頭文件所在的目錄。
4. 在目錄框中,雙擊列表底部的空白行(以長方形表示),然后鍵入: C:\DXSDK\SDK\INC。
5. 按回車鍵。
6. 在目錄框中,雙擊列表底部空白行并鍵入: c:\DXSDK\SDK\SAMPLES\MISC。
7. 單擊 OK 選項。
接下來,按以下步驟為庫文件選擇路徑:
1. 在目錄列表框中,選擇庫文件所在的目錄。
2. 選擇 Link 選項
3. 在目錄下拉盒中,找到 General 選項
4. 在 Objext/library 模塊下拉盒中,加入 Draw.lib 和 Winmm.lib
5. 單擊 OK 選項。
上面所列出的大多數步驟在創建新 Project 的過程中都會用到。其中目錄路徑和鏈接模塊被永久地加入到環境參量中。
為 NMAKE 設置路徑:
如果你更喜歡使用 NMAKE,你需要為庫模塊和頭文件設置正確的路徑。下面列出了 Visual C++ 4.0 所用到的所有路徑:
@echo off
set path=c:\MSDEV\BIN;%PATH%
set
INLUDE=C:\MSDEV\INCLUDE;C:\MSDEV\MFC\INCLUDE;C:\DXSDK\SDK\INC;%I
NCLUDE%
set LIB=C:\MSDEV\LIB;C:\MSDEV\MFC\LI;C:\DXSDK\SDK\LIB;%LIB%
set INIT=C:\MSDEV\;%INIT%
在批處理 autoexec.bat 中加入以上各行,并重新啟動計算機,你就可以方便地編輯你的程序了。(如果你使用的是Microsoft Visual C++ 2.0, 則你需要把上面的 MSDEV 改為 MSVC20,且其他路徑均不變)
為了實際編輯一個程序,進入該程序子目錄(例如:C:\DXDSK\SDK\SAMPLES\ DDEX4),并鍵入:
NMAKE
這將在當前目錄下創建一個DEBUG子目錄,并且在該子目錄下生成可執行文件。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -