DircetDraw c/c++ 使用指導(三) (轉)
DircetDraw c/c++ 使用指導
310cdt 譯
這幾篇指導的例程我放到網上了
tutorial3:從一個離屏表面(off-screen surface)的塊移動(blt)
在ddex2中,把一張點陣圖放到了後臺快取中,然後在快取與主平面間翻啊翻...其實這不是顯示點陣圖的一般行為.在這一篇中(例子是ddex3)將要透過包含兩個離屏表面來擴充套件ddex2的能力.兩個點陣圖-一個是第偶數次顯示的,一個是奇數次顯示-存放在這兩個離屏表面.例子中,用IDirectDrawSurface7::BltFast方法把離屏表面的內容複製到後臺快取中去,然後翻轉,然後再把下一個離屏表面拷到快取...
(譯者注:這一篇只是演示離屏表面和blit的方法,實際上,離屏表面使用的時候大部分是用來存放精靈,實現動畫的.存放的都是小的圖片,是一個特殊的平面)
ddex3新的以下面3個步驟演示:
step1:建立離屏表面
step2:載入點陣圖到離屏表面
step3:塊移動(blit)離屏表面到後臺緩衝
step1:建立離屏表面
下面的程式碼是加入到doInit函式中建立兩個離屏表面.
// Create an off-screen bitmap.
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = 480;
ddsd.dwWidth = 640;
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSOne, NULL);
if(ddrval != DD_OK)
{
return initFail(hwnd);
}
// Create another off-screen bitmap.
ddrval = lpDD->CreateSurface(&ddsd, &lpDDSTwo, NULL);
if(ddrval != DD_OK)
{
return initFail(hwnd);
}
dwFlags成員定義了將使用DDSCAPS結構,並且將要設定離屏表面的高和寬.這個表面因為標示了DDSCAPS_OFFSCREEN在DDSCAPS結構中,所以將會是一個完全的離屏的快取.高和寬分別設為480 和640.隨後,表面經過IDirectDraw7::CreateSurface方法建立.
因為兩個離屏表面大小相同,就又不同的指標了IDirectDraw7::CreateSurface又一次,建立了另一個.
你可以透過在DDSCAPS結構中定義DDSCAPS_SYSTEMMEMORY或DDSCAPS_VOMEMORY來決定將離屏表面放在還是視訊記憶體中.放在視訊記憶體中,你可以加快離屏表面到後臺快取的移動速度.將用到點陣圖的動畫的時候,這將十分的重要.但是,如果你使用DDSCAPS_VIDEOMEMORY並且沒有足夠的視訊記憶體區存放那個點陣圖了,當你試圖建立這個表面的時候,將會返回一個DDERR_OUTOFVIDEOMEMORY錯誤.
step2:載入點陣圖到離屏表面
當兩個離屏表面建立好後,DDEx3用InitSurface函式將frntback.bmp的點陣圖裝入到表面中.InitSurface函式用到了ddutil.cpp檔案中的DDCopyBitmap函式去裝載點陣圖.如下:
// Load the bitmap re.
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap,
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSOne, hbm, 0, 0, 640, 480);
DDCopyBitmap(lpDDSTwo, hbm, 0, 480, 640, 480);
Delete(hbm);
return TRUE;
如果你用看圖或畫圖的看過frntback.bmp檔案了,你就知道,這個檔案包括兩個圖,一個在另一個的上面.DDCopyBitmap函式把這個點陣圖從分界的地方分成兩部分.一個裝入到第一個離屏表面(lpDDSOne),另一個在第二個離屏表面(lpDDSTwo).
step3:塊移動(blit)離屏表面到後臺緩衝
WM_TIMER訊息觸發的程式碼包括寫入表面和翻轉表面.在DDEx3中,他包含了下面的程式碼去選擇適當的離屏表面,然後把他塊移動(blit)到後臺快取.
rcRect.left = 0;
rcRect.top = 0;
rcRect.right = 640;
rcRect.bottom = 480;
if(phase)
{
pdds = lpDDSTwo;
phase = 0;
}
else
{
pdds = lpDDSOne;
phase = 1;
}
while(1)
{
ddrval = lpDDSBack->BltFast(0, 0, pdds, &rcRect, FALSE);
if(ddrval == DD_OK)
{
break;
}
}
phase變數決定了到底是哪一個離屏表面將被移動到後臺快取.IDirectDrawSurface7::BltFast方法的呼叫是用來把所選的離屏表面塊移動到後臺快取的.在(0,0)處開始,左上角.reRect引數指向一個RECT結構,他定義了移動出來的離屏表面的左上和右下角.最後的一個引數設為FALSE(0),標示沒有使用特殊的傳輸標示符.
根據你的程式的需要,你可以使用IDirectDrawSurface7::Blt 或者IDirectDrawSurface7::BltFast 方法實現塊移動.如果你的離屏表面在視訊記憶體中,你最好使用IDirectDrawSurface7::BltFast 方法.這樣做,如果你使用的是塊移動支援的系統,你不會獲得更快的速度,但是,如果使用的硬體模仿的塊移動,你將會少用10%的時間.所以,你應該使用IDirectDrawSurface7::BltFast方法去做所有的在視訊記憶體中的塊移動.如果你從系統記憶體中移動,或者需要特別的硬體標誌,那就只好使用IDirectDrawSurface7::Blt了.
當完成的從離屏表面到後臺快取的塊移動,後臺快取就和主平面之間像前面幾篇一樣不停的翻啊翻....
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-996520/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DircetDraw c/c++ 使用指導(四) (轉)C++
- DircetDraw c/c++ 使用指導(一) (轉)C++
- DircetDraw c/c++ 使用指導(二) (轉)C++
- C++指標轉換C++指標
- [C++]指標和引用(三)C++指標
- 高中生學習c/c++指導C++
- Prefer C++(三) (轉)C++
- C++物件導向三大特性C++物件
- C/C++指向指標的指標C++指標
- C++ this 指標C++指標
- C++ 指標C++指標
- C++中智慧指標的簡單使用C++指標
- 【C++】智慧指標的正確使用方式C++指標
- C++指標理解C++指標
- 【c++】智慧指標C++指標
- C++智慧指標C++指標
- C/C++指標總結C++指標
- C++中智慧指標的設計和使用C++指標
- C++模板的定製三:部分定製C++類 (轉)C++
- C++入門解惑(2)——初探指標(上) (轉)C++指標
- C++入門解惑(3)——初探指標(下) (轉)C++指標
- c++指標使用經驗總結之懸垂指標C++指標
- C++中的this指標C++指標
- c++ 函式指標C++函式指標
- C++引用和指標C++指標
- C++指標問題C++指標
- 「C++」理解智慧指標C++指標
- c++指標小計C++指標
- C++(函式指標)C++函式指標
- 劍指offer——把字串轉換成整數C++字串C++
- C++深度探索系列:智慧指標(Smart Pointer) [二] (轉)C++指標
- Git使用指導Git
- 關於C/C++ void指標,使用void指標拷貝int 陣列C++指標陣列
- 詳解c++指標的指標和指標的引用C++指標
- C++程式設計雜談:物件導向 (轉)C++程式設計物件
- 再學C/C++ 之 指標常量 和 常量指標C++指標
- 匯出 C/C++ API 給 Lua 使用[轉]C++API
- 函式指標使用c++類成員函式函式指標C++