動畫程序編寫——DirectDraw之旅(1)(異域の蝸牛注:老文章回顧)

  作者:不詳
 
DirectDraw——也許大多數人聞所未聞,但當提到 DirectX 恐怕每一個 遊戲愛好者都再熟悉不過了,但是隻知道那是一個很多遊戲都要求的必須安裝的程序,再多就無從所知了,那麼它到底能爲我們的遊戲幹什麼呢,其實它又叫 Game SDK,它最大的特點是直接對硬件的抽象層(HAL)進行操作,利用 此特點可製作出高性能的Windows遊戲。
http://www. microsoft.com/directx/default.asp。
DirectDraw就是DirectX5的6個組件之一。DirectX5的其它5個組件分別是:
Direct3D
提供了3D硬件接口。
DirectSound
立體聲和3D聲音效果,同時管理聲卡的內存。
DirectPlay
支持開發多人網絡遊戲,並能處理遊戲中網絡之間的通信問題。
DirectInput
爲大量的設備提供輸入支持。
DirectSetup
自動安裝DirectX驅動程序。
而DirectDraw則是DirectX的基礎,DirectX的其它組件都是建立在它的基礎之上的。DirectDraw使用頁面切換的方法實現動畫,它不僅可以訪問系統內存,還可以訪問顯示內存,這是以往的Windows程序員所不能的。(例如:如果你是用MFC中的CDC類進行繪圖,那麼它是絕對不會讓您直接訪問顯存的。) 另外,我們利用DirectDraw還可以生成、移動、剪切、轉換、合成圖像數據,從而編寫出各種“炫麗多彩”圖形的應用程序。
您先不要急,我們會在後面附上本文介紹的動畫程序原代碼,只要將其用vc打開,進行工程的編譯創建後,您就會立刻看到效果。並且我們在工程文件中有詳細的中文註釋,力求將理論與實踐緊密聯繫在一起。
首先,讓我們先了解一下DirectDraw的三個重要概念——表面、Bltting、色彩鍵碼
1.表面
在用DirectDraw編寫程序時,我們先要創建若干個圖形數據緩衝區,並把這些圖形數據裝入其中,再進行轉換、拉伸、挎貝等操作,並且還可以顯示這些緩衝區中的圖形數據,這些緩衝區就稱爲表面。
表面可以分爲幾類。
主表面(primary surface)是用戶在屏幕上可以看到的,它是顯示內存的一部分。所有DirectDraw程序都有主表面,而且只有一個。它在DirectDraw表面對象之前就已經存在了,因此不能改變它的尺寸、格式和位置。
主表面有一個很重要的特性——翻頁(flip)。頁面翻頁用於程序中,可以產生相當平滑、不閃爍的動畫。一個可以翻頁的主表面實際上是兩個表面,一個是可見的,一個是不可見的。不可見的表面稱爲後備緩衝區。當發生表面翻頁時,後備緩衝區就成爲可見的,而以前的可見主表面則成爲後備緩衝區。 下面我們用圖示來向您解釋上面的概念:


當翻頁後,將原後備緩衝區頁中的內容copy入可見主表面頁,而同時將原可見主表面頁的內容copy入後備緩衝區頁。
顯示器屏幕雖然每秒中刷新很多次,在此我們假定爲85次,但每次都是一遍一遍地讀取可見主表面中存儲的顯示頁信息,而你對後備緩衝區的改動不會顯示出來,並且也不會影響可見主表面的顯示,而只有當施行翻頁操作後,兩頁的內容互換,而你已經完成了的在原後備緩衝區的改動纔會顯示在屏幕上,而這個互相拷貝的過程幾乎是瞬間完成的,這個時間比起每次刷新所用的時間少得多得多,兩者幾乎差了幾乎幾十萬個數量級。而人眼是根本察覺不到的,所以用這種方法可以不閃爍,平滑,優質的動畫效果
還有一種表面叫離屏表面(off_screen surface),它是不能直接見到的。離屏表面作爲存儲緩衝區,有助於表面之間的互相切換,它的大小是可以改變的。
主表面和離屏表面都分爲有調色板的和無調色板的這兩類。像素深度爲8位(256色)的表面稱爲有調色板的表面;而像素深度爲16位(64K色)、24位(16M色)的像素表面稱爲無調色板的表面,它們存儲實際的色彩值(RGB值)。
在本文下面的程序中,我們先使用256位表面即有調色板的表面。
2. Bltting
Bltting是用於複製圖形的語言,可以將圖像從一處拷貝到另一處。例如大家所熟悉的CDC類(設備描述表類)的BitBlt()就是具有這樣功能的函數。
在DirectDraw中,典型的blt操作是將離屏表面的內容拷貝到一個後備緩衝區,而一般的blt操作調用一個源表面和一個目標表面,把源表面的內容拷貝到目標表面中,不僅可以整體拷貝源表面,而且還可以拷貝源表面內的任何矩形區域到目標表面的任何位置。blt還支持透明拷貝,就是指表面中的某一像素在blt過程中可以不予以拷貝,而這個像素值是由色彩鍵碼(DDCOLOR KEY )決定的。如圖:
DirectDraw中有三個支持blt的函數,它們是
Blt()
BltBatch()
BltFast()
Blt( )用得最多,BltFast()的速度比Blt()要快,但功能卻很有限,例如不支持拉伸、剪切等操作。
還有一個函數BltSurface(),它是DirectWin類的一個成員函數,Blt()、BltFast()更具有適應性,並且使用起來更加簡單。例如,當我們把源表面拷貝到目標表面外時需要裁剪,而BltFast()不支持裁剪。這時我們使用BltSurface()函數,它在內部使用Blt()和 BltSurface()函數,並根據情況自動執行裁剪。
在此,有人會問,這種頁面切換的方法到底好在那裏?它到底與用一般的繪圖方法的區別在什麼地方?而其它的繪圖方法爲什麼會使屏幕閃動呢?下面我們舉二個例子:(我們仍然用圖示的方法給您一個直觀的解釋)
(1) 在一些繪圖程序中您會發現其用到了清屏函數,這種方式是使屏幕效果最差的,這種方法使得沒有直接從第一個畫面切換到第二個畫面,而是先用黑色將圖形數據緩衝區清空,並且還顯示在屏幕上,但這個時間很短。如果反覆清屏,則會產生嚴重的屏幕閃爍。如下圖:
 
(2)在一些程序中用異或的方式進行繪圖,即先在屏幕上畫出第一個圖像,然後在畫第二個圖像之前,再在屏幕上畫一遍第一個圖像,這樣起到清除第一個圖像的效果。如果您仔細看,會發現這樣就會比上一個方法的畫面效果好得多,但這並不是很完美,因爲如果反覆使用,雖然不會產生全屏幕的閃動,但在所清除圖像處會產生閃爍。究其根本原因還是因其沒能直接從第一個畫面切換到第二個畫面。如下圖:
我想現在您應明白DirectDraw繪圖的優勢了吧,其實這就是對上述方法中缺點的很好的解決方法。

3.色彩鍵碼
DirectDraw 可以把某種顏色或某個範圍的顏色指定爲一個顏色值,這個顏色值是由DDCOLORKEY結構即色彩鍵碼說明的,DDCORLORKEY結構說明如下:
typedef struct _DDCOLORKEY
{
 DWORD dwColorSpaceLowValue; //顏色範圍的低端
 DWORD dwColorSpaceHighValue; //顏色範圍的高端
} DDCOLORKEY;
當我們對錶面進行拷貝操作時,表面中哪些像素不被拷貝是由色彩鍵碼決定的。例如當DDCOLORKEY結構的兩個分量都爲零時,表面內所有置爲零的像素都不能被拷貝。又例如,當表面是24位RGB模式時,若想指定RGB=(120,120,120)像素不被拷貝,則應該:
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue=RGB(120,120,120);
ddck.dwColorSpaceHighValue=RGB(120,120,120);
surf→SetColorKey(DDCKEY_SRCBLT,
&ddck);
其中SetColorKey()函數是把色彩鍵碼賦給表面surf。這樣,在對錶面surf的 blt操作期間RGB值爲(120,120,120)的像素不能被拷貝。
OK,我們現在已經具備基本的DirectDraw的知識,下面我們就來進行實戰演練(未完待續......)
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章