1.1 Surfaces之封裝CXSurface
1、Surfaces是什么:
通俗的講surfaces就是一個二維的矩形平面。在DX9中,與其對應的com接口為IDirect3DSurface9,LPDIRECT3DSURFACE9。
2、Surfaces的作用:
作為一個矩形平面,surfaces用來在屏幕上顯示平面圖象,即從文件中讀取圖象數據呈現給用戶。
3、IDirect3DSurface9的使用一般過程:
聲明: LPDIRECT3DSURFACE9
創建: CreateOffscreenPlainSurface(…)
獲取圖象信息: D3DXGetImageInfoFromFile(…)
裝載到surfaces中: D3DXLoadSurfaceFromFile(…)
獲取back buffer地址: GetBackBuffer(…)
顯示: UpdateSurface(…)
釋放內存 Release()
代碼段如下:
LPDIRECT3DSURFACE9 g_Surface =NULL;
D3DXIMAGE_INFO Info;
D3DXGetImageInfoFromFile("D:\image.jpg", &Info);
g_pd3dDevice->CreateOffscreenPlainSurface(Info.Width, Info.Height,
Info.Format, &g_Surface, NULL);
D3DXLoadSurfaceFromFile(g_Surface, NULL, NULL, "D:\image.jpg", NULL,
D3DX_FILTER_NONE, 0xFF000000, NULL);
//--------------------------------------------------------------------------------------------------
LPDIRECT3DSURFACE9 BackBuffer = NULL;
g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, &BackBuffer);
g_pd3dDevice->UpdateSurface(g_Surface, NULL, BackBuffer, NULL);
if(BackBuffer != NULL)
??? BackBuffer->Release();
//---------------------------------------------------------------------------------------------------
if(g_Surface!= NULL)
??? g_Surface ->Release();
由上述過程可以看到,IDirect3DSurface9的使用雖然不十分復雜,但有點不方便
——創建和釋放總要成對出現,使用過程中還穿插著LPDIRECT3DDEVICE9接口。這些若用一個類封裝起來,使用就要方便的多。
4、如何封裝:
按照surfaces的功能,創建它就用來顯示圖象。因此要有讀取圖象的接口和顯示圖象的接口。又要與LPDIRECT3DDEVICE9設備接口關聯,因此需要一個設置設備的接口。如下所示:
1、聲明及釋放
聲明: LPDIRECT3DSURFACE9
釋放內存 Release()
2、關聯圖像:LoadFromFile
獲取圖象信息: D3DXGetImageInfoFromFile(…)
創建: CreateOffscreenPlainSurface(…)
裝載到surfaces中: D3DXLoadSurfaceFromFile(…)
3、顯示圖象 Render
獲取緩存地址: GetBackBuffer(…)
顯示: UpdateSurface(…)
4、關聯設備接口 SetDevice
所以CXSurface的定義如下:
class CXSurface
{
protected:
??? LPDIRECT3DSURFACE9 m_Surface;
???
LPDIRECT3DSURFACE9 m_BackBuffer; //Back buffer
???
LPDIRECT3DDEVICE9 m_pDevice; //Direct3D的設備指針
public:
???
CXSurface(LPDIRECT3DDEVICE9 pDevice);
???
~CXSurface();
???
HRESULT LoadFromFile(LPCSTR Path);
???
void Render(void);
};
1.2 Textures & Sprite 之封裝CXTexture & CXSprite
1、何為Textures
Textures是在屏幕上顯示的平面圖形,它能夠提供比 surface
更多的圖形處理效果——移動、縮放、旋轉及作為紋理皮膚粘貼在3D模型上。在Direct3D中,其封裝的接口為IDirect3DTexture9。
2、何為Sprite
IDirect3DTexture9能從文件中讀取紋理數據,但由于Textures不能直接復制到 back
buffer,因此在屏幕上繪制Textures之前,需要另一個接口——ID3DXSprite(精靈)。ID3DXSprite能夠把若干個Textures
復制給back buffer,因此需要ID3DXSprite的一個實例就可以繪制所有的紋理。
所以,IDirect3DTexture9用來存放程序所需的紋理,但它本身又不能繪制紋理,需要借助接口ID3DXSprite。
3、IDirect3DTexture9和ID3DXSprite的使用過程
定義:~
創建:D3DXCreateTextureFromFile
D3DXCreateSprite
創建變換矩陣: D3DXMatrixTransformation2D
變換: SetTransform
繪制圖象: Draw
釋放內存: ~
代碼如下:
D3DXCreateTextureFromFile(g_pd3dDevice, "c:\\image.bmp”, &g_Texture);
D3DXCreateSprite(g_pd3dDevice, &g_Sprite);
//--------------------------------------------------------------------------
D3DXVECTOR2 Translation;
Translation.x = 500;
Translation.y = 500;
D3DXVECTOR2 Scaling;
Scaling.x = 1.0;f
Scaling.y = 1.0f;
D3DXMATRIX Mat;
D3DXMatrixTransformation2D(&Mat, NULL, 0, &Scaling, NULL, 0,
&Translation);
g_Sprite->Begin(0);
g_Sprite->SetTransform(&
g_Sprite->Draw(g_Texture,
g_Sprite->End();
4、 如何封裝
從以上的基本過程可以看到,CXTexture需要完成的功能:提供與LPDIRECT3DDEVICE9的接口,與紋理文件文件關聯,對紋理進行處理(縮放、旋轉……)。
class CXTexture
{
protected:
??? LPDIRECT3DTEXTURE9 m_Texture;
???
LPDIRECT3DDEVICE9 m_pDevice;
???
D3DXVECTOR2 m_RotationCenter;
???
D3DXVECTOR2 m_Translation;
???
D3DXVECTOR2 m_Scaling;
???
FLOAT m_Rotation;
???
RECT m_SrcRect;
public:
???
CXTexture(LPDIRECT3DDEVICE9 pDevice);
???
~CXTexture();
???
LPDIRECT3DTEXTURE9 GetTexture() const {return m_Texture;}
???
void SetTexture(LPDIRECT3DTEXTURE9 Texture) const {m_Texture = Texture;}
???
LPDIRECT3DDEVICE9 GetDevice() const {return m_pDevice;}
???
void SetDevice(LPDIRECT3DDEVICE9 pDevice) const {m_pDevice = pDevice;}
???
D3DXVECTOR2 GetRotationCenter() const {return m_RotationCenter;}
???
void SetRotationCenter(D3DXVECTOR2 RotationCenter) {m_RotationCenter =
RotationCenter;}
???
D3DXVECTOR2 GetTranslation() const {return m_Translation;}
???
void SetTranslation (D3DXVECTOR2 Translation) const {m_Translation =
Translation;}
???
D3DXVECTOR2 GetScaling() const {return m_Scaling;}
???
void SetScaling(D3DXVECTOR2 Scaling) const {m_Scaling = Scaling;}
???
FLOAT GetRotation() const {return m_Rotation;}
???
void SetRotation (FLOAT Rotation) const {m_Rotation = Rotation;}
???
RECT GetRect() const {return m_SrcRect;}
???
void SetRect(RECT SrcRect) const {m_SrcRect = SrcRect;}
???
HRESULT LoadFromFile(char* Path);
};
CXSprite的主要功能就是在屏幕上顯示 CXTexture,因此需要有與 LPDIRECT3DDEVICE9 接口和
CXTexture連接的函數。
class CXSprite
{
protected:
???
LPD3DXSPRITE m_Sprite;
???
LPDIRECT3DDEVICE9 m_pDevice;
public:
???
CXSprite (LPDIRECT3DDEVICE9 pDevice);
???
~CXSprite ();
???
LPD3DXSPRITE GetSprite() const {return m_Sprite;}
???
void SetSprite(LPD3DXSPRITE Sprite) const {m_Sprite = Sprite;}
???
LPDIRECT3DDEVICE9 GetDevice() const {return m_pDevice;}
???
void SetDevice(LPDIRECT3DDEVICE9 pDevice) const {m_pDevice = pDevice;}
???
HRESULT DrawTexture(CXTexture* Texture);
};
1.3 Keyboard & Mouse之封裝CXKeyboard & CXMouse
1、何為Keyboard & Mouse
“地球人都知道”。DX9提供的接口 IDirectInputDevice8。
2、二者的功能
Keyboard:讀取鍵盤的按鍵信息
Mouse:讀取鼠標的按鍵、位置信息,設置光標屬性(如用圖片表示光標)。
3、使用過程
創建 IDirectInput8 對象 DirectInput8Create
創建 IDirectInput8 設備(鍵盤、鼠標等) CreateDevice
設置設備屬性 SetCooperativeLevel
SetDataFormat
獲取設備使用權 Acquire
讀取設備傳入的數據 GetDeviceState
釋放設備及 IDirectInput8 Release
設置鼠標光標過程:
創建光標圖片資源: 參照surfaces
設置光標為指定的圖片 SetCursorProperties
設置光標的初始位置 SetCursorPosition
顯示光標 ShowCursor
程序段如下:
LPDIRECTINPUT8 g_lpDI;
LPDIRECTINPUTDEVICE8 g_Keyboard;
LPDIRECTINPUTDEVICE8 g_Mouse
//========================================================
HRESULT Result = DirectInput8Create(g_hInst, DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&g_lpDI, NULL);
if(SUCCEEDED(Result))
{
??? //創建鍵盤設備
??? Result = g_lpDI->CreateDevice(GUID_SysKeyboard,
&g_lpDIDevice, NULL);
???
if(SUCCEEDED(Result))
???
{
???????
g_lpDIDevice->SetCooperativeLevel(g_hWnd, DISCL_FOREGROUND |
DISCL_NONEXCLUSIVE);
???????
g_lpDIDevice->SetDataFormat(&c_dfDIKeyboard);
???
}
}
//-------------------------------------------------------------------------------------------
//獲取按鍵信息
if(SUCCEEDED(g_Keyboard->Acquire())) //Acquire the device
{
???
char KeyState[256];
???
g_Keyboard->GetDeviceState(sizeof(KeyState),(LPVOID)&KeyState);
???
//根據KeyState返回的數據就可以判斷按下何鍵
}
//====================================================
//創建鼠標
g_lpDI->CreateDevice(GUID_SysMouse, &g_Mouse, NULL);
g_Mouse->SetDataFormat(&c_dfDIMouse);
g_Mouse->SetCooperativeLevel(g_hWnd, DISCL_EXCLUSIVE |
DISCL_FOREGROUND);
//------------------------------------------------------------------------
//設置鼠標光標
//獲取光標圖片
D3DXIMAGE_INFO ImageInfo;
D3DXGetImageInfoFromFile("C:\\Cursor.jpg”, &ImageInfo);
g_pd3dDevice->CreateOffscreenPlainSurface(ImageInfo.Width,
ImageInfo.Height, ImageInfo.Format, D3DPOOL_DEFAULT, &g_MouseCursor,
NULL);
D3DXLoadSurfaceFromFile(g_MouseCursor, NULL, NULL, ("C:\\Cursor.jpg”,
NULL, D3DX_FILTER_NONE, 0xFF000000, NULL);
//設置成指定的光標
g_pd3dDevice->SetCursorProperties(0,0, g_MouseCursor);
//初試位置
g_pd3dDevice->SetCursorPosition(0,0,D3DCURSOR_IMMEDIATE_UPDATE);
//顯示光標
g_pd3dDevice->ShowCursor(true);
//-------------------------------------------------------------------------
//獲取鼠標信息
if(SUCCEEDED(g_Mouse->Acquire()))
{
???
DIMOUSESTATE State;
???
g_Mouse->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&State);
???
//信息保存在 State中。
}
//==============================================
//釋放設備
if(g_lpDI != NULL)
???
g_lpDI->Release();
4、封裝
CXKeyboard的封裝
class CXKeyboard
{
private:
???
LPDIRECTINPUTDEVICE8 m_pDevice;
???
char m_KeyState[256];
public:
???
CXKeyboard (LPDIRECTINPUT8 pInput, HWND hWnd);
???
~ CXKeyboard();
???
bool IsKeyPressed(int Key);
???
HRESULT Update();
};
CXMouseSurface的封裝
為了能制作出動畫效果的光標,因此需要一個surfaces列表,因此從CXSurface繼承一個CXMouseSurface類,使之能夠操作多個圖片。
class CXMouseSurface : public CXSurface
{
private:
???
CXMouseSurface* m_pNext;
???
int MouseSurfaceType;
???
UINT HotSpotX;
???
UINT HotSpotY;
public:
???
CXMouseSurface* GetNext() {return m_pNext;}
???
void SetNext(CXMouseSurface* Surf) {m_pNext = Surf;}
???
int GetSurfaceType() {return MouseSurfaceType;}
???
void SetSurfaceType(int Type) {MouseSurfaceType = Type;}
???
UINT GetHotSpotX() {return HotSpotX;}
???
UINT GetHotSpotY() {return HotSpotY;}
???
void SetHotSpotX (UINT X) {HotSpotX = X;}
???
void SetHotSpotY (UINT Y) {HotSpotY = Y;}
???
CXMouseSurface(LPDIRECT3DDEVICE9 pDevice) : CXSurface(pDevice) {m_pNext
= NULL;}
???
CXMouseSurface() : CXSurface() {m_pNext = NULL;}
};
CXMouse的封裝
class CXMouse
{
private:
???
CXMouseSurface* m_Surface; //指向光標列表
???
CXMouseSurface* m_CurrentCursorSurface; //當前光標
???
LPDIRECTINPUTDEVICE8 m_pDevice;
???
LPDIRECT3DDEVICE9 m_p3DDevice;
???
DIMOUSESTATE m_State;
???
LONG m_iX;
???
LONG m_iY;
public:
???
CXMouse (LPDIRECT3DDEVICE9 pDevice, LPDIRECTINPUT8 pInput, HWND hWnd,
bool Exclusive);
???
~ CXMouse();
???
HRESULT Update();
???
LONG GetXPos();
???
LONG GetYPos();
???
bool IsButtonPressed(int Button);
???
HRESULT SetCursorImage();
???
HRESULT SetMouseCursor(char* FilePath, UINT HotSpotX, UINT HotSpotY, int
Type);
???
void AddCursorSurface(CXMouseSurface* Surface);
???
CXMouseSurface* GetFirstSurface() {return m_Surface;}
???
bool SetCursor(int Type);
???
CXMouseSurface* GetCurrentCursor() {return m_CurrentCursorSurface;}
???
void SetCurrentCursor(CXMouseSurface* Surface) {m_CurrentCursorSurface =
Surface;}
???
void SetCursorPosition(int X, int Y);
???
HRESULT SetCursorVisible(bool Show);
}; |
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
常用鏈接
留言簿(7)
隨筆檔案
文章分類
文章檔案
相冊
收藏夾
c++
搜索
最新評論

閱讀排行榜
評論排行榜
|
|