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

📄 game_skybox.cpp

📁 自己写的一个D3D游戏Dome。实现了基本的游戏功能
💻 CPP
字号:
#include "..\Include\Game_SkyBox.h"

Game_SkyBox::Game_SkyBox(FLOAT width,char * strSkyName){
	m_cStrSkyName=strSkyName;
	m_vPos=D3DXVECTOR3(0,0,0);
	m_fWidth=width;
	m_pVB=NULL;
	m_uSpeed=0.02f;
	m_vSpeed=0.03f;
	m_nSegment=16;
	m_nSkyTile=10;
	m_nAngle=D3DX_PI/4;
}

Game_SkyBox::~Game_SkyBox(){
	SAFE_RELEASE(m_pVB);
	for(UINT i=0; i<7; i++){
		SAFE_RELEASE(m_pTexture[i]);
	}
	SAFE_RELEASE(m_pVBSky);
	SAFE_RELEASE(m_pIBSky);
}

WCHAR* Game_SkyBox::CreateWideStringFromCharString(const char *c_str){
	if (!c_str)
		return NULL;

	size_t len=strlen(c_str)+1;
	WCHAR *wideString=new WCHAR[len];

	if( MultiByteToWideChar( CP_ACP, 0, c_str, -1, wideString, (int)len ) == 0 )
		return NULL;

	return wideString;
}

void Game_SkyBox::InitObject(char * strName){
	CreateSkyBox();
	LoadSkyBox(strName);
	InitialiseVertexBuffer();
}

HRESULT Game_SkyBox::CreateSkyBox(char *strTextureA6[]){
	
	if(strTextureA6){
		for(int i=0;i<7;i++){
			D3DXCreateTextureFromFile(g_sGlobal.g_pDevice,CreateWideStringFromCharString(strTextureA6[i]),&m_pTexture[i]);
		}
	}
	else{		
		for(int i=0;i<7;i++)	
			m_pTexture[i]=NULL;

	}
	return S_OK;
}

HRESULT Game_SkyBox::LoadSkyBox(char * strName){
	//_ASSERT(!m_pTexture[0]);
	char strFileName[256];
	char *strKeyName[]={
		"East",
			"South",
			"West",
			"North",
			"Earth",
			"Sky",
			"Cloud"
	};
	if(!m_pTexture[0]){
		for(int i=0;i<7;i++){	
			if (FAILED(GetPrivateProfileStringA(m_cStrSkyName,strKeyName[i],"\0",strFileName,sizeof(strFileName),strName))){
				MessageBox(NULL,L"A",L"",0);
				return E_FAIL;
			}
			if (FAILED(D3DXCreateTextureFromFileA(g_sGlobal.g_pDevice,strFileName, &m_pTexture[i]))){ 
				return E_FAIL;
			}

		}
	}
	return S_OK;
}

HRESULT Game_SkyBox::InitialiseVertexBuffer(){
	VERTEX_BOX VB[]={	
		{	0.5f,-0.5f,  0.5f,-1.0f,0,0, 0.0f,1.0f,},		//East
		{	0.5f, 0.5f,  0.5f,-1.0f,0,0, 0.0f,0.0f,},		
		{	0.5f,-0.5f, -0.5f,-1.0f,0,0, 1.0f,1.0f,},		
		{	0.5f, 0.5f, -0.5f,-1.0f,0,0, 1.0f,0.0f,},

		{  0.5f,-0.5f,  -0.5f,0,0,1.0f, 0.0f,1.0f,},		//North 
		{  0.5f, 0.5f,  -0.5f,0,0,1.0f, 0.0f,0.0f,},
		{ -0.5f,-0.5f,  -0.5f,0,0,1.0f, 1.0f,1.0f,},		
		{ -0.5f, 0.5f,  -0.5f,0,0,1.0f, 1.0f,0.0f,},

		{ -0.5f,-0.5f,  -0.5f,1.0f,0,0, 0.0f,1.0f,},		//West
		{ -0.5f, 0.5f,  -0.5f,1.0f,0,0, 0.0f,0.0f,},
		{ -0.5f,-0.5f,   0.5f,1.0f,0,0, 1.0f,1.0f,},		
		{ -0.5f, 0.5f,   0.5f,1.0f,0,0, 1.0f,0.0f,},

		{-0.5f,-0.5f,    0.5f,0,0,-1.0f,0.0f,1.0f,},		//South
		{-0.5f, 0.5f,    0.5f,0,0,-1.0f,0.0f,0.0f,},
		{ 0.5f,-0.5f,    0.5f,0,0,-1.0f,1.0f,1.0f,},	
		{ 0.5f, 0.5f,    0.5f,0,0,-1.0f,1.0f,0.0f,},

		{ -0.5f,-0.5f,  0.5f,0,1.0f,0, 0.0f,0.0f,},		//Earth
		{  0.5f,-0.5f,  0.5f,0,1.0f,0, 0.0f,1.0f,},
		{ -0.5f,-0.5f, -0.5f,0,1.0f,0, 1.0f,0.0f,},	
		{  0.5f,-0.5f, -0.5f,0,1.0f,0, 1.0f,1.0f,},

		{ 0.5f,  0.5f,  0.5f,0,-1.0f,0, 0.0f,0.0f,},		//Sky
		{-0.5f,  0.5f,  0.5f,0,-1.0f,0, 1.0f,0.0f,},		
		{ 0.5f,  0.5f, -0.5f,0,-1.0f,0, 0.0f,1.0f,},	     
		{-0.5f,  0.5f, -0.5f,0,-1.0f,0, 1.0f,1.0f,},

	};

	//---------------------------------------------------------------------------------------------
	//创建SkyDome,方形圆顶
	//---------------------------------------------------------------------------------------------

	int nVertex=(m_nSegment+1)*(m_nSegment+1);
	int nIndex=m_nSegment*m_nSegment*6;

	float R=0.5f/sinf(m_nAngle/2);	            //半径满足弧形宽度为1,和天空盒相等大小

	VERTEX_BOX *VBSKY=new VERTEX_BOX[nVertex];	//顶点缓冲区
	DWORD	   *IBSKY=new DWORD[nIndex];		//索引数据

	float angleCol,angleRow;
	float anglePerSeg=m_nAngle/m_nSegment;  
	float angleStart=D3DX_PI/2-m_nAngle/2;
	float dYDown=R*sinf(angleStart);	        //云层向下的偏移量,边缘位于地平线上

	for (int i=0;i<nVertex;i++){	//顶点数据
		angleCol=angleStart+(i%(m_nSegment+1))*anglePerSeg;
		angleRow=angleStart+(i/(m_nSegment+1))*anglePerSeg;

		VBSKY[i].nx=-cosf(angleCol);				//法线指向圆心
		VBSKY[i].ny=-sinf(angleCol)*sinf(angleRow);
		VBSKY[i].nz=-sinf(angleCol)*cosf(angleRow);

		VBSKY[i].x=-R*VBSKY[i].nx;
		VBSKY[i].y=-R*VBSKY[i].ny-dYDown;			//偏移,边缘和地平线(y=0)平齐
		VBSKY[i].z=-R*VBSKY[i].nz;

		VBSKY[i].tu=m_nSkyTile*angleCol/m_nAngle;
		VBSKY[i].tv=m_nSkyTile*angleRow/m_nAngle;	
		if(VBSKY[i].y<0.0f)
			VBSKY[i].y=0.0f;
	}

	DWORD *lpIB=IBSKY;						//索引数据
	long   iMax=(m_nSegment+1)*m_nSegment;	//最后一个对应到矩形的左下角的顶点的索引号
	for (int i=0;i<iMax;i++ ){
		if(i%(m_nSegment+1)!=m_nSegment){	//每行的最后一个点不对应一个矩形
			*(lpIB++)=i;
			*(lpIB++)=i+m_nSegment+2;		//每行顶点数量m_nSegment+1;
			*(lpIB++)=i+m_nSegment+1;

			*(lpIB++)=i;
			*(lpIB++)=i+1;
			*(lpIB++)=i+m_nSegment+2;
		}
	}

	g_sGlobal.g_pDevice->CreateVertexBuffer(sizeof(VB),0,D3DFVF_SKYBOX, 
		D3DPOOL_DEFAULT, &m_pVB,NULL);
	void* pVertices;
	m_pVB->Lock(0,0,&pVertices,D3DLOCK_DISCARD);
	memcpy(pVertices,(void*)VB,sizeof(VB));
	m_pVB->Unlock();

	//云的顶点数据
	g_sGlobal.g_pDevice->CreateVertexBuffer(sizeof(VERTEX_BOX)*nVertex,0,	D3DFVF_SKYBOX, 
		D3DPOOL_DEFAULT, &m_pVBSky,NULL);
	m_pVBSky->Lock(0,0,&pVertices,D3DLOCK_DISCARD);
	memcpy(pVertices,(void*)VBSKY,sizeof(VERTEX_BOX)*nVertex);
	m_pVBSky->Unlock();

	//天空的索引数据
	g_sGlobal.g_pDevice->CreateIndexBuffer(sizeof(DWORD)*nIndex,0,D3DFMT_INDEX32, 
		D3DPOOL_DEFAULT, &m_pIBSky,NULL);
	m_pIBSky->Lock(0,0,&pVertices,D3DLOCK_DISCARD);
	memcpy(pVertices,(void*)IBSKY,sizeof(DWORD)*nIndex);
	m_pIBSky->Unlock();

	delete []IBSKY;
	delete []VBSKY; 

	return S_OK;
}

VOID Game_SkyBox::Render(){
	SetPosition(*(g_sGlobal.g_pGameApp->m_pGame_Camera->GetCameraPos()));
	VERTEX_BOX *pV;
	static float timeLastFrame=timeGetTime()/1000.0f;
	float timeNow=timeGetTime()/1000.0f;
	float timeFrameTime=timeNow-timeLastFrame;
	timeLastFrame=timeNow;

	m_pVBSky->Lock(0,0,(void**)&pV,0);

	//Refresh UV coordinate
	if(pV[m_nSegment/2].tu<2.0f){
		for(UINT i=0;i<(m_nSegment+1)*(m_nSegment+1) ;i++)	pV[i].tu+=m_uSpeed*timeFrameTime;
	}
	else{	
		float tu=pV[m_nSegment/2].tu;
		for(int i=(m_nSegment+1)*(m_nSegment+1)-1;i>=0;i--)	pV[i].tu-=tu;
	}

	if(pV[m_nSegment/2].tv<2.0f){	
		for(UINT i=0;i<(m_nSegment+1)*(m_nSegment+1) ;i++)	pV[i].tv+=m_vSpeed*timeFrameTime;
	}
	else{	
		float tv=pV[m_nSegment/2].tv;
		for(int i=(m_nSegment+1)*(m_nSegment+1)-1;i>=0;i--)	pV[i].tv-=tv;
	}
	m_pVBSky->Unlock();

	g_sGlobal.g_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);	//使用透明贴图
	g_sGlobal.g_pDevice->SetRenderState( D3DRS_ZWRITEENABLE,FALSE);						//关闭深度写入
	g_sGlobal.g_pDevice->SetRenderState(D3DRS_ZENABLE,TRUE);   
	g_sGlobal.g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	g_sGlobal.g_pDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);
	g_sGlobal.g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR);
	g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR);
	//g_sGlobal.g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
	FrameMove(); 
	g_sGlobal.g_pDevice->SetFVF(D3DFVF_SKYBOX);
	g_sGlobal.g_pDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX_BOX));		

	g_sGlobal.g_pDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
	for(int i=0;i<6;i++){
		g_sGlobal.g_pDevice->SetTexture(0,m_pTexture[i]);
		g_sGlobal.g_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,i*4,2);
	}

	g_sGlobal.g_pDevice->SetTexture(0,m_pTexture[6]);							//云的纹理
	g_sGlobal.g_pDevice->SetStreamSource(0,m_pVBSky,0,sizeof(VERTEX_BOX));	
	g_sGlobal.g_pDevice->SetIndices(m_pIBSky);
	g_sGlobal.g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,
		(m_nSegment+1)*(m_nSegment+1),0,m_nSegment*m_nSegment*2);

	g_sGlobal.g_pDevice->SetRenderState( D3DRS_CLIPPLANEENABLE ,TRUE);
	g_sGlobal.g_pDevice->SetRenderState( D3DRS_ZWRITEENABLE,TRUE);
}

VOID Game_SkyBox::FrameMove(){
	D3DXMATRIX	matWorld;

	matWorld._11=m_fWidth;	matWorld._12=0;			matWorld._13=0;			matWorld._14=0;
	matWorld._21=0;			matWorld._22=m_fWidth;	matWorld._23=0;			matWorld._24=0;
	matWorld._31=0;			matWorld._32=0;			matWorld._33=m_fWidth;	matWorld._34=0;
	matWorld._41=m_vPos.x;	matWorld._42=m_vPos.y;	matWorld._43=m_vPos.z;	matWorld._44=1;
	g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
}

VOID Game_SkyBox::SetPosition(D3DXVECTOR3 pos){
	m_vPos=pos;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -