d3d中的Surface(2d)繪製

來源:互聯網
上載者:User

原文出處:

http://coffeejp.com/bbs/viewthread.php?tid=168641

感謝作者:ccsakura

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();
};

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.