前面的例子都是,直接在主表面上繪東西。對於動畫,直接在主表面上繪,會產生很嚴重的閃爍。解決的辦法是採用雙緩衝或後備緩衝。
雙緩衝:在離屏緩衝中繪製影象,然後將其拷貝到顯示表面。
見下面**,先把資料放到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);以上**。lpddsprimary指向主表面,lpddsback指向後備緩衝表面。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;
對後備緩衝表面進行訪問,也需要對其加鎖和解鎖。在對後備緩衝表面繪圖後,把怎麼把所之圖顯示到主表面呢。這就要用到頁面切換了(而且這個切換是由硬體完成的)。
用主表面呼叫下面的函式來切換。(注意在頁面切換前主表面或後備緩衝表面都必須被解鎖)
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
:強迫硬體不 在出現問題時立即返回,而是等待直到頁面切換能夠進行為止。一般就用這個標誌比較多。
intmaingame()
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指定雙快取視...