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(); 之前 就可以看到第一張圖片在旋轉囉~
描述: |
|
![](images/icon_clip.gif) 下載 |
檔名: |
DxEX.rar |
附件大小: |
6.71 KB |
下載次數: |
共 819 次 |
_________________ 已經畢業了!! |
|