| DirectDraw中的基本圖形概念 如果你熟悉Windows下C及C++編程,那你就不難消化這部分內容。當你閱讀完這部分內容,你就有了一個堅實的DirectDraw基本圖形概念。共分以下幾部分: o 與裝置無關位元影像 (Device-Independent Bitmaps)DIB o 繪製平面 o 塊圖形移動 o 交換頁和屏後緩衝 o 矩形 1 裝置無關位元影像 Windows及DirectX都使用與裝置無關位元影像(DIB)作為其原始圖形格式。本質上,一個DIB檔案就是包含描述圖象的尺寸,使用多少色彩,描述這些色彩的參數,每一像素的描述資料。另外,一個DIB還包含一些基本參數如:壓縮資訊,有效色(如果沒有使用),及物理尺寸(如列印輸出到尾部)。DIB通常以BMP為副檔名,有時也使用DIB為副檔名。 因為DIB在Windows程式中應用廣泛,作業系統SDK已經包含許多函數操作DIB你可與DirectX一起使用。例如:以下常式Ddutil.cpp定義一個功能,用Win32及DirectX的函數讀取一個DIB到一個DirectX平面:
extern "C" IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy) { HBITMAP hbm; BITMAP bm; DDSURFACEDESC ddsd; IDirectDrawSurface *pdds; // // 這是Win32部分 // 試圖讀取一個Bitmap(位元影像) // 如果失敗,用檔案代替 // hbm = (HBITMAP)LoadImage( GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION); if (hbm == NULL) hbm = (HBITMAP)LoadImage( NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION); if (hbm == NULL) return NULL; // // 擷取位元影像的尺寸 // GetObject(hbm, sizeof(bm), &bm); // // 現在回到DirectX函數調用 // 為該位元影像建立一個DirectDrawSurface(平面) // ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = bm.bmWidth; ddsd.dwHeight = bm.bmHeight; if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK) return NULL; DDCopyBitmap(pdds, hbm, 0, 0, 0, 0); DeleteObject(hbm); return pdds; } 要獲得DIB的詳細內容參見WIN32SDK。 2 繪製平面 繪製平面接收資料將圖象顯示到螢幕(位元影像)。在大多數Windows程式中都要通過Win32函數來建立繪製平面例如GetDC,用來擷取裝置控制代碼(DC)。當你獲得裝置控制代碼後,你就可向螢幕輸出。不管怎樣,Win32的圖形函數是系統另一部分提供的,圖形裝置介面(GDI)。GDI是為Windows應用程式提供一個圖形輸出的抽象層。 對GDI來說最不利的就是對於多媒體來說它不是高度最佳化的。它是用來製作商用程式如WORD或試算表。GDI能作業系統記憶體,而不是顯存,也無法發揮硬體所提供的特性。簡言之,GDI對大多數商業軟體已足夠,但效能太差無法滿足多媒體及遊戲軟體。 另一方面,DirectDraw能讓你繪製平面來顯示顯存中的內容。這意味著當你使用DirectDraw,你能直接操作顯示卡的顯存,使圖形操作非常快。這些平面能反映對應的顯存塊,使定址更容易。 詳見平面。 3 塊圖形移動 Blit術語是塊移動(Bit Block Transfer),就是將一記憶體塊從原地整塊移動到其他地方。圖形程式用Blit將圖形從一記憶體塊移動到其他地方。Blit通常用於小物體精靈(Sprite)的移動,將在以後討論。詳見DirectDraw的Blit和平面(Surface)的Blit。 4 交換頁和屏後緩衝 頁交換是多媒體,動畫,及遊戲的關鍵。軟體上的頁交換就象畫卡通的一疊紙。藝術家只要在每張紙上稍加修改,當你快速翻動時,它就動起來了。 軟體頁交換過程與此很象,當你設定許多DirectDraw平面,就象藝術家的紙一張一張的層疊,第一個平面稱為主平面,而後面的平面稱為屏後緩衝。你的程式事先修改屏後緩衝的圖象,然後翻開主平面,屏後緩衝便顯示出來了。當系統顯示圖象,你的程式繼續寫屏後緩衝。就這樣不停繼續,使你能高速高效顯示動畫。DirectDraw能使你簡單實現使用頁交換,如簡單雙緩衝(一個主平面一個屏後緩衝)或更多更複雜的多屏後緩衝。詳見DirectDraw教程及平面交換。 5 矩形 通過DirectDraw及Windows程式,螢幕上的對象都歸於一個叫綁定矩形(Bounding Rectangles)的術語。在綁定矩形通常與螢幕平行,因此綁定矩形由兩點決定,左上方及右下角。多數程式在Blit時使用RECT結構來設定綁定矩形的資訊。RECT結構如下: typedef struct tagRECT { LONG left; // 這是左上方的X座標。 LONG top; // 這是左上方的Y座標。 LONG right; // 這是右下角的X座標。 LONG bottom; // 這是右下角的Y座標。 } RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
在上面的結構中,左面及上面的X,Y座標是綁定矩形的左上方。同樣,右面及下面的數是綁定矩形的右下角。下面的圖片直觀顯示了該結構: 出於效率,相容,易用性,所有的DirectDraw的Blit函數都以綁定矩形來工作。不管怎樣,你可使用自由Blit自行定義Blit。詳見自由Blit。 |