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

📄 game_skybox.cpp

📁 我做的毕业设计
💻 CPP
字号:
#include "Game_User.h"

CSkyBox::CSkyBox(LPDIRECT3DDEVICE9 pDevice,float width,char *strTextureA6[])
{	
	m_pDevice=pDevice;
	m_uSpeed=0.12f;
	m_vSpeed=0.17f;
	m_nSegment=16;
	m_nSkyTile=15;
	m_nAngle=D3DX_PI/4;
	m_vPos.x=100;
	m_vPos.y=100;
	m_vPos.z=100;
	m_fWidth=width;

	if(strTextureA6)
	{
		for(int i=0;i<7;i++)
		{
			D3DXCreateTextureFromFile(m_pDevice, strTextureA6[i], &m_pTexture[i]);
		}
	}
	else
	{		
		for(int i=0;i<7;i++)	m_pTexture[i]=NULL;
	
	}
	Initialize();

}			
CSkyBox::~CSkyBox()
{
	SAFE_RELEASE(m_pVBSky);
	SAFE_RELEASE(m_pIBSky);
	SAFE_RELEASE(m_pVB);

	for(int i=0;i<7;i++)
	{	if (m_pTexture[i])
		{
			/*delete m_pTexture[i];
			m_pTexture[i]=NULL;*/
			SAFE_RELEASE(m_pTexture[i]);
		}
	}	
	m_pDevice = NULL;
}
void CSkyBox::Render(float fFrameTime)
{
	VERTEX_BOX *pV;
	m_pVBSky->Lock(0,0,(void**)&pV,0);

	//Refresh UV coordinate
	if(pV[m_nSegment/2].tu<2.0f)
	{
		for(int i=0;i<(m_nSegment+1)*(m_nSegment+1) ;i++)	
			pV[i].tu+=m_uSpeed*fFrameTime;
	}
	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(int i=0;i<(m_nSegment+1)*(m_nSegment+1) ;i++)	
			pV[i].tv+=m_vSpeed*fFrameTime;
	}
	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();

	
	//m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);	//使用透明贴图
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE,FALSE);						//关闭深度写入
	
	m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);
	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	this->SetMatrix(); 
	m_pDevice->SetFVF(D3DFVF_SKYBOX);
	m_pDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX_BOX));		

	m_pDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE);
	for(int i=0;i<6;i++)
	{
			m_pDevice->SetTexture(0,m_pTexture[i]);
			m_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,i*4,2);
	}
	
	m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);
	m_pDevice->SetTexture(0,m_pTexture[6]);							//云的纹理
	m_pDevice->SetStreamSource(0,m_pVBSky,0,sizeof(VERTEX_BOX));	
	m_pDevice->SetIndices(m_pIBSky);

 	m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,
		(m_nSegment+1)*(m_nSegment+1),0,m_nSegment*m_nSegment*2);

	m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
	m_pDevice->SetRenderState( D3DRS_CLIPPLANEENABLE ,TRUE);
	m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE,TRUE);

}


// Function name   : CSkyBox::Initialize
// Description     : 
// Return type     : void 

void CSkyBox::Initialize()
	{	
		//天空盒
		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);	//289
		int nIndex=m_nSegment*m_nSegment*6;			//每个segment两个三角形,每个三角形3
													//顶点,所以乘6
	
		float R=0.5f/sinf(m_nAngle/2);	//半径满足弧形宽度为1,和天空盒相等大小
										//1.30656

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

		float angleCol,angleRow;
		float anglePerSeg=m_nAngle/m_nSegment;		//0.049087
		float angleStart=D3DX_PI/2-m_nAngle/2;		//1.178097
		float dYDown=R*sinf(angleStart);	//云层向下的偏移量,边缘位于地平线上
											//0.9238794
											//1.207103
		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;
/*
			云的索引方式
			   0		 3
				 _______	
				|\      |
				|  \    |
				|    \  |
			  2	|______\| 1

*/
				*(lpIB++)=i;
				*(lpIB++)=i+1;
				*(lpIB++)=i+m_nSegment+2;
			}
	
		}
		
		//天空盒
		m_pDevice->CreateVertexBuffer(sizeof(VB),D3DUSAGE_WRITEONLY, D3DFVF_SKYBOX, 
			D3DPOOL_DEFAULT, &m_pVB,NULL);
		void* pVertices;
		m_pVB->Lock(0,0,&pVertices,0);
			memcpy(pVertices,(void*)VB,sizeof(VB));
		m_pVB->Unlock();


		//云的顶点数据
		m_pDevice->CreateVertexBuffer(sizeof(VERTEX_BOX)*nVertex, 0,
			D3DFVF_SKYBOX, D3DPOOL_DEFAULT, &m_pVBSky,NULL);
		m_pVBSky->Lock(0,0,&pVertices,0);
			memcpy(pVertices,(void*)VBSKY,sizeof(VERTEX_BOX)*nVertex);
		m_pVBSky->Unlock();
		
		//天空的索引数据
		m_pDevice->CreateIndexBuffer(sizeof(DWORD)*nIndex,0,D3DFMT_INDEX32, 
					D3DPOOL_DEFAULT, &m_pIBSky,NULL);
		m_pIBSky->Lock(0,0,&pVertices,0);
			memcpy(pVertices,(void*)IBSKY,sizeof(DWORD)*nIndex);
		m_pIBSky->Unlock();
		
		/*delete []IBSKY;
		delete []VBSKY; 	*/
		SAFE_DELARRAY(IBSKY);
		SAFE_DELARRAY(VBSKY);
}



// Function name   : CSkyBox::LoadSkyBox
// Description     : 
// Return type     : void 
// Argument        : char *strConfigFile
// Argument        : char* strSkyName

void CSkyBox::LoadSkyBox(char *strConfigFile,char* strSkyName)
{
	//当表达式为false时产生Debug信息(只对应Debug版本)
	_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++)
		{
			GetPrivateProfileString(strSkyName,strKeyName[i],"\0",strFileName,
			sizeof(strFileName),strConfigFile);
			/*LPCTSTR lpAppName ------- cfg文件中的一个字段名
			LPCTSTR lpKeyName -------- lpAppName 下的一个键名,也就是里面具体的变量名
			LPCTSTR lpDefaut ----------如果没有其前两个参数值,则将此值赋给变量			
			LPSTR lpReturnedString --------接收cfg文件中的值的CString对象,即接收缓冲区
			DWORD nSize ------接收缓冲区的大小
			LPCTSTR lpFileName --------完整的cfg文件路径名*/
			_ASSERT(strFileName[0]); 
			D3DXCreateTextureFromFile(m_pDevice,strFileName, &m_pTexture[i]);
		}
	}

}

// Function name   : CSkyBox::SetMatrix
// Description     : 
// Return type     : void 
void CSkyBox::SetMatrix()
{
	//天空盒的位置总是随着摄像机在动
	//天空盒在移动过程中会遮挡到地图,所以你看上去地形好像没了似的
	//其实是地图某部分到了天空盒的外部
	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;
	m_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
}


⌨️ 快捷键说明

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