【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2781|回复: 0

详细讲解D3D8里面的2D图形编程

[复制链接]
发表于 2007-1-22 04:52:45 | 显示全部楼层 |阅读模式
利用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;
  }
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-2-6 04:01

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表