電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[雜亂教學] 混在一起使用 DirectX 的ID3DXSPRITE貼2D圖片 [2011/08/04]

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
babu61509
散播福音的祭司


註冊時間: 2007-08-26
文章: 142

681.01 果凍幣

發表發表於: 2011-8-4, PM 9:58 星期四    文章主題: [雜亂教學] 混在一起使用 DirectX 的ID3DXSPRITE貼2D圖片 [2011/08/04] 引言回覆

為了減少程式碼,就用了我包裝的一些東西。

1. WinForm 1.0b UA版
2. DxDevice 1.0 跟 DxSprite 1.4b

連結可以點,都有的下載,裡面有一些簡單說明,或是直接抓本附件的範例編來用也可以。
本範例使用 Unicode 字集,還有請先安裝 DirectX SDK。(俺用的是2010 June)

p.s 雖然本範例用了一些自己寫的東西,但是讀者也可以自己寫或是參考網路範例來替代。
================== 正文開始 ======================

1. 建立一個視窗
恩 ! 看讀者要用 win32、透過 CLR 存取 .NET、MFC、第三方函式庫( wxWidget、gtk 等)都可以,只要能建立視窗跟拿到 hwnd 就可以了,本範例是用個人包起來的 WinForm。

當然,第一步是寫一個程式進入點,Console出生的應該都很熟。
代碼:

int main(){
   return 0;
};

上面執行結果就是一個空白的主控台。(咻一下就沒了)

加 include 引用 winform,而為了能讓所有函式都能存取到建立出來的視窗,所以設成全域指標變數 form,main 裡面去 new 它、置中它,然後把它秀出來,最後結束前把 new 出來的 delete 掉。

p.s. 詳細的 winform 用法可以參考文章開始的連結或.H檔。
代碼:

#include "WinForm.h"      // Winform 必須引用

WinForm *form;            // 全域視窗指標

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                        // 置中視窗
   form->Show();                              // 進入主迴圈與視窗訊息迴圈
   delete form;                              // 有借有還
   return 0;
};

這段程式碼就會跑出一個置中且名為"我的視窗"的視窗。

win32 有個主迴圈跟視窗訊息函數,而主迴圈會將接受的訊息傳給視窗訊息函數處理,就這樣一直主迴圈接收並轉送訊息->視窗訊息函數處理->主迴圈傳主迴圈接收並轉送訊息->視窗訊息函數處理,無限輪迴直到程式結束、中斷或視窗被關閉才會跳出。

建立一個 mymainfun 函式來當做主迴圈並指定給它。
這樣只要視窗在,mymainfun 函式會一直被呼叫。
代碼:

#include "WinForm.h"      // Winform 必須引用

WinForm *form;            // 全域視窗指標

int mymainfun(){
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈
   form->Show();                                 // 進入主迴圈與視窗訊息迴圈
   delete form;                                 // 有借有還
   return 0;
};

跑起來跟上面一樣。

建立視窗 (完)

2. 建立DX裝置

要使用 DirectX 當然要建立 DX裝置 囉!

要使用 ID3DXSPRITE 需要先有 IDirect3D9、IDirect3DDevice9 (以使用DX9為例),這 2 個東西都包在 DxDevice 裡面了,當然讀者想要自己寫也可以的。

引用 DxDevice ,然後弄一個全域指標變數叫 mydxdev。main 裡面去 new 它,因為 IDirect3DDevice9 需要 hwnd 傳入,所以還要傳進去給它。

最後當然要delete囉~

p.s. 詳細的 DxDevice 用法可以參考文章開始的連結或.H檔。
代碼:

#include "WinForm.h"      // Winform 必須引用
#include "DxDevice.h"      // DxDevice 必須引用

WinForm *form;            // 全域視窗指標
DxDevice *mydxdev;         // 全域DX裝置指標

int mymainfun(){
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈

   mydxdev = new DxDevice();                        // new 一個DX裝置
   mydxdev->CreateDevice(form->GetHWND());               // 建立裝置!

   form->Show();                                 // 進入主迴圈與視窗訊息迴圈

   delete mydxdev;                                 // 我砍!
   delete form;                                 // 有借有還
   
   return 0;
};

執行結果還是一樣XD

3. 清畫面啦!

這裡開始就用 DX 的東西囉~

為了方便使用 IDIRECT3DDEVICE9,宣告一個叫 g_pD3DDev 的 LPDIRECT3DDEVICE9 全域變數(當然不用宣告也是可以)。把建立後的裝置放到這邊來。
代碼:

#include "WinForm.h"      // Winform 必須引用
#include "DxDevice.h"      // DxDevice 必須引用

WinForm *form;            // 全域視窗指標
DxDevice *mydxdev;         // 全域DX裝置指標
LPDIRECT3DDEVICE9 g_pD3DDev;      // DX裝置方便用

int mymainfun(){
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈

   mydxdev = new DxDevice();                        // new 一個DX裝置
   mydxdev->CreateDevice(form->GetHWND());               // 建立裝置!
   g_pD3DDev = mydxdev->m_pD3DDevice;                  // 擺進去

   form->Show();                                 // 進入主迴圈與視窗訊息迴圈

   delete mydxdev;                                 // 我砍!
   delete form;                                 // 有借有還
   
   return 0;
};


再來就開始清畫面囉!

呼叫 IDIRECT3DDEVICE9 的 clear 來清顯示區域,然後再呼叫 Present 叫它做!

p.s 詳細的IDirect3DDevice9介紹 (MSDN) http://msdn.microsoft.com/en-us/library/bb174336(v=VS.85).aspx
代碼:

#include "WinForm.h"      // Winform 必須引用
#include "DxDevice.h"      // DxDevice 必須引用

WinForm *form;            // 全域視窗指標
DxDevice *mydxdev;         // 全域DX裝置指標
LPDIRECT3DDEVICE9 g_pD3DDev;      // DX裝置方便用

int mymainfun(){
   g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(150,150,255), 1.0f, 0 );      // 指定清除!
   g_pD3DDev->Present( NULL, NULL, NULL, NULL );         // 給我做!
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈

   mydxdev = new DxDevice();                        // new 一個DX裝置
   mydxdev->CreateDevice(form->GetHWND());               // 建立裝置!
   g_pD3DDev = mydxdev->m_pD3DDevice;                  // 擺進去

   form->Show();                                 // 進入主迴圈與視窗訊息迴圈

   delete mydxdev;                                 // 我砍!
   delete form;                                 // 有借有還
   
   return 0;
};

就可以看到視窗內容變色囉!!

4. 我要貼圖片! PART I

再來要開始建立 ID3DXSPRITE 了 ! ID3DXSPRITE 可以用來顯示IDIRECT3DTEXTURE9的內容 (IDIRECT3DTEXTURE9 裡面放的就是圖片),為了簡化一些東西,就把 IDIRECT3DTEXTURE9 包成 Texture ,ID3DXSPRITE 包成 DxSprite。

所以就先 include DxSprite ,全域弄一個mySprite,為了方便使用的g_pSprite,以及拿來存圖片的 myTexture 容器。

main 裡面就先 new DxSprite,再把建立出來的 Sprite 指定到 g_pSprite。

再來就是重點了! 載入圖片 !

先 tmp 一個 Texture,然後讀入圖片(範例為載入一個名為 n1 的PNG檔)再丟到圖片容器裡面。

p.s. 詳細的 DxSprite 用法可以參考文章開始的連結或.H檔。
代碼:

#include "WinForm.h"      // Winform 必須引用
#include "DxDevice.h"      // DxDevice 必須引用
#include "DxSprite.h"      // DxSprite 必須引用

WinForm *form;            // 全域視窗指標
DxDevice *mydxdev;         // 全域DX裝置指標
LPDIRECT3DDEVICE9 g_pD3DDev;      // DX裝置方便用
DxSprite *mySprite;         // 全域Sprite指標
LPD3DXSPRITE g_pSprite;      // Sprite方便用
vector<Texture> myTexture;   // 圖片容器

int mymainfun(){
   g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(150,150,255), 1.0f, 0 );      // 指定清除!
   g_pD3DDev->Present( NULL, NULL, NULL, NULL );         // 給我做!
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈

   mydxdev = new DxDevice();                        // new 一個DX裝置
   mydxdev->CreateDevice(form->GetHWND());               // 建立裝置!
   g_pD3DDev = mydxdev->m_pD3DDevice;                  // 擺進去

    mySprite = new DxSprite(g_pD3DDev);                  // new DxSprite
    g_pSprite = mySprite->m_psprite;                  // 方便用!

    Texture tmp(g_pD3DDev);                           // 暫存用!
    tmp.LoadFromFile(L"t1.png");                     // 讀入圖片
    myTexture.push_back(tmp);                        // 丟到圖片容器裡面

   form->Show();                                 // 進入主迴圈與視窗訊息迴圈

   delete mySprite;                              // 阿答答答!
   delete mydxdev;                                 // 我砍!
   delete form;                                 // 有借有還
   
   return 0;
};

執行結果不變 !

5. 我要貼圖片! PART II

載完圖片之後 ! 就是來把它貼出來囉 !!

ID3DXSPRITE 的 Draw 需要包在 ID3DXSPRITE::Begin 跟 ID3DXSPRITE::End 之間,而 DX裝置 要進行的繪製動作也要包在 IDirect3DDevice9::BeginScene 跟 IDirect3DDevice9::EndScene 裡面。(詳細請參考MSDN)

通通加進去! 然後中間再加上繪製圖片容器裡面的圖片出來就可以了 !
p.s 原本 Draw 要傳入的參數通通都包到 Texture.Format 裡面了。
代碼:

#include "WinForm.h"      // Winform 必須引用
#include "DxDevice.h"      // DxDevice 必須引用
#include "DxSprite.h"      // DxSprite 必須引用

WinForm *form;            // 全域視窗指標
DxDevice *mydxdev;         // 全域DX裝置指標
LPDIRECT3DDEVICE9 g_pD3DDev;      // DX裝置方便用
DxSprite *mySprite;         // 全域Sprite指標
LPD3DXSPRITE g_pSprite;      // Sprite方便用
vector<Texture> myTexture;   // 圖片容器

int mymainfun(){
   g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(150,150,255), 1.0f, 0 );      // 指定清除!
   g_pD3DDev->BeginScene();                        // DX裝置場景開始
   g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);            // Sprite 開始,且開啟透明功能

   for (int i = 0; i < (int)myTexture.size();i++)         // 容器內所有圖片都
      mySprite->Draw(&myTexture[i]);                  // 給我畫出來!!

   g_pSprite->End();                              // Sprite 結束
   g_pD3DDev->EndScene();                           // DX狀置場景結束
   g_pD3DDev->Present( NULL, NULL, NULL, NULL );         // 給我做!
   return 0;
};

int main(){
   form = new WinForm(L"我的視窗",100,100,800,600);      // new 一個視窗
   form->resetLocation();                           // 置中視窗
   form->MyMainLoop = mymainfun;                     // 指定 mymainfun 為主訊息迴圈

   mydxdev = new DxDevice();                        // new 一個DX裝置
   mydxdev->CreateDevice(form->GetHWND());               // 建立裝置!
   g_pD3DDev = mydxdev->m_pD3DDevice;                  // 擺進去

    mySprite = new DxSprite(g_pD3DDev);                  // new DxSprite
    g_pSprite = mySprite->m_psprite;                  // 方便用!

    Texture tmp(g_pD3DDev);                           // 暫存用!
    tmp.LoadFromFile(L"t1.png");                     // 讀入圖片
    myTexture.push_back(tmp);                        // 丟到圖片容器裡面

   form->Show();                                 // 進入主迴圈與視窗訊息迴圈

   delete mySprite;                              // 阿答答答!
   delete mydxdev;                                 // 我砍!
   delete form;                                 // 有借有還
   
   return 0;
};


圖片就出現囉!!

雖然這樣的程式碼很沒有架構,但還是畫出圖片來囉 !!

(還在想要怎樣弄架構XD)

(完)

==============================================
小附錄:
代碼:

myTexture[0].Format[0].Rotate += 0.1f;

將這個程式行加在 g_pSprite->End(); 之前 就可以看到第一張圖片在旋轉囉~



DxEX.rar
 描述:

下載
 檔名:  DxEX.rar
 附件大小:  6.71 KB
 下載次數:  共 804 次


_________________
已經畢業了!!
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作