d3d8.dll:D3D8里面的2D图形编程



  利用D3D8IDirect3DSurface8 & IDirect3DTexture8 模拟出个简单表面类   利用这个类可以去完成图片局部BLT及图片和图片BLT也就是个进似于IDirectDrawSurface7东西当然了功能没有它而且是非常简单

功能:
   个表面分成:静态表面(IDirect3DTexture8)、动态表面(IDirect3DSurface8)静态表面不支持静态拷贝到静态或静态拷贝到动态最终只好使用动态拷贝到动态再由动态拷贝到静态
静态表面时只有个功能可以改变表面数据CreFileToTex;但是静态表面BLT速度相对动态而言就快了些(静态:纹理->后备缓存Cache动态:表面->纹理->后备缓存Cache);这里使用专门提供这个功能是平常要去改变表面数据机会不会太多最常见是:建立个表面把图像数据放到里面去再去建立另个再放图像数据……最后把这个表面里面图像块BLT到后备缓存Cache那块表面里面图像BLT到后备缓存Cache从这里可以看到个静态表面是很常用所以尽可以使用静态表面如果要使用动态也最好少更新数据另外Updata最好多次更新表面数据后(在帧时间内)再(不过这样话多次更新中间是不能使用ALPHA功能ALPHA功能只在Updata才能使用)表面数据建立可以直接去文件里面读取(静态时只有去文件里面读取当要完成从虽功能处来读取你可以让动态表面帮忙下)

  好了口水不多流了自己看源代码吧看源代码比看我口水好多了
   ……不好意思再流这里面ColorKey修改功能还没有完成还用品质模式修改(ColorKey可以在建立张图片时候指定使用动态表面和动态表面的间数据拷贝也可以设定ColorKey[BltSurToSur])哪位有空帮忙写下好了其实也不如何用到所以就懒了……
# !d(__AFX_GESURFACE_H__)
# __AFX_GESURFACE_H__

# _MSC_VER > 1000
#pragma _disibledevent=>GESUR_EXTERIOR =1, //使用外部定义效果
GESUR_INTERIOR =2, //使用内部定义效果
}GEBLTMODE;

typedef enum _GEMEMMODE
{
GEVIEMEM = 1, //显卡内存
GEMANMEM = 2, //管理内存
GESYSMEM = 3 //系统内存
}GEMEMMODE;

//-----------------
//功能:虚拟D3D表面缓冲使其成为2D里面表面
//备注:将表面建立在显卡缓存Cache是提供给显示缓冲使用
// (主表面/屏后缓冲)平常图形都应建立在系统缓存Cache
//-----------------
GESurface
{
private:
bool C_bAnimate;//表面是否建立
DWORD C_dwBasicColor;//表面基础颜色值
DWORD C_dwColorKey;//表面颜色键值
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, fiw, 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);

//宽高
GetWidth{ C_iWidth;};
GetHeight{ 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, fiw, 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;
};

#end


# <windows.h>
# <d3d8.h>
# <d3dx8.h>
# \"GESurface.h\"

//在2D里面不使用多层次纹理所以将其设定为第
const 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,
fiw, 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_MANAGEDD3DPOOL_SYSTEMMEM
//静态纹理使用D3DPOOL_MANAGED

true;
}

//动态表面锁定
//当矩形值为NULL时锁定整个动态表面
GESurface::
LockRect(
RECT *fprLockRect,
UCHAR **fppucData,
INT *fpiPitch)
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

HRESULT hr;

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

*fppucData = (UCHAR*)d3dLockRect.pBits;
*fpiPitch = d3dLockRect.Pitch;

true;
}

//动态表面解锁
GESurface::
UnlockRect
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

C_pd3dSurface->UnlockRect;

true;
}

//基础颜色(色含背景色和ALPHA)
//当张图片使用了这个基础色的后
//将会使这张图片和这个基础色进行混合混合比率使用设定ALPHA值
//(ALPHA值对目图片依然有效)
GESurface::
SetBasicColor(
DWORD fdwBasicColor)
{
C_dwBasicColor = fdwBasicColor;
}

GESurface::
GetBasicColor(
DWORD *fdwBasicColor)
{
*fdwBasicColor = C_dwBasicColor;
}

//颜色键
//该功能没有完成
GESurface::
SetColorKey(
DWORD fdwColorKey)
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

true;
}

GESurface::
GetColorKey(
DWORD *fdwColorKey)
{
*fdwColorKey = C_dwColorKey;
}

//表面数据品质模式(ARGB8888/RGB888/RGB565/ARGB4444...)
//该功能没有完成
GESurface::
SetQualityFormat(
D3DFORMAT fd3dFormat)
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

// memcpy(&C_d3dFormat,&fd3dFormat,(D3DFORMAT));

true;
}

GESurface::
GetQualityFormat(
D3DFORMAT *fd3dFormat)
{
memcpy(fd3dFormat,&C_d3dFormat,(D3DFORMAT));
}

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

//取静态表面指针
GESurface::
GetSurToTex(
LPDIRECT3DTEXTURE8 *fppd3dTex)
{
*fppd3dTex = C_pd3dTexture;
}

//取动态表面指针
GESurface::
GetSurToSur(
LPDIRECT3DSURFACE8 *fppd3dSur)
{
(C_SurfaceState != GESUR_DYNAMIC)
{
*fppd3dSur = NULL;
false;
}

*fppd3dSur = C_pd3dSurface;

true;
}

//BLT动态表面数据区去另个动态表面数据区
GESurface::
BltSurToSur(
RECT *fprSrcRect,
RECT *fprDestRect,
DWORD fdwColorKey,
GESurface *fpgeSur)
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

LPDIRECT3DSURFACE8 pd3dSrcSur;
HRESULT hr;

//取源动态表面指针
fpgeSur->GetSurToSur(&pd3dSrcSur);
//拷贝数据
hr=D3DXLoadSurfaceFromSurface(C_pd3dSurface,NULL,fprDestRect,
pd3dSrcSur,NULL,fprSrcRect,D3DX_FILTER_NONE,fdwColorKey);
(FAILED(hr)) false;

//这里使用源指针是直接从表面拷过来不能使用Release
pd3dSrcSur = NULL;

true;
}

//BLT静态表面上某区域到后备缓存Cache
GESurface::
Blt(
RECT *fprSrcRect,
RECT *fprDestRect,
GEBLTMODE fgeFlags)
{
D3DSURFACE_DESC d3dDesc;
D3DDISPLAYMODE d3dDisMod;
RECT rSrcRect,rDestRect;
float fDestWP = 1,fDestHP = 1;

C_pd3dTexture->GetLevelDesc(0,&d3dDesc);
C_pd3dDev->GetDisplayMode(&d3dDisMod);

//正规化RECT数据
(fprSrcRect)
{
rSrcRect = *fprSrcRect;
((long)d3dDesc.Width <= rSrcRect.left ||
(long)d3dDesc.Height <= rSrcRect.top ||
rSrcRect.right <= rSrcRect.left ||
rSrcRect.bottom <= rSrcRect.top)
false;

//调整非法数据
(0 > rSrcRect.left)
rSrcRect.left = 0;
(0 > rSrcRect.top)
rSrcRect.top = 0;
((long)d3dDesc.Width < rSrcRect.right)
{
fDestWP -= (rSrcRect.right - d3dDesc.Width)/
(rSrcRect.right - rSrcRect.left);
rSrcRect.right = d3dDesc.Width;
}
((long)d3dDesc.Height < rSrcRect.bottom)
{
fDestHP -= (rSrcRect.bottom - d3dDesc.Height)/
(rSrcRect.bottom - rSrcRect.top);
rSrcRect.bottom = d3dDesc.Height;
}
}

{
rSrcRect.left = 0;
rSrcRect.top = 0;
rSrcRect.right = d3dDesc.Width;
rSrcRect.bottom = d3dDesc.Height;
}

(fprDestRect)
{
rDestRect = *fprDestRect;
((long)d3dDisMod.Width <= rDestRect.left ||
(long)d3dDisMod.Height <= rDestRect.top ||
rDestRect.right <= rDestRect.left ||
rDestRect.bottom <= rDestRect.top)
false;
//调整非法数据
//显示系统自动调整
}

{
rDestRect.left = 0;
rDestRect.top = 0;
rDestRect.right = d3dDisMod.Width;
rDestRect.bottom = d3dDisMod.Height;
}

//设定BLT位置及数据源位置
//x/y代表BLT位置
//tu/tv代表数据源位置
float fVLeft,fVTop,fVRight,fVBottom,fTLeft,fTTop,fTRight,fTBottom;
fTLeft = (float)((float)rSrcRect.left / (float)d3dDesc.Width);
fTTop = (float)((float)rSrcRect.top / (float)d3dDesc.Height);
fTRight = (float)((float)rSrcRect.right / (float)d3dDesc.Width);
fTBottom = (float)((float)rSrcRect.bottom / (float)d3dDesc.Height);
fVLeft = (float)rDestRect.left;
fVTop = (float)rDestRect.top;
fVRight = (float)rDestRect.right * fDestWP;
fVBottom = (float)rDestRect.bottom * fDestHP;



float z = 0,rhw = 1.f;
//建立顶点
GEVertex geVertex={
{ fVLeft, fVTop, z, rhw, C_dwBasicColor, fTLeft, fTTop },
{ fVRight, fVTop, z, rhw, C_dwBasicColor, fTRight, fTTop },
{ fVRight, fVBottom, z, rhw, C_dwBasicColor, fTRight, fTBottom },
{ fVLeft, fVBottom, z, rhw, C_dwBasicColor, fTLeft, fTBottom }
};

//设定显示状态
C_pd3dDev->SetRenderState(D3DRS_LIGHTING, false);
(fgeFlags != GESUR_DISABLE)
{
//是否使用默认ALPHA状态(不使用话就使用外部定义ALPHA状态)
(fgeFlags GESUR_INTERIOR)
{
//关闭CULLMODE使图像两面都为可见
C_pd3dDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
//开启ALPHABlend混合方式使用按源ALPHA值线性上升或下降
C_pd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
C_pd3dDev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
C_pd3dDev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//Colorkey有效BasicColor有效
C_pd3dDev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
C_pd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
C_pd3dDev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
}
}

{
C_pd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
}

HRESULT hr;
//画图
hr=C_pd3dDev->SetRenderState(D3DRS_LIGHTING,false);
(FAILED(hr)) false;
hr=C_pd3dDev->SetTexture(0,C_pd3dTexture);
(FAILED(hr)) false;
hr=C_pd3dDev->SetVertexShader(GEFVF);
(FAILED(hr)) false;
hr=C_pd3dDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,geVertex,(GEVertex));
(FAILED(hr)) false;

true;
}

//动态表面清零
GESurface::
ClearSur
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

HRESULT hr;
D3DLOCKED_RECT d3dlockRect;
D3DSURFACE_DESC d3dsurDesc;
hr=C_pd3dSurface->GetDesc(&d3dsurDesc);
(FAILED(hr)) false;
hr=C_pd3dSurface->LockRect(&d3dlockRect,NULL,0);
(FAILED(hr)) false;
mem((BYTE*)d3dlockRect.pBits,0,(d3dsurDesc.Height * d3dlockRect.Pitch));
C_pd3dSurface->UnlockRect;

true;
}

//建立个动态表面并清零
GESurface::
CreSur(
LPDIRECT3DDEVICE8 fpd3dDev,
fiw, fih,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode)
{
(C_bAnimate)
Release;
C_SurfaceState = GESUR_DYNAMIC;

HRESULT hr;
D3DPOOL d3dPool;
(fgeMemoryMode GEMANMEM ||fgeMemoryMode GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
(fgeMemoryMode GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
false;

//建立动态表面
hr=fpd3dDev->CreateImageSurface(fiw,fih,fd3dFormat,&C_pd3dSurface);
(FAILED(hr)) false;

//建立用于显示静态表面
hr=D3DXCreateTexture(fpd3dDev,fiw,fih,1,0,fd3dFormat,d3dPool,&C_pd3dTexture);
(FAILED(hr)) false;

//对动态表面清零
ClearSur;

Init(fpd3dDev,fiw,fih,fd3dFormat,fgeMemoryMode);

true;
}

//化静态表面(从文件中读图形数据)
//支持ColorKey(只能在时候使用)
GESurface::
CreFileToTex(
LPDIRECT3DDEVICE8 fpd3dDev,
char fpcFileName,
RECT *fprDestRect,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode,
DWORD fdwColorKey)
{
(C_bAnimate)
Release;
C_SurfaceState = GESUR_STATIC;

D3DXIMAGE_INFO d3dImgInfo;
D3DPOOL d3dPool;
(fgeMemoryMode GEMANMEM ||fgeMemoryMode GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
(fgeMemoryMode GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
false;

HRESULT hr;
hr=D3DXCreateTextureFromFileEx(fpd3dDev,fpcFileName,
D3DX_DEFAULT,D3DX_DEFAULT,1,0,fd3dFormat,d3dPool,
D3DX_FILTER_NONE,D3DX_FILTER_NONE,fdwColorKey,
&d3dImgInfo,NULL,&C_pd3dTexture);
(FAILED(hr))
{
false;
}

Init(fpd3dDev,d3dImgInfo.Width,d3dImgInfo.Height,fd3dFormat,fgeMemoryMode);

true;
}

//化动态表面(从文件中读图形数据)
//支持ColorKey(只能在时候使用)
GESurface::
CreFileToSur(
LPDIRECT3DDEVICE8 fpd3dDev,
char fpcFileName,
RECT *fprDestRect,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode,
DWORD fdwColorKey)
{
D3DXIMAGE_INFO d3dImgInfo;
D3DPOOL d3dPool;
HRESULT hr;
(fgeMemoryMode GEMANMEM ||fgeMemoryMode GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
(fgeMemoryMode GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
false;

//快速取得图像宽高
LPDIRECT3DSURFACE8 pd3dSur;
hr=fpd3dDev->CreateImageSurface(1,1,fd3dFormat,&pd3dSur);
(FAILED(hr)) false;
hr=D3DXLoadSurfaceFromFile(pd3dSur, NULL, NULL, fpcFileName,
NULL, D3DX_FILTER_NONE, 0, &d3dImgInfo);
(FAILED(hr)) false;
pd3dSur->Release;
pd3dSur=NULL;

//建立动态表面
CreSur(fpd3dDev,d3dImgInfo.Width,d3dImgInfo.Height,fd3dFormat,fgeMemoryMode);

//读取图像数据去动态表面
hr=D3DXLoadSurfaceFromFile(C_pd3dSurface,NULL,NULL,fpcFileName,
NULL,D3DX_FILTER_NONE,fdwColorKey,&d3dImgInfo);
(FAILED(hr)) false;

C_pd3dDev = fpd3dDev;



true;
}

//拷贝动态表面数据去静态表面
//动态表面最终BLT还是要转成静态表面
//所以当使用动态表面时(图像数据->动态表面->静态表面)
//当使用静态表面时(图像数据->静态表面)
//比较可知动态表面速度比静态表面速度慢多了
//现在还没有找到好思路方法只好先用这个了
GESurface::
Updata
{
(C_SurfaceState != GESUR_DYNAMIC)
false;

HRESULT hr;

LPDIRECT3DSURFACE8 pd3dTexSur;
hr=C_pd3dTexture->GetSurfaceLevel(0,&pd3dTexSur);
(FAILED(hr)) false;
hr=C_pd3dDev->CopyRects(C_pd3dSurface,0,0,pd3dTexSur,0);
(FAILED(hr)) false;
pd3dTexSur->Release;

true;
}

//释放
GESurface::
Release
{
(C_pd3dSurface){C_pd3dSurface->Release; C_pd3dSurface=NULL;}
(C_pd3dTexture){C_pd3dTexture->Release; C_pd3dTexture=NULL;}
}



Tags:  java图形编程 图形编程 2d图形导出插件 d3d8.dll

延伸阅读

最新评论

发表评论