DirectX5.0最新遊戲程式設計指南 DirectDraw篇 三、DirectDraw的要素(四) (轉)

worldblog發表於2007-12-04
DirectX5.0最新遊戲程式設計指南 DirectDraw篇 三、DirectDraw的要素(四) (轉)[@more@]

5、調色盤(Palette)
  調色表面需要有調色盤才能正確地顯示出來。一個調色表面(既顏色標)是一些數字的簡單集合,其中每個每個數字都表徵了一個畫素。數字的值是一個顏色表的索引,它告訴DirectDraw顯示每個畫素時該使用什麼顏色。DirectDrawPalette通常稱為調色盤,它提供了管理顏色表的簡單方法。使用16位或更高位數的畫素格式的表面不使用調色盤。
  DirectDrawPalette物件表徵了具有2、4、16或256個實體的用於顏色索引表面的索引顏色表。調色盤中的每個實體都是一個RGB三元組,描述了顯示錶面內畫素所使用的顏色。顏色表可以包含16位和24位RGB三元組來表徵所用的顏色。對於16色的調色盤,顏色表也能包含另一個256色的調色盤的索引。調色盤可以應用在紋理、屏外表面和覆蓋表面中,它們都不要求具有和主表面相同的調色盤。
你可以IDirectDraw2::CreatePalette方法建立一個調色盤,該方法取得調色盤物件的IDirectDrawPalette介面的指標。然後就可以利用該介面的方法處理調色盤的實體,獲取有關物件能力的資訊或初始化物件(若調色盤是用COMCoCreateInstance建立的)。
  呼叫IDirectDrawSurface3::SetPalette方法可將一個調色盤附加在一個表面上。一個單一的調色盤可以應用到多個表面上。DirectDrawPalette物件對8位的調色盤保留實體0和實體255,除非你指定了 DDPCAPS_ALLOW256標誌要求這兩個實體可用。你可以用IDirectDrawPalette::GetEntries方法獲得調色盤實體,用IDirectDrawPalette::SetEntries方法修改調色盤實體。
5.1、調色盤型別
  DirectDraw支援1位、2位、4位和8位的調色盤。一個調色盤只能附給具有相同畫素格式的表面。例如,一個由DDPCAPS_1BIT標誌建立的2實體調色盤只能附給用 DDPF_PALETTEINDEXED1標誌建立的1位表面。另外,也可以建立完全不包含顏色表的調色盤,即索引調色盤。同顏色表不同的是,索引調色盤包含了索引值,這些值表徵了另一個調色盤顏色表的位置。
  要建立一個索引調色盤,需呼叫IDirectDraw2::CreatePalette方法,指定 DDPCAPS_8BITENTRIES標誌。例如,要建立一個4位調色盤,還需要指定DDPCAPS_4BIT和DDPCAPS_8BITENTRIES標誌。當建立索引調色盤時,要將一個指標傳遞給位元組陣列。
5.2、設定非主表面上的調色盤(Setting Palettes on Nonprimary Surfaces)
  調色盤能夠附在任意的調色表面(主表面,後臺緩衝區,屏外表面和紋理貼圖)上,但只有附在主表面上的調色盤才能影響調色盤。
必須注意的是,DirectDraw位塊傳輸不會顏色變換操作,任何附於位塊傳輸的源表面和目的表面都被忽略。非主表面上的調色盤主要用於Direct3D應用。
5.3、共享調色盤(Sharing Palettes)
  調色盤可以在多個表面之間共享。同一個調色盤可以附於一個翻轉鏈的前臺緩衝區和後臺緩衝區,也可以共享於多個紋理表面。當使用IDirectDrawSurface3::SetPalette方法將一個調色盤附於一個表面時,該表面就會增加該調色盤的索引值,當表面的索引值達到0時,該表面就會減少附著的調色盤的索引值。另外,如果一個調色盤同一個表面分離開,該表面的調色盤的索引值也會減少。
5.4、調色盤動畫(Palette Animation) 
  調色盤動畫是指在顯示時透過改變表面的調色盤來更改表面的外觀的過程。重複地改變調色盤,表面看起來就象是改變了,但實際上,表面的真實內容並無變化。因此,調色盤動畫提供了一種改變表面的顯示錶現而不改變表面的具體內容的方法。對於直線式的調色盤動畫可以提供兩種辦法:
  i. 在單一的調色盤修改調色盤實體
  ii. 在多個調色盤之間切換 
使用前一種方法,你可以改變耽擱調色盤中那些相關顏色的實體,然後呼叫 IDirectDrawPalette::SetEntries方法一次復位這些實體。第二種方法要求2個或多個DirectDrawPalette物件,然後呼叫IDirectDrawSurface3::SetPalette方法將一個接一個的調色盤物件附給表面物件從而產生
動畫。兩種方法都同無關,因此使用哪種方法主要是看是否適合應用程式。

6、剪下板(Clipper)
  剪下板或DirectDrawClipper物件允許位塊傳輸到表面中選定的部分。一個剪下板物件拔海內一個或多個剪下板列表。一個剪下板列表就是一個有界矩形或幾個有界矩形列,它是表面中允許位塊傳輸到的一塊或幾塊區域。這些區域都由RECT結構以螢幕座標的方式來表示。
  剪下列表是一個非常有用的工具,其中最常用的是禁止應用程式將資料塊寫到超出螢幕邊界的地方。例如,若要顯示一個精靈從螢幕邊界進入,你不希望精靈一下子就彈出出現在螢幕上,而是平滑地慢慢從螢幕邊界一點一點移動到螢幕中央。若沒有剪下板物件,就需要包含限制位塊操作以保護表面的邏輯。下圖顯示了這一類的剪下。
 
  你可以使用剪下板物件來芝麻一個目的矩形的一定區域是可寫的,DirectDraw將在這些區域對位塊傳輸加以剪下以保護指定的剪下矩形之外的畫素。這種剪下方式如下圖所示:
 
6.1、剪下列表(ClList)
  DirectDraw用DirectDrawClipper物件來管理剪下列表。一個剪下列表就是描述表面可見區域的一系列矩形。一個DirectDrawClipper物件可以附在任何表面之上。一個視窗控制程式碼也可以附在DirectDrawClipper物件上,在這種情況下,DirectDraw將使用視窗中的剪下列表來修改DirectDrawClipper剪下列表。
  儘管DirectDraw HAL中剪下列表可見,DirectDraw也只在用矩形位塊傳輸時才呼叫HAL來滿足剪下列表要求。例如,若一個表面的左上角矩形被剪下掉了,在應用程式將該表面塊寫到主表面時,DirectDraw將使用HAL執行兩次位塊傳輸操作,第一次是傳輸表面的左上角,第二次操作是傳輸表面的下半部分。
  透過 IDirectDrawClipper::SetClipList方法可以將這個剪下列表傳送給程式(如果該驅動程式支援剪下),而不是多次呼叫驅動程式。
另外,還能透過指定目的視窗的控制程式碼,呼叫 IDirectDrawClipper::SetHWnd方法將剪下板設到一個單一的視窗。只有當覆蓋硬體支援剪下或者目的Color Key還沒有被啟用時,覆蓋表面才支援剪下功能。
6.1、共享DirectDrawClipper物件
  DirectDrawClipper物件能在多個表面之間共享。例如,同一個DirectDrawClipper物件可以同時用於翻轉鏈的前臺和後臺緩衝區。當應用程式用IDirectDrawSurface3::SetClipper方法將一個DirectDrawClipper物件附於一個表面時,次表面就增加該物件的索引值。如果一個DirectDrawClipper物件同一個表面(該表面是用IDirectDrawSurface3::SetClipper方法由一個空剪下板介面指標建立的)分離,該表面的
DirectDrawClipper物件的索引值就會遞減。
6.3、獨立的剪下板物件
  你可以建立一個不直接從屬於任何一個DirectDraw物件的DirectDrawClipper物件。這種剪下板物件可以在多個DirectDraw物件之間共享。驅動程式獨立性的剪下板物件可用新的DirectDraw函式DirectDrawCreateClipper建立,應用程式可在建立任何DirectDraw物件之前呼叫該函式。
  因為DirectDraw物件不能擁有這些獨立的DirectDrawClipper物件,所以當應用中的物件釋放後,這些DirectDrawClipper物件並不會自動釋放。若應用程式沒有顯式地釋放這些剪下板物件,DirectDraw將在程式結束時釋放它們。
當然,你還是可以用 IDirectDraw2::CreateClipper方法建立DirectDrawClipper物件,用這種方法建立的剪下板物件在與其相關的DirectDraw物件釋放後會自動釋放。
6.4、用COM函式建立DirectDrawClipper物件
  DirectDrawClipper物件完全支援COM應用。除了使用標準的IDirectDraw2::CreateClipper方法和DirectDrawCreateClipper函式外,還可以用COM函式 CoGetClass 建立來建立剪下板物件。下面是用CoCreateInstance函式和IDirectDrawClipper::Initialize方法建立剪下板物件的例項:
 ddrval = CoCreateInstance(&CLSID_DirectDrawClipper,
  NULL, CLSCTX_ALL, &IID_IDirectDrawClipper, &lpClipper);
if (!FAILED(ddrval))
  ddrval = IDirectDrawClipper_Initialize(lpClipper,lpDD, 0UL);
  在對CoCreateInstance的呼叫中,第一個引數CLSID_DirectDrawClipper是剪下板物件類的類標誌, IID_IDirectDrawClipper參數列明了當前支援的介面,lpClipper引數是剪下板物件的指標。
  應用程式必須必須使用IDirectDrawClipper::Initialize方法來初始化剪下板物件, 0UL是dwFlags引數的值,本例中表示沒有使用任何標誌。lpDD是擁有該剪下板物件的DirectDraw物件;若用NULL代替lpDD,將會建立一個獨立的DirectDrawClipper物件,也將等價於用DirectDrawCreateClipper函式建立的剪下板物件。關閉應用程式之前,應該先用CoUninitialize函式關閉COM。
  DirectDraw通常為提供一種引導使用滑鼠的方法。對於使用頁翻轉的全屏獨佔的應用程式,唯一的選擇是在一個精靈上手工實現滑鼠的游標,依靠由DirectInput從裝置中獲取的資料或視窗的滑鼠訊息來移動精靈。任何不使用頁翻轉的應用程式也可以使用系統的滑鼠游標支援。
  使用系統的滑鼠游標時,在塊寫主表面的一部分時可能會出現影像贗象現象。在位塊傳輸操作中,剪下板物件可以防止這些贗象的出現。
在應用中,先用IDirectDraw2::CreateClipper方法建立剪下板物件,再用 IDirectDrawClipper::SetHWnd方法將應用的控制程式碼分配給剪下板。一旦剪下板附上了,任何隨後的用IDirectDrawSurface3::Blt方法實現的位塊傳輸的操作將不會出現贗象現象。
  你可以將一個剪下板物件塊寫到多個視窗。首先要建立一個只有一個主表面的DirectDraw物件,然後建立一個剪下板物件,再用 IDirectDrawSurface3::SetClipper方法將剪下板物件分配到主表面。要塊寫到視窗的客戶區(client area),需要在塊寫到主表面之前用IDirectDrawClipper::SetHWnd方法將剪下板設到視窗的客戶區。如果需要塊寫到另一個視窗的客戶區域,就用目標視窗的控制程式碼再呼叫
IDirectDrawClipper::SetHWnd方法一次。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987884/,如需轉載,請註明出處,否則將追究法律責任。

相關文章