詳細講解D3D8裡面的2D圖形程式設計(轉)

post0發表於2007-08-12
詳細講解D3D8裡面的2D圖形程式設計(轉)[@more@]

  利用D3D8的IDirect3DSurface8 & IDirect3DTexture8 模擬出一個簡單的表面類。

  

  利用這個類可以去完成圖片的區域性BLT及圖片與圖片的BLT,也就是一個進似於IDirectDrawSurface7的東西,當然了,功能沒有它的強的,而且是非常的簡單。

  

  功能:

  一個表面分成:靜態表面(IDirect3DTexture8)、動態表面(IDirect3DSurface8),因為靜態表面不支援靜態複製到靜態或靜態複製到動態,最終只好使用動態複製到動態再由動態複製到靜態。

  靜態表面時只有一個功能可以改變表面資料CreFileToTex();但是靜態表面BLT的速度相對動態而言就快了一些(靜態:紋理->後備快取,動態:表面->紋理->後備快取);這裡使用專門提供這個功能是因為平常要去改變表面資料的機會不會太多,最常見的是:建立一個表面,把影像資料放到裡面去,再去建立另一個再放影像資料……,最後把這個表面裡面的影像的某一塊BLT到後備快取,那塊表面裡面的影像BLT到後備快取,從這裡可以看到,一個靜態的表面是很常用的,所以儘可以的使用靜態表面,如果要使用動態也最好少更新資料,另外Updata最好多次更新表面資料後(在一幀時間內)再呼叫(不過這樣的話多次更新的中間是不能使用ALPHA功能的,ALPHA功能只在Updata才能使用)。表面資料建立可以直接去檔案裡面讀取(靜態時,只有去檔案裡面讀取,當要完成從雖的功能處來讀取,你可以讓動態表面幫忙一下)。

  

  好了,口水不多流了,自己看原始碼吧,看原始碼比看我的口水好多了。

  ……不好意思,再流一下,這裡面的ColorKey修改功能還沒有完成還用品質模式修改(ColorKey可以在建立一張圖片的時候指定的,使用動態表面與動態表面之間的資料複製也可以設定ColorKey[BltSurToSur()]),哪位有空幫忙寫一下好了,其實也不怎麼用到的,所以就懶了……

  #if !defined(__AFX_GESURFACE_H__)

  #define __AFX_GESURFACE_H__

  

  #if _MSC_VER > 1000

  #pragma once

  #endif

  

  #include

  #include

  #pragma comment (lib, "d3d8.lib")

  #include

  #pragma comment (lib, "d3dx8.lib")

  #pragma comment (lib, "dxguid.lib")

  

  typedef enum _GEBLTMODE

  {

  GESUR_DISABLE =0, //關閉所有效果

  GESUR_EXTERIOR =1, //使用外部定義的效果

  GESUR_INTERIOR =2, //使用內部定義的效果

  }GEBLTMODE;

  

  typedef enum _GEMEMMODE

  {

  GEVIEMEM = 1, //顯示卡記憶體

  GEMANMEM = 2, //管理記憶體

  GESYSMEM = 3 //系統記憶體

  }GEMEMMODE;

  

  //-----------------

  //功能:虛擬D3D表面緩衝使其成為2D裡面的表面

  //備註:將表面建立在顯示卡快取是提供給顯示緩衝使用的

  //   (主表面/屏後緩衝),平常的圖形都應建立在系統快取

  //-----------------

  class GESurface

  {

  private:

  bool C_bAnimate;//表面是否建立

  DWORD C_dwBasicColor;//表面基礎顏色值

  DWORD C_dwColorKey;//表面顏色鍵值

  int C_iWidth,C_iHeight;//表面寬高

  D3DFORMAT C_d3dFormat;//表面資料模式

  GEMEMMODE C_geMemoryMode;//表面儲存器模式

  LPDIRECT3DDEVICE8 C_pd3dDev;//D3D裝置指標

  LPDIRECT3DTEXTURE8 C_pd3dTexture;//D3D紋理指標

  LPDIRECT3DSURFACE8 C_pd3dSurface;//D3D表面指標

  

  struct GEVertex

  {

  float x,y,z,rhw;

  DWORD color;

  float u, v;

  };

  enum {GEFVF = D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE};

  typedef enum _GESURSTATE

  {

  GESUR_STATIC = 0,

  GESUR_DYNAMIC = 1

  }GESURSTATE;

  GESURSTATE C_SurfaceState;//表面狀態(動態或靜態)

  

  //初始化

  Init(LPDIRECT3DDEVICE8 fpd3dDev,int fiw,int fih,D3DFORMAT fd3dFormat,GEMEMMODE fgeMemoryMode);

  

  public:

  GESurface();

  ~GESurface();

  

  //資料操作

  LockRect(RECT *fprLockRect,UCHAR **fppucData, INT *fpiPitch);//矩形鎖定

  UnlockRect();//矩形解鎖

  

  //ALPHA

  SetBasicColor(DWORD fdwBasicColor);

  GetBasicColor(DWORD *fdwBasicColor);

  

  //顏色鍵

  SetColorKey(DWORD fdwColorKey);

  GetColorKey(DWORD *fdwColorKey);

  

  //寬高

  int GetWidth(){return C_iWidth;};

  int GetHeight(){return C_iHeight;};

  

  //表面資料品質模式(ARGB8888/RGB888/RGB565/ARGB4444...)

  SetQualityFormat(D3DFORMAT fd3dFormat);

  GetQualityFormat(D3DFORMAT *fd3dFormat);

  

  //表面指標

  GetSurToTex(LPDIRECT3DTEXTURE8 *fppd3dTex);//取靜態表面指標

  GetSurToSur(LPDIRECT3DSURFACE8 *fppd3dSur);//取動態表面指標

  

  //建立表面

  CreFileToTex(LPDIRECT3DDEVICE8 fpd3dDev,char fpcFileName[],RECT *fprDestRect,D3DFORMAT fd3dFormat,GEMEMMODE fgeMemoryMode,DWORD fdwColorKey);

  CreFileToSur(LPDIRECT3DDEVICE8 fpd3dDev,char fpcFileName[],RECT *fprDestRect,D3DFORMAT fd3dFormat,GEMEMMODE fgeMemoryMode,DWORD fdwColorKey);

  CreSur(LPDIRECT3DDEVICE8 fpd3dDev,int fiw,int fih,D3DFORMAT fd3dFormat,GEMEMMODE fgeMemoryMode);

  

  //BLT

  Blt(RECT *fprSrcRect,RECT *fprDestRect,GEBLTMODE fgeFlags=GESUR_INTERIOR);

  BltSurToSur(RECT *fprSrcRect,RECT *fprDestRect,DWORD fdwColorKey,GESurface *fpgeSur);

  ClearSur();//用於將動態表面資料清零

  

  //動態指標要求:修改了表面資料之後應Updata,要不然,不能更新

  //可以多次更新資料,再於最後要顯示的時候Updata,這樣能提高利用率

  Updata();

  

  //釋放

  Release();

  };

  

  #endif

  

  #include

  #include

  #include

  #include "GESurface.h"

  

  //因為在2D裡面不使用多層次紋理,所以將其設定為第一層

  const int M_iTextLevel = 1;

  

  

  GESurface::

  GESurface():

  C_bAnimate(false),

  C_dwBasicColor(0x7fffffff),

  C_dwColorKey(0xff000000),

  C_iWidth(0),

  C_iHeight(0),

  C_pd3dDev(NULL),

  C_pd3dSurface(NULL),

  C_pd3dTexture(NULL)

  {

  }

  

  GESurface::

  ~GESurface()

  {

  Release();

  }

  

  //初始化

  GESurface::

  Init(

  LPDIRECT3DDEVICE8 fpd3dDev,

  int fiw,int fih,

  D3DFORMAT fd3dFormat,

  GEMEMMODE fgeMemoryMode)

  {

  //屬性初始化

  C_bAnimate = true;

  C_iWidth = fiw;

  C_iHeight = fih;

  C_d3dFormat = fd3dFormat;

  C_geMemoryMode = fgeMemoryMode;

  C_pd3dDev = fpd3dDev;

  

  //動態紋理建立在AGP(圖形加速介面)

  //如果是動態紋理,使用D3DPOOL_DEFAULT,並在系統記憶體中建立一個後備紋理用於恢復裝置

  //因為動態紋理不能使用D3DPOOL_MANAGED,D3DPOOL_SYSTEMMEM

  //靜態紋理,使用D3DPOOL_MANAGED

  

  return true;

  }

  

  //動態表面鎖定

  //當矩形值為NULL時,鎖定整個動態表面

  GESurface::

  LockRect(

  RECT *fprLockRect,

  UCHAR **fppucData,

  INT *fpiPitch)

  {

  if(C_SurfaceState != GESUR_DYNAMIC)

  return false;

  

  HRESULT hr;

  

  D3DLOCKED_RECT d3dLockRect;

  hr=C_pd3dSurface->LockRect(&d3dLockRect,fprLockRect,0);

  if(FAILED(hr))return false;

  

  *fppucData = (UCHAR*)d3dLockRect.pBits;

  *fpiPitch = d3dLockRect.Pitch;

  

  return true;

  }

  

  //動態表面解鎖

  GESurface::

  UnlockRect()

  {

  if(C_SurfaceState != GESUR_DYNAMIC)

  return false;

  

  C_pd3dSurface->UnlockRect();

  

  return true;

  }

  

  //基礎顏色(色含背景色和ALPHA)

  //當一張圖片使用了這個基礎色之後,

  //將會使這張圖片與這個基礎色進行混合,混合比率使用設定的ALPHA值

  //(ALPHA值對目的圖片依然有效)

  GESurface::

  SetBasicColor(

  DWORD fdwBasicColor)

  {

  C_dwBasicColor = fdwBasicColor;

  }

  

  GESurface::

  GetBasicColor(

  DWORD *fdwBasicColor)

  {

  *fdwBasicColor = C_dwBasicColor;

  }

  

  //顏色鍵

  //該功能沒有完成

  GESurface::

  SetColorKey(

  DWORD fdwColorKey)

  {

  if(C_SurfaceState != GESUR_DYNAMIC)

  return false;

  

  return true;

  }

  

  GESurface::

  GetColorKey(

  DWORD *fdwColorKey)

  {

  *fdwColorKey = C_dwColorKey;

  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-951831/,如需轉載,請註明出處,否則將追究法律責任。

相關文章