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

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

4.4、建立表面
  DirectDrawSurface表徵了駐留在顯示中的一個表面。如果顯示記憶體用完了或者是顯式地建立,該表面也可存在於記憶體中。
你可以使用IDirectDraw2::CreateSurface方法建立一個或多個表面。CreateSurface時,必須指定表面的大小、表面型別(是單一表面還是複雜表面)、畫素格式(如果表面不使用的調色盤)。所有的這些特性都包含在DDSURFACEDESC結構中,在呼叫時需要將該結構的地址傳送過去。如果不支援請求的特性或者此前已經將那些資源分配給了另一個DirectDrawSurface物件,呼叫就會失敗。
  建立單一的表面或多表面只需要幾行簡單的程式碼。建立表面有四個主要的步驟。每一個步驟都需要比前一個步驟更多的準備工作,不過並不太難,它們是:
 (1). 建立主表面
 (2). 建立一個屏外表面
 (3). 建立複雜表面和翻轉鏈
 (4). 建立寬表面
  在預設的情況下,DirectDraw在本地影片記憶體建立一個表面,如果足夠的本地影片記憶體儲存該表面,DirectDraw就嘗試利用非本地影片記憶體(僅在一些AGP裝置系統中)。你可以在呼叫CreateSurface時對DDSCAPS結構賦以適當的標誌來顯式地指明在哪類記憶體中建立表面。
4.4.1、建立主表面
  主表面是當前在顯示器上可見的並且由DDSCAPS_PRIMARYSURFACE標誌指明的表面,每一個DirectDraw物件只能有一個主表面。
當你建立一個主表面時,其大小應該同當前的顯示匹配。因此,在這種情況下你不需要指明表面的大小。事實上,如果你指明瞭表面的大小,即使同當前的顯示模式匹配,也會導致建立過程的失敗。
  下面的例子顯示瞭如何設定DDSURFACEDESC結構的相關成員來建立主表面:
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
 // Tell DirectDraw which members are valid.
ddsd.dwFlags = DDSD_CAPS;
  // Request a primary surface.
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
 
4.4.2、建立屏外表面
  屏外表面通常用於點陣圖的快取,該點陣圖將被位塊傳輸到主表面或後臺緩衝區中。你必須設定包含DDSC_WIDTH和DDSD_HEIGHT標誌並設定dwWidth和dwHeight成員 為適當的值來說明屏外表面的大小。另外,還必須在DDSCAPS結構中包含DDSCAPS_OFFSCREENPLAIN標誌。
  當沒有足夠的顯示記憶體使用時,DirectDraw就使用系統記憶體來建立表面。你可以在DDSCAPS結構中的dwCaps成員包含DDSCAPS_SYSTEMMEMORY或 DDSCAPS_VOMEMORY標誌來顯式地指明是在顯示記憶體還是在系統記憶體中建立表面。下面的例子顯示了建立一個屏外表面之前的準備工作:
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
 
// Tell DirectDraw which members are valid.
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
 
// Request a simple off-screen surface, sized
// 100 by 100 pixels.
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
dwHeight = 100;
dwWidth = 100;
  在以前的版本中,屏外表面的最大寬度不能超過主表面的寬度。在DirectX 5中,你可以建立任意寬度的屏外表面,只要顯示裝置指出就行。需要注意的是,當宣告瞭屏外表面的寬度時,如果顯示記憶體容不下請求的表面的寬度,該表面將換在系統記憶體中建立。如果顯式地宣告使用影片記憶體,而影片記憶體又不夠時,建立表面的工作就會失敗。
4.4.3、建立複雜表面(Complex Surface)和翻轉鏈(Flip Chain)
  一個複雜表面就是用IDirectDraw2::CreateSurface方法建立的一組單一表面的組合。若在呼叫CreateSurface時設定了DDSCAPS_COMPLEX標誌,除了顯式指定的表面外,DirectDraw還將隱式地建立一個或多個表面。你可以象管理單一表面一樣管理複雜表面。呼叫IDirectDraw::Release方法會釋放所有的表面,呼叫IDirectDrawSurface3::Restore則會將這些表面恢復。
  最常用的複雜表面是翻轉鏈。通常,一個翻轉鏈由一個主表面和一個或多個後臺緩衝區組。DDSCAPS_FLIP標誌說明了某一表面是一翻轉鏈一部分。用這種辦法建立一個翻轉鏈還需要包含DDSCAPS_COMPLEX標誌。下面的例子建立一個主表面翻轉鏈所需要的準備工作:
DDSURFACEDESC ddsd;
ddsd.dwSize = sizeof(ddsd);
 
// Tell DirectDraw which members are valid.
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
 
// Request a primary surface with a single
// back buffer
ddsd.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FL|
DDSCAPS_PRIMARYSURFACE;
ddsd.dwBackBufferCount = 1;
  該例構建了一個雙緩衝翻轉環境。呼叫IDirectDrawSurface3::Flip方法將主表面和後臺緩衝區的表面記憶體。如果DDSURFACEDESC結構中的成員dwBackBufferCount取值為2,就會建立兩個後臺緩衝區,每次呼叫Flip就會迴圈地翻轉表面,並提供三緩衝翻轉環境。
4.4.4、建立寬表面(Wide Surface)
  DirectDraw允許建立比主表面寬的屏外表面,當然這需要顯示硬體支援才行。要確定顯示裝置是否支援寬表面,需要呼叫IDirectDraw2::GetCaps方法,檢視第一個DDCAPS結構中的dwCaps2成員是否包含DDCAPS2_WIDESURFACES標誌。如果該標誌存在,就表明可以在影片記憶體中建立比主表面還要寬的屏外表面。如果該標誌不存在,在影片記憶體中建立寬表面將會失敗,並返回一個DDERR_INVALIDPARAMS錯誤。
系統記憶體表面、影片埠表面和緩衝區都支援寬表面。
4.4.5、翻轉表面(Flipping Surface)
  DirectDraw中的任何表面都可以構建為一個翻轉表面。一個翻轉表面就是能夠在前臺緩衝區(front buffer)和後臺緩衝區(back buffer)之間互相交換的任意一塊記憶體。通常,前臺緩衝區就是主表面,但這並不是必需的。
當使用IDirectDrawSurface3::Flip方法執行表面翻轉操作時指向主表面的表面記憶體的指標和後臺緩衝區的表面記憶體的指標互換。因此,表面的翻轉是顯示裝置用於指向記憶體的指標的交換,而不是對錶面記憶體的複製。唯一的例外是,當DirectDraw用模擬翻轉時只是簡單地複製表面。如果一個後臺緩衝區不能裝入到顯示記憶體中或硬體不支援DirectDraw時,DirectDraw就用軟體模擬翻轉操作。當一個翻轉鏈包含了一個主表面和多個後臺緩衝區時,指標的轉換就採用了迴圈的方式週而復始,如下圖所示:
 
  DirectDraw物件的其它附加表面不是翻轉鏈的一部分,不受Flip方法的影響。切記,DirectDraw翻轉表面是透過交換DirectDrawSurface物件表面記憶體的指標實現的,而不是交換這些物件。這就意味著,位塊傳輸到後臺緩衝區時,必須一直使用同一個DirectDrawSurface物件,該緩衝區是你建立翻轉鏈的後臺緩衝區。而指向翻轉操作一直是透過呼叫前臺緩衝區的Flip方法完成的。
4.4.6、丟失表面(Losing Surface)
  當表徵表面記憶體的DirectDrawSurface物件不必要釋放時,同該表面關聯的表面記憶體卻被釋放了。這就是失去了表面。當DirectDrawSurface物件事情了它的表面記憶體時,許多方法就不執行其它的操作並返回DDERR_SURFACELOST。
因為改變了顯示模式或另一個應用獲得了對顯示裝置的獨佔訪問而釋放了當前分配的所有表面記憶體,表面就可能會丟失。
IDirectDrawSurface3::Restore方法重新建立這些丟失的表面並同DirectDrawSurface物件重新聯結。恢復表面並不裝入表面丟失之前存在的點陣圖。因此,如果丟失的表面,必須完全重新裝入此前曾裝入的圖形。
4.4.7、釋放表面(Releasing Surface)
  象所有的COM介面一樣,不需要表面時,必須呼叫Release方法釋放表面。每一個單獨建立的表面都必須顯式地釋放。如果是一次呼叫 IDirectDraw2::CreateSurface或IDirectDraw::CreateSurface方法顯式地建立的多個表面(如翻轉鏈等),你只需要釋放前臺緩衝區即可。在這種情況下,指向後臺緩衝區表面的任何指標都會顯式地釋放,並且不可再用。
4.4.8、表面特徵(Updating Surface Characteristics)
  你可以使用IDirectDrawSurface3::SetSurfaceDesc方法來更新已有表面的特徵。用該方法可以改變畫素格式,也可以改變DirectDrawSurface物件的表面記憶體在系統記憶體中的位置,該物件是應用顯式地分配的。它允許一個表面直接使用先前分配的緩衝區中的資料而不需要複製,這一新的表面記憶體由客戶應用來分配,也由該客戶應用來釋放。
  呼叫 IDirectDrawSurface3::SetSurfaceDesc方法時,lpddsd引數必須是描述新的表面記憶體的結構DDSURFACEDESC的地址,也就是指向該記憶體地址的指標。在DDSURFACEDESC結構中,可以只設定dwFlags成員來反映表面記憶體的位置、大小和畫素格式。因此dwFlags只能包含DDSD_WIDTH、DDSD_HEIGHT、DDSD_PITCH、DDSD_LPSURFACE和DDSD_PIXELFORMAT等標誌的組合,用這些組合來設定有效的結構成員。
  在設定結構的值前,必須分配記憶體來裝入表面。分配的記憶體的大小非常重要 。你不僅需要分配足夠的記憶體來容納表面的寬和高,還需要為表面間距(pitch)留下足夠的記憶體空間,表面間距是一個Q(8個位元組),間距是用高度而不是用畫素度量的。
  設定結構中表面的值時,lpSurface成員是你分配的記憶體的指標, dwHeight和dwWidth成員以畫素單位描述了表面的大小。如果指定了表面的大小,也需要填充Ipitch成員來反映表面間距。ddpfPixelFormat成員描述了表面的畫素格式。除了lpSurface成員外,若你不為這些成員設定值,IDirectDrawSurface3::SetSurfaceDesc方法就從當前的表面中使用預設的值。
在呼叫IDirectDrawSurface3::SetSurfaceDesc方法時需要注意一些問題。例如,lpSurface必須是系統記憶體的一個有效指標(該方法目前不支援影片記憶體指標);dwWidth和dwHeight必須是非0的值;不能在主翻轉鏈中重新分配主表面或其它任意表面。
  你可以為多個DirectDrawSurface物件分配同一記憶體,但必須注意當記憶體分配給任意表面物件後,就不能取消對該記憶體的分配。對SetSurfaceDesc方法不正確的使用會導致不可預料的反應。因此,當不再需要表面記憶體時,你必須記住釋放它。不過,在呼叫該方法時,DirectDraw將釋放建立表面時顯式分配的表面記憶體。
4.4.9、直接訪問幀緩衝區(Accessing the Frame-Buffer Directly)
  你可以使用IDirectDrawSurface3::Lock方法直接訪問幀緩衝區或系統記憶體中的表面記憶體。當呼叫該方法時,lpDestRect引數是一個RECT結構的指標。該結構描述了要直接訪問的表面上的矩形。若想鎖定整個表面,可將lpDestRect設為NULL。也可以指定一個只包含了表面的一部分的RECT。如果沒有兩個矩形重疊,兩個程式可以同時鎖定一個表面中的多個矩形。
  Lock方法用需要適當地訪問表面記憶體的所有資訊填充DDSURFACEDESC結構。該結構包含了有關表面間距和畫素格式的資訊(在同主表面的畫素格式不同時)。在完成了對錶面的訪問後,呼叫IDirectDrawSurface3::Unlock方法對其進行解鎖。
4.4.10、使用非本地影片記憶體表面(Using Non-local Video Memory Surfaces)
  DirectDraw支援高階圖形埠AGP(Advanced Graphics Port)特性,能夠在非本地影片記憶體中建立表面。在AGP系統中,如果本地影片記憶體已用完或應用程式顯式地要求使用非本地記憶體,DirectDraw將會使用非本地影片記憶體建立表面。
  目前,有兩種AGP體系。一種是“執行模型”(Execute Model),一種是“DMA模型”(Direct Memory Access Model)。在執行模型中,顯示裝置支援非本地影片記憶體和本地影片記憶體同樣的特性。因此,當使用 IDirectDraw2::GetCaps方法獲取硬體的時,同位塊傳輸相關的標誌dwNLVBCaps、dwNLVBCaps2、dwNLVBCKeyCaps、dwNLVBFXCaps和dwNLVBRops將指明用於本地影片記憶體。在執行模式下,如果本地影片記憶體被用完了,DirectDraw將自動使用非本地影片記憶體。
  在DMA模型中,對從非本地影片記憶體中位塊傳輸的紋理貼圖的支援是有限的。當顯示裝置使用了DMA模型時,欲獲得硬體的效能,dwCaps成員將被設為DDCAPS2_NONLOCALVIDMEMCAPS標誌。同位塊傳輸相關的標誌包含在dwNLVBCaps、dwNLVBCaps2、dwNLVBCKeyCaps、dwNLVBFXCaps和dwNLVBRops等成員中。除非顯式地指明,DirectDraw將不使用非本地影片記憶體建立表面。DMA模型的實現在對非本地影片記憶體表面的支援是不同的。如果程式支援從非本地影片記憶體表面的紋理貼圖,在用IDirect3DDevice2::GetCaps方法獲取3D裝置的效能時,D3DDEVCAPS_TEXTURENONLOCALVIDMEM標誌將被設定。
4.4.11、轉換顏色和格式(Converting Color and Format)
  非RGB表面格式由四個字元的程式碼(FOURCC codes)表示。如果應用程式呼叫了IDirectDrawSurface3::GetPixelFormat方法來要求使用畫素格式,並且表面是一個非RGB表面, DDPF_FOURCC標誌就會設定,DDPIXELFORMAT結構中的成員dwFourCC將成為有效的。如果FOURCC碼錶示的是一個YUV格式,DDPF_YUV標誌將被設定,dwYUVBitCount、dwYBits、dwUBits、dwVBits和dwYUVAlphaBits
成員將是有效的掩碼,能用於從畫素中提取資訊。
  如果當前是RGB格式,DDPF_RGB標誌就會被設定,dwRGBBitCount、dwRBits、dwGBits、dwBBits和dwRGBAlphaBits成員將是能夠用於從畫素中提前資訊的有效掩碼。
在顏色和格式的轉過程中,有兩組FOURCC程式碼用於應用程式中。一組表徵了硬體位塊傳輸的能力,另一組表徵了硬體覆蓋的能力。
4.4.12、覆蓋表面(Overlay Surfaces)
  覆蓋表面是具有特殊硬體支援能力的表面,通常用於顯示活動影片、錄製影片或靜止點陣圖而不需要位塊傳輸到主表面或改變主表面的內容。對覆蓋表面的字此完全由硬體提供,DirectDraw支援顯示裝置驅動程式所支援的特性,DirectDraw不模擬覆蓋表面。可以將覆蓋表面想象為一片塑膠紙,我們可以在這片塑膠上畫圖並可將其放置在顯示器前面。塑膠紙覆蓋在顯示器前面時,你可以看到覆蓋和主表面,移去塑膠紙後,主表面並沒有改變。覆蓋表面的工作原理同透明塑膠紙覆蓋的原理很相似。的顯示一個覆蓋表面時,就是告訴裝置驅動程式在哪裡怎樣使覆蓋表面可見。當顯示裝置掃描線重畫到顯示器上時,它檢查主表面上的每一個畫素,看是否被覆蓋所代替。如果是,顯示裝置就從覆蓋表面中抽取相關畫素的資料替代。
  使用這種方法,顯示適配卡在顯示器上生成主表面和覆蓋表面的合成表面, 產生透明和拉伸效果而不需要改變每個表面的內容。合成表面被送入影片資料流直接送到顯示器。因為這種處理和畫素替代是硬體級的操作,所以不存在明顯的效能損失。另外,這種方法還使得能夠用不同的畫素格式無縫地合成主表面和覆蓋表面。
建立覆蓋表面需要在DDSCAPS結構中指定 DDSCAPS_OVERLAY標誌,然後呼叫IDirectDraw2::CreateSurface方法覆蓋表面只能在支配記憶體中建立,因此還必須包含DDSCAPS_VIDEOMEMORY標誌。同其他型別的表面一樣,透過包含合適的標誌,可以 建立單一的覆蓋表面,也可以建立由多個覆蓋組成的翻轉鏈。
  你可以呼叫IDirectDraw2::GetCaps方法來獲取有關支援的覆蓋特性的資訊。該方法用描述所有的特性資訊填充一個DDCAPS結構。在報告硬體特性時,裝置驅動程式設定dwCaps成員的標誌來指明何時強制執行硬體提供的某種型別的。獲得的驅動程式的能力後,透過檢查dwCaps成員的標誌可知道提供的約束的資訊。DDCAPS結構包含了9個成員,這9個成員描述了覆蓋表面的約束資訊。下標列出了同覆蓋相關的成員既它們的標誌。
 
成員
標誌
dwMaxVisibleOverlays
該成員始終有效
dwCurrVisibleOverlays
該成員始終有效
dwAlignBoundarySrc
DDCAPS_ALIGNBOUNDARYSRC
dwAlignSizeSrc
DDCAPS_ALIGNSIZESRC
dwAlignBoundaryDest
DDCAPS_ALIGNBOUNDARYDES
T
dwAlignSizeDest
DDCAPS_ALIGNSIZEDEST
dwMinOverlayStretch
DDCAPS_OVERLAYSTRETCH
dwMaxOverlayStretch
DDCAPS_OVERLAYSTRETCH

  dwMaxVisibleOverlays和dwCurrVisibleOverlays成員指明瞭硬體可以顯示的覆蓋的最大數目,以及當前有多少個可見。
dwAlignBoundarySrc、dwAlignSizeSrc、dwAlignBoundaryDest、dwAlignSizeDest和dwAlignStrideAlign成員是硬體報告的矩形的位置和大小的約束。這些成員的值指明瞭在顯示覆蓋表面時如何確定源矩形和目的矩形的大小和位置。
dwMinOverlayStretch和dwMaxOverlayStretch是有關拉伸因子的資訊。
a、源矩形和目的矩形( and Destination Rectangles)
  要顯示一個覆蓋表面,需呼叫IDirectDrawSurface3::UpdateOverlay方法,在dwFlags 引數中指定 DDOVER_SHOW標誌。該方法要求你在lpSrcRect和lpDestRect引數中指定一個源矩形和目的矩形。若使用整個表面,將lpSrcRect引數設為NULL即可。目的矩形是在主表面上產生覆蓋表面的位置。
  源、目的矩形不必大小相同。一般讓目的矩形必源矩形大一些或小一些都可以,硬體在顯示時會自動地或拉伸。要想成功地顯示一個覆蓋表面,可能需要調整源、目的矩形的大小和位置,這一過程是否必要依賴於裝置驅動程式的限制。
b、邊界和大小調整(Boundary and Size Alignment)
  由於不同硬體的限制,一些裝置驅動程式對用於顯示覆蓋表面的源矩形和目的矩形的大小和位置做了約束。要找出裝置應用的約束,可呼叫IDirectDraw2::GetCaps方法,然後檢查DDCAPS結構中同覆蓋相關的dwCaps成員的標誌。下標列出了指定邊界和大小調整約束的成員和標誌。

類別
標誌
成員
邊界約束
DDCAPS_ALIGNBOUNDARYSRC
dwAlignBoundarySrc

DDCAPS_ALIGNBOUNDARYDEST
dwAlignBoundaryDest
大小約束
DDCAPS_ALIGNSIZESRC
dwAlignSizeSrc

DDCAPS_ALIGNSIZEDEST
dwAlignSizeDest

約束有兩種,邊界約束和大小約束。兩種約束都以畫素的方式表示,並且能夠用於源矩形和目的矩形。當然,由於覆蓋表面和主表面的畫素格式的不同,這些約束也可以不一樣。
  邊界約束影響源矩形和目的矩形放置的位置。dwAlignBoundarySrc和dwAlignBoundaryDest成員的值告訴你如何調整相關矩形的左上角。
矩形左上角的X座標(RECT結構中的left成員)必須是報告出的值的整數倍。
大小約束影響源矩形和目的矩形的有效寬度。dwAlignSizeSrc和dwAlignSizeDest成員的值以畫素的格式指出怎樣調整相關矩形的寬。如果按照一個最小拉伸因子拉伸矩形,應確保拉伸後的矩形仍然是大小調整過的。拉伸矩形之後,透過向上圓整來調整寬度,就可以保持最小的拉伸因子。
c、最大和最小拉伸因子(Minimum and Maximum Stretch Factors)
  由於硬體的侷限性,一些裝置限制了目的矩形同相關的源矩形寬度的比較。DirectDraw將這些約束作為拉伸因子。一個拉伸因子就是源矩形同目的矩形的寬度之間的比率。若驅動程式提供有關拉伸因子的資訊,在呼叫 IDirectDraw2::GetCaps 方法時後,它將在DDCAPS結構中設定 DDCAPS_OVERLAYSTRETCH標誌。注意,拉伸因子都已經乘以1000,所以值為1300的拉伸因子實際上是1.3。
  不壓縮和拉伸覆蓋目的矩形的裝置所報告出的最大最小拉伸因子通常是0。
  最小拉伸因子指出目的矩形比源矩形寬多少或窄多少。如果最小拉伸因子大於1000,就必須增加目的矩形的寬度。例如,若拉伸因子為1300,則目的矩形的寬度應該至少是源矩形寬度的1.3倍。如果拉伸因子小於1000,目的矩形就比源矩形的寬度要小。最大拉伸因子是目的矩形能夠拉伸的最大倍數。例如,若最大拉伸因子是2000,則目的矩形的寬度最多可以是源矩形寬度的2倍。若最大拉伸因子小於1000,
目的矩形就需要壓縮。經過拉伸之後,目的矩形必須遵守裝置要求的任何大小調整約束。因此,最後在大小調整之前拉伸目的矩形。硬體並不要求調整目的矩形的高度。你可以增加矩形的高度來保持方向比率的不變。
d、覆蓋Color Key
  象其它型別的表面一樣,覆蓋表面也使用源、目的Color Key來控制表面之間的透明位塊傳輸操作。因為覆蓋表面的顯示不是透過位塊傳輸完成的,所以在呼叫IDirectDrawSurface3::UpdateOverlay方法時就需要採取不同的辦法來控制覆蓋表面顯示在主表面上的方式。答案就是覆蓋Color Key。同位塊傳輸相關的Color Key相似,覆蓋Color Key也有源Color Key和目的Color Key,可透過呼叫方法
IDirectDrawSurface3::SetColorKey並利用DDCKEY_DESTOVERLAY標誌來設定源Color Key和目的Color Key。覆蓋表面能夠將位塊傳輸和覆蓋Color Key結合在一起來控制位塊傳輸操作和覆蓋顯示操作,兩種不同型別的Color Key並不互相沖突。
  IDirectDrawSurface3::UpdateOverlay方法用源Color Key檢查覆蓋表面中哪個畫素應該是透明的,允許主表面透過覆蓋表面顯示。同樣,該方法使用目的覆蓋Color Key來確定主表面顯示時哪部分允許倍覆蓋表面所覆蓋,其顯示效果同位塊傳輸Color Key相同。
e、 定位覆蓋表面(Positioning Overlay Surfaces)
  在最先呼叫IDirectDrawSurface3::UpdateOverlay方法顯示一個覆蓋時,可以用方法 IDirectDrawSurface3::SetOverlayPosition來更新目的矩形。必須確保你指定的目的矩形的位置遵守邊界對齊約束, IDirectDraw2::SetOverlayPosition方法並不執行剪下工作,使用了可能引起覆蓋越界的座標會使呼叫該方法失敗,並返回 DDERR_INVALIDPOSITION。
f、建立覆蓋表面(Creating Overlay Surfaces)
  象所有的表面一樣,你可以呼叫IDirectDraw2::CreateSurface方法來建立一個覆蓋表面。建立覆蓋表面還需要在相關的結構DDSCAPS 中包含 DDSCAPS_OVERLAY標誌。覆蓋支援許多顯示裝置,因此不能判斷一個給定的畫素格式是否被大多數的驅動程式所支援,必須做好準備使之能工作於多種畫素格式。你可以呼叫 IDirectDraw2::GetFourCCCodes方法來獲得驅動程式支援的有關非RGB格式的資訊。要建立一個覆蓋表面,最好使用最常用的畫素格式,若給定的畫素格式不被支援,DirectDraw會使用顯示裝置所支援的其他畫素格式。建立覆蓋表面翻轉鏈也是允許的。
g、翻轉覆蓋表面(Flipping Overlay Surfaces)
  同其他型別的表面一樣,你可以建立覆蓋表面翻轉鏈。一旦建立了覆蓋的翻轉鏈,就可以呼叫方法IDirectDrawSurface3::Flip來翻轉這些覆蓋。軟體解壓在呼叫Flip方法顯示覆蓋表面時可使用DDFLIP_ODD和 DDFLIP_EVEN標誌以減少運動贗象。如果驅動程式支援奇──偶翻轉,在獲得了驅動程式的能力後,DDCAPS2_CANFLIPODDEVEN標誌將會在DDCAPS結構中設定。一旦設定了DDCAPS2_CANFLIPODDEVEN,就可在呼叫IDirectDrawSurface3::UpdateOverlay方法時包含DDOVER_BOB標誌以通知驅動程式使用“Bob”演算法最小化運動贗象。此後,用DDFLIP_ODD或 DDFLIP_EVEN標誌呼叫Flip時,驅動程式將會自動調整覆蓋的源矩形來彌補抖動贗象。
  如果獲取硬體的能力後沒有設定DDCAPS2_CANFLIPODDEVEN標誌,但在呼叫UpdateOverlay時又使用了
DDOVER_BOB標誌,那麼該呼叫將會失敗。


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

相關文章