📄 gesurface.cpp
字号:
#include <windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#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;
}
//表面数据品质模式(ARGB8888/RGB888/RGB565/ARGB4444...)
//该功能没有完成
GESurface::
SetQualityFormat(
D3DFORMAT fd3dFormat)
{
if(C_SurfaceState != GESUR_DYNAMIC)
return false;
// memcpy(&C_d3dFormat,&fd3dFormat,sizeof(D3DFORMAT));
return true;
}
GESurface::
GetQualityFormat(
D3DFORMAT *fd3dFormat)
{
memcpy(fd3dFormat,&C_d3dFormat,sizeof(D3DFORMAT));
}
//-------------------------
//取静态表面指针
GESurface::
GetSurToTex(
LPDIRECT3DTEXTURE8 *fppd3dTex)
{
*fppd3dTex = C_pd3dTexture;
}
//取动态表面指针
GESurface::
GetSurToSur(
LPDIRECT3DSURFACE8 *fppd3dSur)
{
if(C_SurfaceState != GESUR_DYNAMIC)
{
*fppd3dSur = NULL;
return false;
}
*fppd3dSur = C_pd3dSurface;
return true;
}
//BLT动态表面数据区去另一个动态表面数据区
GESurface::
BltSurToSur(
RECT *fprSrcRect,
RECT *fprDestRect,
DWORD fdwColorKey,
GESurface *fpgeSur)
{
if(C_SurfaceState != GESUR_DYNAMIC)
return false;
LPDIRECT3DSURFACE8 pd3dSrcSur;
HRESULT hr;
//取源动态表面指针
fpgeSur->GetSurToSur(&pd3dSrcSur);
//拷贝数据
hr=D3DXLoadSurfaceFromSurface(C_pd3dSurface,NULL,fprDestRect,
pd3dSrcSur,NULL,fprSrcRect,D3DX_FILTER_NONE,fdwColorKey);
if(FAILED(hr))return false;
//因为这里使用的源指针是直接从表面拷过来的,不能使用Release()
pd3dSrcSur = NULL;
return true;
}
//BLT静态表面上某一区域到后备缓存
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数据
if(fprSrcRect)
{
rSrcRect = *fprSrcRect;
if((long)d3dDesc.Width <= rSrcRect.left ||
(long)d3dDesc.Height <= rSrcRect.top ||
rSrcRect.right <= rSrcRect.left ||
rSrcRect.bottom <= rSrcRect.top)
return false;
//调整非法数据
if(0 > rSrcRect.left)
rSrcRect.left = 0;
if(0 > rSrcRect.top)
rSrcRect.top = 0;
if((long)d3dDesc.Width < rSrcRect.right)
{
fDestWP -= (rSrcRect.right - d3dDesc.Width)/
(rSrcRect.right - rSrcRect.left);
rSrcRect.right = d3dDesc.Width;
}
if((long)d3dDesc.Height < rSrcRect.bottom)
{
fDestHP -= (rSrcRect.bottom - d3dDesc.Height)/
(rSrcRect.bottom - rSrcRect.top);
rSrcRect.bottom = d3dDesc.Height;
}
}
else
{
rSrcRect.left = 0;
rSrcRect.top = 0;
rSrcRect.right = d3dDesc.Width;
rSrcRect.bottom = d3dDesc.Height;
}
if(fprDestRect)
{
rDestRect = *fprDestRect;
if((long)d3dDisMod.Width <= rDestRect.left ||
(long)d3dDisMod.Height <= rDestRect.top ||
rDestRect.right <= rDestRect.left ||
rDestRect.bottom <= rDestRect.top)
return false;
//调整非法数据
//显示系统自动调整
}
else
{
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);
if(fgeFlags != GESUR_DISABLE)
{
//是否使用默认ALPHA状态(不使用的话就使用外部定义的ALPHA状态)
if(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);
}
}
else
{
C_pd3dDev->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
}
HRESULT hr;
//画图
hr=C_pd3dDev->SetRenderState(D3DRS_LIGHTING,false);
if(FAILED(hr))return false;
hr=C_pd3dDev->SetTexture(0,C_pd3dTexture);
if(FAILED(hr))return false;
hr=C_pd3dDev->SetVertexShader(GEFVF);
if(FAILED(hr))return false;
hr=C_pd3dDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,geVertex,sizeof(GEVertex));
if(FAILED(hr))return false;
return true;
}
//动态表面清零
GESurface::
ClearSur()
{
if(C_SurfaceState != GESUR_DYNAMIC)
return false;
HRESULT hr;
D3DLOCKED_RECT d3dlockRect;
D3DSURFACE_DESC d3dsurDesc;
hr=C_pd3dSurface->GetDesc(&d3dsurDesc);
if(FAILED(hr))return false;
hr=C_pd3dSurface->LockRect(&d3dlockRect,NULL,0);
if(FAILED(hr))return false;
memset((BYTE*)d3dlockRect.pBits,0,(d3dsurDesc.Height * d3dlockRect.Pitch));
C_pd3dSurface->UnlockRect();
return true;
}
//建立一个动态表面并清零
GESurface::
CreSur(
LPDIRECT3DDEVICE8 fpd3dDev,
int fiw,int fih,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode)
{
if(C_bAnimate)
Release();
C_SurfaceState = GESUR_DYNAMIC;
HRESULT hr;
D3DPOOL d3dPool;
if(fgeMemoryMode == GEMANMEM ||fgeMemoryMode == GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
else if(fgeMemoryMode == GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
else return false;
//建立动态表面
hr=fpd3dDev->CreateImageSurface(fiw,fih,fd3dFormat,&C_pd3dSurface);
if(FAILED(hr))return false;
//建立用于显示的静态表面
hr=D3DXCreateTexture(fpd3dDev,fiw,fih,1,0,fd3dFormat,d3dPool,&C_pd3dTexture);
if(FAILED(hr))return false;
//对动态表面清零
ClearSur();
Init(fpd3dDev,fiw,fih,fd3dFormat,fgeMemoryMode);
return true;
}
//初始化静态表面(从文件中读图形数据)
//支持ColorKey(只能在初始化的时候使用)
GESurface::
CreFileToTex(
LPDIRECT3DDEVICE8 fpd3dDev,
char fpcFileName[],
RECT *fprDestRect,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode,
DWORD fdwColorKey)
{
if(C_bAnimate)
Release();
C_SurfaceState = GESUR_STATIC;
D3DXIMAGE_INFO d3dImgInfo;
D3DPOOL d3dPool;
if(fgeMemoryMode == GEMANMEM ||fgeMemoryMode == GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
else if(fgeMemoryMode == GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
else return 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);
if(FAILED(hr))
{
return false;
}
Init(fpd3dDev,d3dImgInfo.Width,d3dImgInfo.Height,fd3dFormat,fgeMemoryMode);
return true;
}
//初始化动态表面(从文件中读图形数据)
//支持ColorKey(只能在初始化的时候使用)
GESurface::
CreFileToSur(
LPDIRECT3DDEVICE8 fpd3dDev,
char fpcFileName[],
RECT *fprDestRect,
D3DFORMAT fd3dFormat,
GEMEMMODE fgeMemoryMode,
DWORD fdwColorKey)
{
D3DXIMAGE_INFO d3dImgInfo;
D3DPOOL d3dPool;
HRESULT hr;
if(fgeMemoryMode == GEMANMEM ||fgeMemoryMode == GESYSMEM)
d3dPool = D3DPOOL_MANAGED;
else if(fgeMemoryMode == GEVIEMEM)
d3dPool = D3DPOOL_DEFAULT;
else return false;
//快速取得图像宽高
LPDIRECT3DSURFACE8 pd3dSur;
hr=fpd3dDev->CreateImageSurface(1,1,fd3dFormat,&pd3dSur);
if(FAILED(hr))return false;
hr=D3DXLoadSurfaceFromFile(pd3dSur, NULL, NULL, fpcFileName,
NULL, D3DX_FILTER_NONE, 0, &d3dImgInfo);
if(FAILED(hr))return 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);
if(FAILED(hr))return false;
C_pd3dDev = fpd3dDev;
return true;
}
//拷贝动态表面数据去静态表面
//动态表面最终BLT还是要转成静态表面,
//所以当使用动态表面时(图像数据->动态表面->静态表面)
//当使用静态表面时(图像数据->静态表面)
//比较可知动态表面速度比静态表面速度慢多了
//现在还没有找到好的方法,只好先用这个了
GESurface::
Updata()
{
if(C_SurfaceState != GESUR_DYNAMIC)
return false;
HRESULT hr;
LPDIRECT3DSURFACE8 pd3dTexSur;
hr=C_pd3dTexture->GetSurfaceLevel(0,&pd3dTexSur);
if(FAILED(hr))return false;
hr=C_pd3dDev->CopyRects(C_pd3dSurface,0,0,pd3dTexSur,0);
if(FAILED(hr))return false;
pd3dTexSur->Release();
return true;
}
//释放
GESurface::
Release()
{
if(C_pd3dSurface){C_pd3dSurface->Release(); C_pd3dSurface=NULL;}
if(C_pd3dTexture){C_pd3dTexture->Release(); C_pd3dTexture=NULL;}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -