全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2765
推到 Plurk!
推到 Facebook!

[分享] 兩個小時學會DirectDraw編程

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-07-23 09:13:34 IP:61.218.xxx.xxx 未訂閱

兩個小時學會DirectDraw編程

作者:標點工作室 http://makegame.myetang.com/jswd.htm 這並非嘩眾取寵, 通常學習一種電腦技術有兩種方法. 一種是自己摸索, 在錯誤的方向上一錯再錯, 屢戰屢敗, 不過最後得道成功. 另一種是有人 或好的材料指導, 因而事半功倍, 在正確的方向上走了速成的捷徑. 就象KFC 的雞一樣. 第一種學法能學出電腦天才, 因為所謂電腦高手, 其實就是排錯試錯的高手. 而第二種則出電腦專才. 這個兩小時(?)的學習, 不能使你深入的掌握DD, 不過可以給你編制DD的框架. 能給你 一個起始點, 這個教程就算成功了. DirectDraw編程需要一些背景知識: DirectDraw是為在 Windows95/NT 下實現高速圖形顯示所寫的程式庫. 高速圖形顯示的基本方法是用一種叫做 Page Flipping的技術. 關於什麼是 Page Flipping, 參見古技介紹.如果你 不急的話, 看到下面, 你也會看到. 在 Windows95/NT下做 Page Flipping 分為全屏的和窗口的兩種. 在全屏下Page Flipping 叫做Flip, 在窗口下叫做 Blit. 知道了這些背景知識, 我們可以開始寫程式了. 寫所有 DirectDraw的程式, 差不多都有以下幾個步驟, 1. 初始化, 這是每個程式都需要的勞什子. 2. 設置顯示模式. 3. 在內存裡建立PageFlipping所需要的兩個頁, 前頁和後頁. 4. 給顯示的區域加個畫框以免畫到外面來. 5. 在後頁畫圖, 然後"刷"的一下子換到前頁來. 步驟一: 初始化 DirectDraw 是一個面向對象的函數庫. "面向對象"的意思並不是指面對著你的女朋友, "對象" 在這裡, 你可以簡單地想象成是一個模板, 比方說,"政府", 一旦你說:"我成立了一個政府". 別人 就會立即把你套入"政府模板", 自然而然地認為你有印鈔票的功能. 在我們的程式裡, 你一旦聲明 一個變量(比如 myDD)是 DirectDraw對象 (DirectDraw對象的正式名為 LPDIRECTDRAW) , 這個myDD就有了 DirectDraw對象的所有的功能和特性. 定義 的語法是: LPDIRECTDRAW pMyDD; 除了 DD的對象外, 還有幾個重要的對象, "頁面", "裁剪板" 和 "調色板". "頁對象"用來定義"前頁"和"後頁". 定義如下: LPDIRECTDRAWSURFACE pMyDDSFront; LPDIRECTDRAWSURFACE pMyDDSBack; 一個"裁剪板對象", 在窗口模式下用來剪去畫出窗口邊界的部份. LPDIRECTDRAWCLIPPER pMyClipper; "調色板"設定屏幕的顏色表, 在讀取256色的 Bitmap時要用到. LPDIRECTDRAWPALETTE myDDPal; 最最重要的"對象"就是這些了. 當然 DirectX還有很多復雜晦澀的對象. 這是速成不起來的. 編制 Windows 程式有一大堆變量和對象是 Windows所要求的, 這也是我最煩 Microsoft的地方. Microsoft 似乎知道這點. 所以在 VC4.0後的版本有了 Wizard的功能幫你自動生成代碼. 盡量地去用它的 Wizard使我們的生活變得容易. 由於我們的程式可能會佔用一個窗口, 就給這個窗口一個 handle: HWND myWnd 初始化的工作還沒有完, 我們要把這些對象指向一個安全的地方 Null. pMyDD = NULL; pMyDDSFront = NULL; pMyDDSBack = NULL; pMyClipper = NULL; pMyDDPal=NULL; 最後, 在 Windows系統為我們的 myDD對象開闢相應的區域: DirectDrawCreate( NULL, //用當前的顯示驅動 &pMyDD, NULL)) Okay, 煩人的初始化總算完了. 步驟二: 設置屏幕的顯示方式. DirectDraw 有自己的設置屏幕的方式, 而且它的屏幕模式分為"全屏"( exclusive mode)和"窗口"( normal mode). 各有各的設置方法. 設置的主要區別在於 SetCooperativeLeve的參數. SetCooperativeLeve 在"窗口"模式下這樣設置: pMyDD->SetCooperativeLevel(AfxGetMainWnd()->GetSafeHwnd(),DDSCL_NORMAL); 而在"全屏"模式下這樣設置: pMyDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ); 如果它們的返回值為 DD_OK表示成功. 我們就可以把屏幕調節成我們想要的樣子, 例如 640x480x8. 也就是256色. 究竟有那些屏幕模式可用取決於你的顯示卡 pMyDD->SetDisplayMode( 640, 480, 8 ); 現在, 我們已經有了一個屏幕, 不過還不能在上面畫畫, 我們需要步驟三來 替我們建立一個可供畫畫塗塗用的畫板. 步驟三: 建立前後頁(兩塊畫板). 兩塊畫板的好處是可以一邊在一塊上面畫, 一邊給別人看已經畫好的另一塊. 等這塊畫好了, 兩塊板就對調一下, 讓別人看新畫好的這塊. 如果畫的足夠快, 換的足夠快. 看的人就會看到動畫了, 就象電影的效果一樣. 我們把這叫做 Page Flipping. 這裡先要介紹的是怎樣在系統中建立兩塊畫板( double buffering), 不過你也可以根據需要建立三塊,四塊畫板. DDSURFACEDESC ddsd; //這個結構描述"頁"的特徵. ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;//指定我們用的是前頁. ddsd.dwSize = sizeof(ddsd); //尺寸 // 做前頁: HRESULT result; result = pMyDD->CreateSurface(&ddsd, &pMyDDSFront, NULL); 當發生錯誤時, 要記得 Release對象. if (result!=DD_OK) { pMyDD->Release(); pMyDD = NULL; } ddsd.dwWidth = scr_width; //設定後頁的大小, ddsd.dwHeight = scr_height; //指定 我們要後頁 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; //做後頁 result = pMyDD->CreateSurface(&ddsd, &pMyDDSBack, NULL); } 步驟四: 給顯示區加一個畫框(裁剪板). 在窗口下. 為了防止 DirectDraw 畫到窗口外面去. 需要加一個畫框(裁剪板). 可以用 CreateClipper來 創建剪貼板. result = pMyDD->CreateClipper(0, &pMyClipper, NULL); 創建後,把它套到窗口上去, 所以要知道是那一個窗口( Handle). myWnd = AfxGetMainWnd()->GetSafeHwnd();// 從系統中拿到窗口的 Handle result = pMyClipper->SetHWnd(0, myWnd); // 把剪貼板加到窗口上去 result = pMyDDSFront->SetClipper(myClipper); 步驟五: 在後頁畫圖, 前後頁互換. 其實到這裡才是真正開始寫游戲的地方, 以前在 DOS下寫游戲, 就是直接從 這個步驟開始的. 以上這些工作, 都是 Microsoft強加給我們的. 寫游戲之前我們先來解決前後互換的問題. // 如果前頁的內存被 Windows"征用"了, 這裡把它要回來. 這個檢察常常會被忘記. if (pMyDDSFront->IsLost() == DDERR_SURFACELOST) pMyDDSFront->Restore(); DirectDraw 用來互換的語句有 Blt和 BltFast. BltFast據稱比 Blt快10%. result = pMyDDSFront->Blt(&rcTo, pMyDDSBack, &rcFrom, DDBLT_WAIT,NULL); result = pMyDDSFront->BltFast( 0, 0, pMyDDSBack, &rcFrom, DDBLTFAST_SRCCOLORKEY); 如果程式工作在"全屏"模式下. 前後頁互換容易得多, 只是一句: result = pMyDDSFront->Flip( NULL, 0 ); 現在就到了游戲的主要部份了, 我們稱之為"游戲邏輯"部, 在普通的游戲中, "游戲邏輯" 通常 要做很多事, 如畫游戲場景, 故事處理等等. 做完這些事後, 再和前頁做換屏. 不過怎樣做你的 游戲, 就沒有我什麼事了:-) 所有的步驟都講完了. 是不是覺得特容易? 半個小時就夠了? okay, 剩下的一個半小時讓 你把它們變成真正的代碼吧. 打開你的 Visual C , 我用的是 VC5.0, 不過你也可以用 VC4.0. 再低恐怕就不可以了. 別忘了檢查一下你的 DirectX SDK 有沒有安裝好. 打開VC, 選擇 MFC app EXE Wizard 來生成程式的框架, 我假設學DirectDraw的人應該 會用VC, 所以怎樣用 Wizard, 我就不再贅述. 進入 IDE環境後, 加入一個新 CPP file, 把上面用到的子函數的代碼打入. 當然你還需要一個 .H file 來放變量名, 對象名和子程式名. MFC(Microsoft Fried Checken)的 Wizard會幫你生成 ::InitInstance() 和 ::OnIdle(LONG lCount), 把你的 初始化部份, 建頁等步驟放在 InitInstance子類裡. 把"游戲邏輯"和換頁放在 OnIdle裡. 最後我想給大家一個完整的可運行的例子, 不過平均每分鐘六個漢字的速度打得我頭昏眼花. 四肢發 麻. 過兩天再說 時間就是金錢---[ 發問前請先找找舊文章]
系統時間:2024-04-26 12:58:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!