您现在的位置: 中国IT实验室 >> 游戏开发 >> 初学入门 >> 文章正文
详细讲解D3D8里面的2D图形编程
来源:ChinaITLab 收集整理 作者: 时间:2004-12-23


  利用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;
  }
收藏本文 责编:admin 


相关文章
游戏开发新手入门之Windows编程
自己研究的一个场景物体剔除方法
教你实现卡通渲染的另类勾边方法
Lua的function、closure和upvalue
Visual C#编写 3D游戏框架示例
推荐文章


 精彩友情推荐
·神州数码交换机
·神州数码交换机价格
·神州数码网络交换机
·netgear交换机
·网件交换机
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  针对于移动新出台的政策,需要尽快地把我们公司的游戏对应到不同的手机平台,这是针对市场策略的有利调整............
Quake-III代码里神奇的浮点开方函数
基于Dialogue的MFC程序调用DirectX
关于Kjava手机平台移植可行性报告
网络游戏的数据传输处理和防火墙穿
浅谈网游的数据传输处理和防火墙穿
向量几何在游戏编程中的使用(六)
向量几何在游戏编程中的使用(五)
向量几何在游戏编程中的使用(四)
向量几何在游戏编程中的使用(三)
向量几何在游戏编程中的使用(二)
  培训中心