雙緩衝技術
在離屏緩衝繪製映像,然後將其拷貝到顯示表面的處理過程被稱作雙緩衝技術。
實現:額外的一塊同主DirectDraw表面具有同樣尺寸的記憶體。並在這塊記憶體上畫每一幀動畫之後拷貝雙內在到主顯示表面。
如:申請640X480X8的記憶體
UCHAR *double_buffer = (UCHAR *) malloc (640*480);
或者
UCHAR *double_buffer = new UCHAR[640*480];
實現:讓後備緩衝顯示出來,可以把後備緩衝拷貝到主顯示頁面代碼如下:
DDSURFACEDESC2 ddsd; //directdraw 表面結構說明
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;//主表面指標
LPDIRECTDRAWSURFACE7 lpddsback = NULL;//後備緩衝指標
DDRAW_INIT_STRUCT(ddsd);//初始化ddsd
//藍色的表示ddsd的dwBackBufferCount欄位有效
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;//表示一個後備緩衝頁面
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;//步驟第二條
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);
return(0);//建立主表面
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
//主表面得到後備緩衝
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
return(0);
如果想操控後備緩衝資訊
// 初始化ddsd
DDRAW_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR| DDLOCK_WAIT, NULL);//鎖定後備緩衝
//這裡可以對它進行讀寫操作
lpddsback->Unlock(NULL);//解鎖
離屏表面有兩類
A) 後備緩衝 (Back Buffer) 當你建立主表面進也建立它們。目的是用DirectDraw的方式來實現對雙緩衝功能的模擬。
讀寫會非常快。 可以和主表面進行頁面切換。
建立一個關聯有後備緩衝的主表面, 必須建立DirectDraw所謂的複雜表面(ComplexSurface) 建立步驟如下:
1先將 DDSD_BACKBUFFERCOUNT加到dwFlags標誌欄位,向DirectDraw表明DDSURFACESC2
結構的dwBackBufferCount欄位有效,其中包括後備緩衝數目。
2再將控制標誌DDSCAPS_COMPLEX和DDSCAPS_FLIP加到DDSURFACEDESC2結構的特性描述
欄位ddsCaps.dwCaps上。
3最後像通常一樣建立表面,用IDIRECTDRAWSURFACE7 :: GetAttachedSurface()得到後備緩衝。
例如:
DDSURFACEDESC2 ddsd; //directdraw 表面結構說明
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;//主表面指標
LPDIRECTDRAWSURFACE7 lpddsback = NULL;//後備緩衝指標
DDRAW_INIT_STRUCT(ddsd);//初始化ddsd
//藍色的表示ddsd的dwBackBufferCount欄位有效
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;//表示一個後備緩衝頁面
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;//步驟第二條
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL);
return(0);//建立主表面
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
//主表面得到後備緩衝
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
return(0);
如果想操控後備緩衝資訊
// 初始化ddsd
DDRAW_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR| DDLOCK_WAIT, NULL);//鎖定後備緩衝
//這裡可以對它進行讀寫操作
lpddsback->Unlock(NULL);//解鎖
頁面切換:前面有了主表面和後備緩衝表面,進行頁面切換後就能實現動畫了。
1清除後備緩衝。(初始化)
2將情境渲染到後備緩衝。
3用後備緩衝切換掉主顯示表面。
4鎖定畫面播放速率。
5重複第一步。
用下面的函數來對關聯表面和主表面進行切換。
HRESULT Flip (LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags);其中lpDDSurfaceTargetOverride
是個進階參數,用來覆蓋切換鏈,實現切換到另一個表面,而不是切換到同主表面相關的後備緩衝,這裡值為NULL。
後面的dwFlags是控制標誌見p248
預設是1。這些要在DDCAPS結構中設定了DDCAPS2_FLIPINTERVAL後才起作用。
例如:
lpddsprimary->Fliy(NULL, DDFLIP_WAIT);
注意:切換之前主表面和後備緩衝表面都要解鎖。代碼例子p249