1.1 Surfaces之封裝CXSurface 1、Surfaces是什么: 通俗的講surfaces就是一個(gè)二維的矩形平面。在DX9中,與其對(duì)應(yīng)的com接口為IDirect3DSurface9,LPDIRECT3DSURFACE9。 2、Surfaces的作用: 作為一個(gè)矩形平面,surfaces用來(lái)在屏幕上顯示平面圖象,即從文件中讀取圖象數(shù)據(jù)呈現(xiàn)給用戶。 3、IDirect3DSurface9的使用一般過程: 聲明: LPDIRECT3DSURFACE9 創(chuàng)建: CreateOffscreenPlainSurface(…) 獲取圖象信息: D3DXGetImageInfoFromFile(…) 裝載到surfaces中: D3DXLoadSurfaceFromFile(…) 獲取back buffer地址: GetBackBuffer(…) 顯示: UpdateSurface(…) 釋放內(nèi)存 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的使用雖然不十分復(fù)雜,但有點(diǎn)不方便 ——?jiǎng)?chuàng)建和釋放總要成對(duì)出現(xiàn),使用過程中還穿插著LPDIRECT3DDEVICE9接口。這些若用一個(gè)類封裝起來(lái),使用就要方便的多。 4、如何封裝: 按照surfaces的功能,創(chuàng)建它就用來(lái)顯示圖象。因此要有讀取圖象的接口和顯示圖象的接口。又要與LPDIRECT3DDEVICE9設(shè)備接口關(guān)聯(lián),因此需要一個(gè)設(shè)置設(shè)備的接口。如下所示: 1、聲明及釋放 聲明: LPDIRECT3DSURFACE9 釋放內(nèi)存 Release() 2、關(guān)聯(lián)圖像:LoadFromFile 獲取圖象信息: D3DXGetImageInfoFromFile(…) 創(chuàng)建: CreateOffscreenPlainSurface(…) 裝載到surfaces中: D3DXLoadSurfaceFromFile(…) 3、顯示圖象 Render 獲取緩存地址: GetBackBuffer(…) 顯示: UpdateSurface(…) 4、關(guān)聯(lián)設(shè)備接口 SetDevice 所以CXSurface的定義如下: class CXSurface { protected: ??? LPDIRECT3DSURFACE9 m_Surface; ??? LPDIRECT3DSURFACE9 m_BackBuffer; //Back buffer ??? LPDIRECT3DDEVICE9 m_pDevice; //Direct3D的設(shè)備指針 public: ??? CXSurface(LPDIRECT3DDEVICE9 pDevice); ??? ~CXSurface(); ??? HRESULT LoadFromFile(LPCSTR Path); ??? void Render(void); }; 1.2 Textures & Sprite 之封裝CXTexture & CXSprite 1、何為Textures Textures是在屏幕上顯示的平面圖形,它能夠提供比 surface 更多的圖形處理效果——移動(dòng)、縮放、旋轉(zhuǎn)及作為紋理皮膚粘貼在3D模型上。在Direct3D中,其封裝的接口為IDirect3DTexture9。 2、何為Sprite IDirect3DTexture9能從文件中讀取紋理數(shù)據(jù),但由于Textures不能直接復(fù)制到 back buffer,因此在屏幕上繪制Textures之前,需要另一個(gè)接口——ID3DXSprite(精靈)。ID3DXSprite能夠把若干個(gè)Textures 復(fù)制給back buffer,因此需要ID3DXSprite的一個(gè)實(shí)例就可以繪制所有的紋理。 所以,IDirect3DTexture9用來(lái)存放程序所需的紋理,但它本身又不能繪制紋理,需要借助接口ID3DXSprite。 3、IDirect3DTexture9和ID3DXSprite的使用過程 定義:~ 創(chuàng)建:D3DXCreateTextureFromFile D3DXCreateSprite 創(chuàng)建變換矩陣: D3DXMatrixTransformation2D 變換: SetTransform 繪制圖象: Draw 釋放內(nèi)存: ~ 代碼如下: 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的接口,與紋理文件文件關(guān)聯(lián),對(duì)紋理進(jìn)行處理(縮放、旋轉(zhuǎn)……)。 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連接的函數(shù)。 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:讀取鼠標(biāo)的按鍵、位置信息,設(shè)置光標(biāo)屬性(如用圖片表示光標(biāo))。 3、使用過程 創(chuàng)建 IDirectInput8 對(duì)象 DirectInput8Create 創(chuàng)建 IDirectInput8 設(shè)備(鍵盤、鼠標(biāo)等) CreateDevice 設(shè)置設(shè)備屬性 SetCooperativeLevel SetDataFormat 獲取設(shè)備使用權(quán) Acquire 讀取設(shè)備傳入的數(shù)據(jù) GetDeviceState 釋放設(shè)備及 IDirectInput8 Release 設(shè)置鼠標(biāo)光標(biāo)過程: 創(chuàng)建光標(biāo)圖片資源: 參照surfaces 設(shè)置光標(biāo)為指定的圖片 SetCursorProperties 設(shè)置光標(biāo)的初始位置 SetCursorPosition 顯示光標(biāo) 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)) { ??? //創(chuàng)建鍵盤設(shè)備 ??? 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); ??? //根據(jù)KeyState返回的數(shù)據(jù)就可以判斷按下何鍵 } //==================================================== //創(chuàng)建鼠標(biāo) g_lpDI->CreateDevice(GUID_SysMouse, &g_Mouse, NULL); g_Mouse->SetDataFormat(&c_dfDIMouse); g_Mouse->SetCooperativeLevel(g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND); //------------------------------------------------------------------------ //設(shè)置鼠標(biāo)光標(biāo) //獲取光標(biāo)圖片 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); //設(shè)置成指定的光標(biāo) g_pd3dDevice->SetCursorProperties(0,0, g_MouseCursor); //初試位置 g_pd3dDevice->SetCursorPosition(0,0,D3DCURSOR_IMMEDIATE_UPDATE); //顯示光標(biāo) g_pd3dDevice->ShowCursor(true); //------------------------------------------------------------------------- //獲取鼠標(biāo)信息 if(SUCCEEDED(g_Mouse->Acquire())) { ??? DIMOUSESTATE State; ??? g_Mouse->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&State); ??? //信息保存在 State中。 } //============================================== //釋放設(shè)備 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的封裝 為了能制作出動(dòng)畫效果的光標(biāo),因此需要一個(gè)surfaces列表,因此從CXSurface繼承一個(gè)CXMouseSurface類,使之能夠操作多個(gè)圖片。 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; //指向光標(biāo)列表 ??? CXMouseSurface* m_CurrentCursorSurface; //當(dāng)前光標(biāo) ??? 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); }; |