| 
 http://bbs.xboxchina.com/read.php?tid=520 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);  };
[此贴子已经被作者于2006-1-26 9:59:21编辑过]  |