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

📄 terrain.cpp

📁 AABB碰撞检测,目前主流3D游戏必需,希望对大家有帮助
💻 CPP
字号:
// Terrain.cpp: implementation of the CTerrain class.
//
//////////////////////////////////////////////////////////////////////
#include <d3dx9.h>
#include <d3d9.h>
#include <windows.h>
#include "Terrain.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTerrain::CTerrain(LPDIRECT3DDEVICE9 pDevice,D3DVECTOR position)
{
		m_pDevice=pDevice;
		m_vPos=position;
		m_nCol=0;
		m_nRow=0;

		m_CellWidth=0;
		m_pIB=NULL;
		m_pVB=NULL;
		m_pTexture=NULL;
		m_maxHeight=800; 
		

}
#define SAFE_RELEASE(p) if(p) {p->Release();p=NULL;}
CTerrain::~CTerrain()
{
	SAFE_RELEASE(m_pIB)
	SAFE_RELEASE(m_pVB);
	SAFE_RELEASE(m_pTexture);
	delete []m_pHeightData; 
}

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);

		
		if(D3D_OK!=
		m_pDevice->CreateVertexBuffer(m_nCol*m_nRow*sizeof(TVertexBuffer),
			0,D3DFVF_TERRAIN, D3DPOOL_DEFAULT, &m_pVB,NULL))
		OutputDebugString("创建地形顶点缓冲区失败!\n"); 
		TVertexBuffer* pVertices;

		m_pVB->Lock(0,m_nCol*m_nRow*sizeof(TVertexBuffer),(void**)&pVertices,D3DLOCK_DISCARD);
			for(i=0;i<m_nCol*m_nRow;i++)
			{
				pVertices[i].y=m_pHeightData[i]*m_maxHeight/255.0f;
				pVertices[i].x=float(i%m_nCol)*m_CellWidth;
				pVertices[i].z=(-float(i/m_nCol)+m_nRow)*m_CellWidth;
				pVertices[i].nx=0;
				pVertices[i].ny=1;
				pVertices[i].nz=0;
				
				pVertices[i].tu=m_nTile*(i%m_nCol)/m_nCol ;
				pVertices[i].tv=m_nTile*(i/m_nCol)/m_nRow ;

			}
		m_pVB->Unlock();


		long nBufferSize=(m_nCol-1)*(m_nRow-1)*6*sizeof(DWORD);
		m_pDevice->CreateIndexBuffer(nBufferSize,D3DUSAGE_WRITEONLY,
			D3DFMT_INDEX32,D3DPOOL_MANAGED,&m_pIB,NULL);


		DWORD* pIndex;
		m_pIB->Lock(0,0,(void**)&pIndex,0);
			for(i=0,j=0;i<m_nCol*m_nRow;i++)
			{
				if((i+1)%m_nCol && i/m_nCol!=m_nRow-1)
				{
					pIndex[j+0]=(WORD)i;
					pIndex[j+1]=i+1;
					pIndex[j+2]=i+m_nCol;
					pIndex[j+3]=i+m_nCol;
					pIndex[j+4]=i+1;
					pIndex[j+5]=i+1+m_nCol;
					j+=6;
				}
			}
		m_pIB->Unlock();
}

	void CTerrain::Render()
	{
		m_pDevice->SetTexture(0,m_pTexture);
		m_pDevice->SetFVF(D3DFVF_TERRAIN);
		m_pDevice->SetStreamSource(0,m_pVB,0,sizeof(TVertexBuffer));
		m_pDevice->SetIndices(m_pIB);
		SetWorldTransorm(); 
		m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
			0,0,m_nCol*m_nRow,0,(m_nCol-1)*(m_nRow-1)*2);

	}

	void CTerrain::SetWorldTransorm()
	{
		D3DMATRIX matWorld;
		ZeroMemory(&matWorld,sizeof(matWorld));
		matWorld._11=1;
		matWorld._22=1;
		matWorld._33=1;
		matWorld._44=1;

		matWorld._41=m_vPos.x-m_nCol*m_CellWidth/2.0f ;	//地形中心在m_vPos
		matWorld._42=m_vPos.y;  
		matWorld._43=m_vPos.z-m_nRow*m_CellWidth/2.0f;		//地形中心在m_vPos
		m_pDevice->SetTransform(D3DTS_WORLD,&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/256.0f);	
			h2=(m_pHeightData[row1*m_nCol+col2]*m_maxHeight/256.0f);	
			h3=(m_pHeightData[row2*m_nCol+col1]*m_maxHeight/256.0f);	
			h4=(m_pHeightData[row2*m_nCol+col2]*m_maxHeight/256.0f);	
			ha=(h2*(rx-col1)+h1*(col2-rx));
			hb=(h4*(rx-col1)+h3*(col2-rx));
			return (hb*(rz-row1)+ha*(row2-rz));

		}
	}

⌨️ 快捷键说明

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