通向DirectDraw之捷徑

2021-06-15 21:01:03 字數 3612 閱讀 1431

1.directdraw的安裝 

在本文中,我假定你擁有微軟公司的 visual c++ , 和 directx 8.1 sdk。如果沒有,就快去準備乙份吧。 首先,啟動你的 visual c++, 建立乙個新的 win32 應用程式工程。 然後進入 你 directx sdk 資料夾中的 **********/common/include 目錄 , 拷貝 dxutil.h 和 ddutil.h 至你新建工程的目錄下。 然後將你 directx sdk資料夾中的 /**********/common/src目錄下的dxutil.cpp 和 ddutil.cpp 也拷貝至你新建工程的目錄下。把四個檔案加入你的工程, 然後連線上下列庫檔案: dxguid.lib ,ddraw.lib,winmm.lib。現在,你建立乙個新的 c++原始檔檔案, 而且也把它加入你的工程。 這些是整個教程中我們將會用到的工作檔案。

2.directdraw程式**

既然我們已經準備好了, 讓我們開始寫一些**什麼的實在的東西吧!

#define win32_lean_and_mean

#include

#include "dxutil.h"

#include "ddutil.h"

這是標準的**。#define win32_lean_and_mean,這句的目的是指示編譯器不要包含與mfc相關的操作。( 只是乙個好的練習——如果你不在使用 mfc) 然後我們包括 dxutil.h 和 ddutil.h,這是兩個很有用的標頭檔案。 他們能夠使你以一種比通常的directx程式設計更輕鬆的方式來工作。

//globals

bool g_bactive = false;

cdisplay *g_pdisplay = null;

csu***ce *g_ptext = null;

//function prototypes

bool initdd(hwnd);

void cleanup();

void gameloop();

**自身說的很清楚,不是嗎?我們的第乙個全域性變數,g_bactive,是乙個讓我們的應用程式知道是否應該執行遊戲的標誌。 如果我們沒有這個全域性變數, 我們的應用程式可能在它自己被登出之後還在嘗試著在我們已經建立的 directdraw 的表面上畫點兒什麼呢!雖然這通常是乙個在程式結束的時候出現的乙個不大的問題,但它會導致乙個非法操作的錯誤,我們並不想那樣,不是嗎? g_pdisplay 是我們的顯示物件。cdisplay 在 ddutil.h 中是最主要的類。它控制著我們前後的緩衝區,並提供一些針對該緩衝區的功能,如訪問及儲存緩衝區,將表面寫入緩衝區,建立乙個表面,等等。 g_ptext 是乙個文字表面。 我們將會在這個表面 (你或許已經有所理解 ) 之上寫文字, 然後將它傳送到我們的螢幕之上。 注意它們兩者都是指向物件的指標, 而且被初始化為null。

現在來看看函式的原型。 initdd() 只是用來初始化 directdraw 。 多虧了 directdraw 的通用檔案(common files),這還算是乙個簡單的程式。( 但是晚些時候我們才會接觸到它們) cleanup()呼叫了物件 g_pdisplay 的析構函式來釋放 ( release)我們所建立的directdraw物件及其表面。很明顯, gameloop() 則是將來用來放你的遊戲的地方。

lresult callback wndproc(hwnd hwnd, uint umsg,

wparam wparam, lparam lparam)

return 0;

}這裡是標準的 windows 程式訊息處理機制的**。 當產生 wm_create 訊息時,我們初始化 directdraw, 並將我們的全域性變數 g_bactive 設定為true,這樣就可以執行遊戲迴圈 gameloop() 了。當訊息 wm_close 被傳遞的時候,我們就把全域性變數 g_bactive 設定為 false ( 這樣我們的應用程式就不會在它自己被登出之後還在嘗試著向我們已經建立的 directdraw 的表面上寫資料了)。然後呼叫 cleanup() 函式,最終登出我們的視窗程式。處理 wm_move 和 wm_size 事件非常重要,因為若處理不當,directdraw 將不顧視窗本身是否已經被移動或重新設定其大小,仍然在螢幕上原來的位置上繼續作畫,從而造成錯誤。

bool initdd(hwnd hwnd)

return true;

}該死的 initdd() 函式... 不過別急,它只不過幾行而已! 這兒就是通常那些個庫檔案的用武之地。現在那些妨礙我們建立 directdraw 物件的冗長的玩意兒已被我們輕鬆搞定了,而你將會再次注意到它挺麻煩的,不是嗎?如果你真的不想弄明白那些惹人煩的玩意兒,那麼至少你得知道個梗概吧!如果你得回去改變協作等級什麼的,它也許幫得上忙。注意到這是乙個返回 bool 值的函式, 因此如果你不厭倦的話, 你應當做一下錯誤檢查。(基於你所可以理解的篇幅問題之原因,我決定在這篇文章中省略)

void cleanup()

真是夠簡單的! 這個函式呼叫了在 dxutil.h 中定義的巨集 safe_delete 來刪除我們的顯示物件,同時呼叫析構函式。

void mainloop()

這兒就是你將來放遊戲的地方。 為了要給你乙個表面物件(su***ce object)如何工作的例子,我們已經做了乙個簡單的文字表面而且寫了一些文字上去。注意我們在最後釋放(destroy)了全域性指標變數 g_ptext,否則每次迴圈它都將被重新建立一次,直到吃光最後一點兒記憶體。

int winapi winmain(hinstance hinstance, hinstance hprevinstance,

lpstr lpcmdline, int ishowcmd)

hwnd = createwindowex(null,"wc","directdraw common files in action",

ws_popupwindow,cw_usedefault,cw_usedefault,640,480,0,0,

hinstance,0);

if(hwnd == null)

showwindow(hwnd,sw_show);

updatewindow(hwnd);

while(lpmsg.message != wm_quit)

else if(g_bactive)

}return lpmsg.wparam;

}這就是我們的應用程式中最長的函式——winmain()。像往常一樣, 我們建立乙個視窗類,然後再建立乙個視窗,顯示及更新它, 並且進入訊息迴圈。看上去主迴圈不同於平常是因為我們不想要主遊戲程序被訊息的處理所干擾。我們通過觀察全域性指標變數 g_bactive 的狀態 來判斷該時刻呼叫遊戲迴圈是否安全以及在迴圈中向螢幕上傳送(blit)圖象,而最後全部結束的時候我們返回乙個長指標 lpmsg.wparam.( 至於為什麼我實在是不敢肯定,可其它每個 win32 應用程式都是這樣做的,對,就是這樣)

實在是太簡單了,嗯!?我們只用了 135 行程式編碼就已經將物件寫到了螢幕上。自由地去進一步**這些類的結構,做一些載入點陣圖至表面一類的實驗等等。這是使用 ddraw的乙個很棒的捷徑。它能在不犧牲控制 (你總是能在你需要的時候回去編輯那些類) 和效能的情況下而使事情變得容易些。有一件事得要注意的是在計算機上如果我使用了這個結構卻不繪製任何物件到螢幕上, 應用程式將會鎖定。( 對,這就是我為什麼把文字輸出也包括在這裡) 如果我說做遊戲很大程度上就是把物件傳送( blit )到螢幕上,大概不會引起什麼爭議(除非又有一些新的藝術風格誕生了)。 

DirectX 之 DirectDraw 視窗模式

在視窗模式下使用 directdraw 最大的痛苦是不能使用換頁操作 flip 但是有許多人還是喜歡在視窗模式下進行遊戲.首先,視窗模式下建立乙個 idirectdraw 介面物件和全屏模式下是一樣的,不同的是,在選擇協作模式和不能改變螢幕解析度.當然你堅決要改變,一定要有禮貌的改變.設定協作級別,...

C 捷徑之五

說明成 員函式重 載運算子 three d operator three d op2 類中定義,運算子過載 three d three d operator 前置 a three d operator int notused three d three d operator int notused ...

C 捷徑之七 結束

異常處理 try,throw,catch try catch int i throw 扔出的值,與 catch 得到的值型別匹配 被扔出值後,程式就跳到 catch 語句進行處理。處理完後繼續執行 catch 後面的語句。class myexception myexception char s 定義...