雙緩衝和後備緩衝

2021-06-19 09:23:27 字數 3904 閱讀 2615

前面的例子都是,直接在主表面上繪東西。對於動畫,直接在主表面上繪,會產生很嚴重的閃爍。解決的辦法是採用雙緩衝或後備緩衝。

雙緩衝:在離屏緩衝中繪製影象,然後將其拷貝到顯示表面。

見下面**,先把資料放到double_buffer,最後再拷貝到主表面上。

下面sleep(300);睡眠了0.3秒這麼長的時間是為了更為明顯的看到畫面的變化。

int

game_main()

memset((

void

*)double_buffer,

0, screen_width

*screen_height);

for(

intindex =0

; index

<

5000

; index++)

ddraw_init_struct(ddsd);

lpddsprimary

->

lock(null,

&ddsd, ddlock_su***cememoryptr

|ddlock_wait,null);

//主表面視訊記憶體指標

uchar

*primary_buffer

=(uchar

*)ddsd.lpsu***ce;

//再把緩衝區的內容拷貝到主表面。

if(ddsd.lpitch

==screen_width)

else

}if(failed(lpddsprimary

->

unlock(null)))

return0;

sleep(

300);

return1;

}

後備緩衝也是離屏表面的一種。它是一些用在動畫鏈中的表面,它們具有和主表面相同的尺寸和色深。當建立主表面的時候也建立它們。它和主表面進行頁面切換,這比雙緩衝方案下所需做的記憶體拷貝要快得多。

建立乙個關聯後備緩衝的主表面步驟(複雜表面):

把ddsd_backbuffercount加到dwflagss標誌字段,把ddsu***cedesc2結構的dwbackbuffercount欄位設為有效。(它可以設定後備緩衝的數目)

把ddscaps_complex | ddscaps_flip加到ddsu***cedesc2 結構的ddscaps.dwcaps

建立主表面。

得到後備緩衝有再個方法。設定ddscaps2 ddscaps.dwcaps= ddscaps_backbuffer; 或 ddsd.ddscaps.dwcaps =ddscaps_backbuffer;

然後呼叫 getattachedsu***ce(&ddsd.ddscaps, &lpddsback)得到後備緩衝。

見下面**:

ddraw_init_struct(ddsd);

ddsd.dwflags

=ddsd_caps

|ddsd_backbuffercount;

//增加ddsd_backbuffercount 表明dwbackbuffercount有效

ddsd.ddscaps.dwcaps

=ddscaps_primarysu***ce

|ddscaps_complex

|ddscaps_flip;

//多了 ddscaps_complex | ddscaps_flip

ddsd.dwbackbuffercount =1

;

//後備緩衝的個數

if(failed(lpdd

->

createsu***ce(

&ddsd,

&lpddsprimary, null)))

return0;

//請求乙個後備緩衝

ddsd.ddscaps.dwcaps

=ddscaps_backbuffer;

//得到後備緩衝

if(failed(lpddsprimary

->

getattachedsu***ce(

&ddsd.ddscaps,

&lpddsback)))

return0;

以上**。lpddsprimary指向主表面,lpddsback指向後備緩衝表面。

對後備緩衝表面進行訪問,也需要對其加鎖和解鎖。在對後備緩衝表面繪圖後,把怎麼把所之圖顯示到主表面呢。這就要用到頁面切換了(而且這個切換是由硬體完成的)。

用主表面呼叫下面的函式來切換。(注意在頁面切換前主表面或後備緩衝表面都必須被解鎖)

hresult flip(lpdirectdrawsu***ce7 lpddsu***cetargetoverride ,dword dwflags); 

第乙個引數:用來覆蓋切換鏈,實現切換到另外乙個表面,不是切換到同主表面想關聯的後備緩衝,一般為null。

第二個引數:控制標誌。如下:

ddflip_interval2

2次垂直逆程後切換

ddflip_interval3

3次垂直逆程後切換

ddflip_interval4

4次垂直逆程後切換

這些標誌 在ddcaps結構中設定了ddcaps2_flipinterval

才能起作用。預設值是1.

這些標誌 表明在兩個切換頁之間等待多少垂直逆程,只有在指定的垂直逆程數目達到了,ddraw才為切換的每一頁返回derr_wasstilldrawing

ddflip_novsync

ddflip_wait

:強迫硬體不 在出現問題時立即返回,而是等待直到頁面切換能夠進行為止。一般就用這個標誌比較多。

int

maingame()

ddraw_init_struct(ddsd);

lpddsback

->

lock(null,

&ddsd, ddlock_su***cememoryptr

|ddlock_wait,null);

uchar

*back_buffer

=(uchar

*)ddsd.lpsu***ce;

//清除後備緩衝資料

if(ddsd.lpitch

==screen_width)

memset(back_buffer,

0, screen_width

*screen_height);

else

}for(

intindex=0

; index

<

5000

; index++)

if(failed(lpddsback

->

unlock(null)))

return0;

//切換主表面,是主表面呼叫flip,另外要注意的是呼叫flip之前,要先解鎖。

while

(failed(lpddsprimary

->

flip(null, ddflip_wait)));

sleep(

500);

return1}

2011.06.07 fangyukuan

單緩衝和雙緩衝的時間計算

在塊裝置輸入資料的過程中,首先把磁碟資料送到緩衝區,花費的時間為ts,簡記為ts過程 然後把作業系統緩衝區的資料送到使用者區,花費的時間為tm,簡記為tm過程 最後使用者程序對這批資料進行計算,花費的時間為tc。簡記為tc過程 當tc過程與tm過程操作同一塊緩衝區時,這兩個操作不能並行 讀寫鎖 ts...

python全緩衝 行緩衝和無緩衝

這裡的緩衝是指的是使用者空間的i o緩衝區,不是核心緩衝。上述都是i o緩衝區,其作用是減少read和write的次數,即減少了系統呼叫,從而減少了系統開銷,提高了i o速度。核心緩衝區。從理論上講,核心可以在任何時候寫磁碟,但並不是所有的write操作都會導致核心的寫動作。核心會把要寫的資料暫時存...

雙緩衝和單快取的區別

雙緩衝和單快取的區別 編碼時遇到glutinitdisplaymode unsigned int mode 函式,主要作用是設定初始顯示模式,其中有兩個可用形參不甚理解。分別為glut single,glut double。其中glut single指定單快取視窗,glut double指定雙快取視...