⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gesurface.cpp

📁 游戏是我在3月5日离职后花3周时间做的。主要目的是验证自己在游戏上相关的编程能力
💻 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 + -