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

📄 game_terrain.cpp

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

CTerrain::CTerrain(LPDIRECT3DDEVICE9 pDevice,D3DVECTOR position)
{
		m_pMesh			 =	NULL;
		m_pDevice		 =	pDevice;
		m_vPos			 =	position;
		m_nCol			 =	0;
		m_nRow			 =	0;
		m_CellWidth		 =	0;
		m_dwNumOfVertices=	0;	
		m_dwNumOfIndices =	0;
		m_dwNumOfPolygons=	0;
		m_pTexture		 = NULL;
		m_maxHeight		 = 800; 

		//设置基本的材质
		D3DCOLORVALUE Diffuse = {1.0, 1.0, 1.0, 0.0};
		D3DCOLORVALUE Ambient = {1.0, 1.0, 1.0, 0.0};
		D3DCOLORVALUE Specular = {0.0, 0.0, 0.0, 0.0};
		D3DCOLORVALUE Emissive = {0.0, 0.0, 0.0, 0.0};
		SetMaterial(Diffuse, Ambient, Specular, Emissive, 0);

}
CTerrain::~CTerrain()
{
	SAFE_RELEASE(m_pMesh);
	SAFE_RELEASE(m_pTexture);
	SAFE_DELARRAY(m_pHeightData);
	//SAFE_DELETE(m_dwNumOfVertices);
	//SAFE_DELETE(m_dwNumOfIndices);
	//SAFE_DELETE(m_dwNumOfPolygons);
	m_pDevice = NULL;
}

void CTerrain::Initialize(char* strTerrain,char* strTexture,
				float cellWidth,float height,float nTile)
{
	m_nTile=nTile;
	m_CellWidth=cellWidth;
	m_maxHeight=height; 
	D3DXCreateTextureFromFile(m_pDevice,
		strTexture,	&m_pTexture);		//创建纹理

	//用GDI对象来读取位图,但是会转换成DIB位图
	long i=0,j=0;
	BITMAP  bmp;
	HBITMAP	hBmp;
	HDC		hDC;
	HBITMAP	oldBmp;
	hDC = CreateCompatibleDC(NULL); 
	hBmp = (HBITMAP)LoadImage(NULL,strTerrain,
			IMAGE_BITMAP,m_nCol,m_nRow,LR_LOADFROMFILE);
	oldBmp = (HBITMAP)SelectObject(hDC,hBmp);
	//从高度图中读取高度信息
	GetObject(hBmp, sizeof(bmp), &bmp);
	m_nCol = bmp.bmWidth;
	m_nRow = bmp.bmHeight; 
	m_pHeightData = new BYTE[m_nCol*m_nRow];
	DWORD color;
	for(i=0; i<m_nRow; i++)
	for(j=0; j<m_nCol; j++)
	{	
		color = GetPixel(hDC,j,i);
		m_pHeightData[i*m_nCol+j] = *(BYTE*)&color;		//取红色通道 0xAABBGGRR
	}
	DeleteObject(oldBmp);
	DeleteObject(hDC);
	DeleteObject(hBmp);

	m_dwNumOfVertices = m_nRow * m_nCol;
	m_dwNumOfPolygons = (m_nCol-1)*(m_nRow-1)*2;

	D3DXCreateMeshFVF(m_dwNumOfPolygons,m_dwNumOfVertices,D3DXMESH_MANAGED,D3DFVF_TERRAIN,m_pDevice,&m_pMesh); 

	TVertexBuffer* pVertices;
	m_pMesh->LockVertexBuffer(0,(void**)&pVertices);
		for(i=0;i<(long)m_dwNumOfVertices;i++)
		{
			pVertices[i].y = m_pHeightData[i];
			pVertices[i].x = float(i%m_nCol);
			pVertices[i].z = -float(i/m_nCol)+m_nRow;
			pVertices[i].nx = 0;
			pVertices[i].ny = 1;
			pVertices[i].nz = 0;
			
			/*pVertices[i].tu = m_nTile*pVertices[i].x/m_nCol ;
			pVertices[i].tv = m_nTile*pVertices[i].z/m_nRow ;*/
			pVertices[i].tu = pVertices[i].x/m_nCol ;
			pVertices[i].tv = pVertices[i].z/m_nRow ;
		}
	m_pMesh->UnlockVertexBuffer();

	WORD* pIndex;
	m_pMesh->LockIndexBuffer(0,(void**)&pIndex);
	for(i=0,j=0;i<(long)m_dwNumOfVertices;i++)
	{
		if((i+1)%m_nCol && i/m_nCol!=m_nRow-1)
		{
			pIndex[j+0]=(WORD)i;
			pIndex[j+1]=(WORD)(i+1);
			pIndex[j+2]=(WORD)(i+m_nCol);
			pIndex[j+3]=(WORD)(i+m_nCol);
			pIndex[j+4]=(WORD)(i+1);
			pIndex[j+5]=(WORD)(i+1+m_nCol);
			j+=6;
		}
	}
	m_pMesh->UnlockIndexBuffer();
	SetWorldTransorm();
}

void CTerrain::Render()
{
	m_pDevice->SetTexture(0,m_pTexture);
	//m_pDevice->SetFVF(D3DFVF_TERRAIN);
	m_pDevice->SetTransform(D3DTS_WORLD,&m_matWorld);
	m_pMesh->DrawSubset( 0 );

}

void CTerrain::SetWorldTransorm()
{
	D3DMATRIX matWorld;
	ZeroMemory(&matWorld,sizeof(matWorld));
	matWorld._11=m_CellWidth;
	matWorld._22=m_maxHeight/255.0f;
	matWorld._33=m_CellWidth;
	matWorld._44=1;
	//地形的世界坐标系是以原点为中心
	matWorld._41=m_vPos.x-m_nCol*m_CellWidth/2 ;	//地形中心在m_vPos(原点)
	matWorld._42=m_vPos.y;  
	matWorld._43=m_vPos.z-m_nRow*m_CellWidth/2;		//地形中心在m_vPos
	m_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
	m_matWorld = matWorld;
};

//一个不怎么好的插值算法
float CTerrain::GetHeight(float x,float z)
{
	x+=m_vPos.x+m_CellWidth*m_nCol/2.0f;
	z+=m_vPos.z+m_CellWidth*m_nRow/2.0f;

	float rx,rz;
	rx=x/m_CellWidth;
	rz=m_nRow-z/m_CellWidth;

	long col1,row1,col2,row2;
	float h1,h2,h3,h4,ha,hb;
	col1=DWORD(rx);
	row1=DWORD(rz);

	if(col1>m_nCol || col1<0 ||row1>m_nRow || row1<0) return 0;
	else 
	{	//双线性插值法计算
		col2=(col1==m_nCol)?col1:col1+1;
		row2=(row1==m_nRow)?row1:row1+1;
		h1=(m_pHeightData[row1*m_nCol+col1]*m_maxHeight/255.0f);	
		h2=(m_pHeightData[row1*m_nCol+col2]*m_maxHeight/255.0f);	
		h3=(m_pHeightData[row2*m_nCol+col1]*m_maxHeight/255.0f);	
		h4=(m_pHeightData[row2*m_nCol+col2]*m_maxHeight/255.0f);	
		ha=(h2*(rx-col1)+h1*(col2-rx));
		hb=(h4*(rx-col1)+h3*(col2-rx));
		return (hb*(rz-row1)+ha*(row2-rz));

	}
}
bool CTerrain::SetMaterial(D3DCOLORVALUE Diffuse, D3DCOLORVALUE Ambient, 
						   D3DCOLORVALUE Specular, D3DCOLORVALUE Emissive, 
						   float rPower)
{
	//设置漫反射
	m_matMaterial.Diffuse = Diffuse;
	//设置环境光
	m_matMaterial.Ambient = Ambient;
	//设置镜面反射
	m_matMaterial.Specular = Specular;
	m_matMaterial.Power = rPower;
	//设置反射
	m_matMaterial.Emissive = Emissive;
	return true;
}
//vPos为摄象机经过地形逆变换之后的位置
bool CTerrain::GetGroundRect(D3DXVECTOR3 vPos,D3DXVECTOR3* vTL,D3DXVECTOR3* vTR,D3DXVECTOR3* vBL,D3DXVECTOR3* vBR)
{
	vTL->x = (float)((int)vPos.x);
	vTL->z = (float)((int)vPos.z + 1);
	vTL->y = m_pHeightData[(m_nRow - ((int)vPos.z + 1))*m_nCol + ((int)vPos.x)];

	vTR->x = (float)((int)vPos.x + 1);
	vTR->z = (float)((int)vPos.z + 1);
	vTR->y = m_pHeightData[(m_nRow - ((int)vPos.z + 1))*m_nCol + ((int)vPos.x + 1)];

	vBL->x = (float)((int)vPos.x);
	vBL->z = (float)((int)vPos.z);
	vBL->y = m_pHeightData[(m_nRow - ((int)vPos.z))*m_nCol + ((int)vPos.x)];

	vBR->x = (float)((int)vPos.x + 1);
	vBR->z = (float)((int)vPos.z);
	vBR->y = m_pHeightData[(m_nRow - ((int)vPos.z))*m_nCol + ((int)vPos.x + 1)];
	return true;
}
HRESULT CTerrain::GetTerrainVertex(D3DXVECTOR3 *cross,DWORD index,float u,float v)
{
	WORD* pIndices;
	WORD index1,index2,index3;
	D3DXVECTOR3 v1,v2,v3;
	m_pMesh->LockIndexBuffer(0,(void**)&pIndices);

	index1=pIndices[index*3];
	index2=pIndices[index*3+1];
	index3=pIndices[index*3+2];
	m_pMesh->UnlockIndexBuffer();

	TVertexBuffer* pcvVertices;
	m_pMesh->LockVertexBuffer (0,(void**)&pcvVertices);

	v1.x=pcvVertices[index1].x;
	v1.y=pcvVertices[index1].y;
	v1.z=pcvVertices[index1].z;

	v2.x=pcvVertices[index2].x;
	v2.y=pcvVertices[index2].y;
	v2.z=pcvVertices[index2].z;

	v3.x=pcvVertices[index3].x;
	v3.y=pcvVertices[index3].y;
	v3.z=pcvVertices[index3].z;
	m_pMesh->UnlockVertexBuffer();

	*cross = v1 + u * (v2 - v1) + v * (v3 - v1);
	return S_OK;
}

⌨️ 快捷键说明

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