www.pudn.com > 3D_Tank.rar > Terrain.cpp
#include "Terrain.h"
CTerrain::CTerrain()
{}
CTerrain::~CTerrain()
{}
VOID CTerrain::InitTerrainFromHeightmap(const CComPtr &device,
LPCTSTR pSrcRawFile,
int nCxPixel, int nCzPixel,
int nCxLength, int nCzLength)
{
m_pDevice = device;
m_MapInfo.InitTerrainInfo(pSrcRawFile, nCxPixel, nCzPixel, nCxLength, nCzLength);
ID3DXMesh *mesh;
D3DXCreateMeshFVF(m_MapInfo.GetPolygonCount(), m_MapInfo.GetVertexCount(),
0, TerrainVertex::FVF, m_pDevice.Get(), &mesh);
m_pTerrain.Reset(mesh);
TerrainVertex *vTemp;
m_pTerrain->LockVertexBuffer(0, reinterpret_cast(&vTemp));
int x = m_MapInfo.GetCxVertexCount();
int z = m_MapInfo.GetCzVertexCount();
int cx = m_MapInfo.GetCxBlockLength();
int cz = m_MapInfo.GetCzBlockLength();
for (int i = 0; i < z; ++i)
for (int j = 0; j < x; ++j)
{
vTemp[i * x + j].x = j * (float)cx;
vTemp[i * x + j].y = (float)m_MapInfo.m_vecHeight[i * x + j];
vTemp[i * x + j].z = i * (float)cz;
vTemp[i * x + j].tx = (float)j;
vTemp[i * x + j].ty = (float)i;
}
m_pTerrain->UnlockVertexBuffer();
WORD *wTemp;
m_pTerrain->LockIndexBuffer(0, reinterpret_cast(&wTemp));
for (int i = 0, n = 0; i < z - 1; ++i)
for (int j = 0; j < x - 1; ++j)
{
wTemp[n++] = static_cast(i * x + j);
wTemp[n++] = static_cast((i + 1) * x + j);
wTemp[n++] = static_cast((i + 1) * x + (j + 1));
wTemp[n++] = static_cast(i * x + j);
wTemp[n++] = static_cast((i + 1) * x + (j + 1));
wTemp[n++] = static_cast(i * x + (j + 1));
}
m_pTerrain->UnlockIndexBuffer();
D3DXComputeNormals(m_pTerrain.Get(), 0);
}
BOOL CTerrain::SetTexture(LPCTSTR pSrcFileName)
{
IDirect3DTexture9 *texture = 0;
D3DXCreateTextureFromFile(m_pDevice.Get(), pSrcFileName, &texture);
m_pTexture.Reset(texture);
m_pDevice->SetTexture(0, m_pTexture.Get());
return TRUE;
}
BOOL CTerrain::PreComputerLight (const D3DXVECTOR3 &vLightDir,
const D3DXCOLOR &vLightColor)
{
D3DXVECTOR3 vLight = -vLightDir;
TerrainVertex *vTemp;
m_pTerrain->LockVertexBuffer(0, reinterpret_cast(&vTemp));
int nVertex = m_MapInfo.GetVertexCount();
for (int n = 0; n < nVertex; ++n)
vTemp[n].color = vLightColor * ComputeShade(vTemp[n].normal, vLight);
m_pTerrain->UnlockVertexBuffer();
return TRUE;
}
//C-------D
//| / |
//| / |
//| / |
//A-------B
float CTerrain::GetHeight(float x, float z)
{ return m_MapInfo.GetHeight(x, z);}
VOID CTerrain::GetNormal(float x, float z, D3DXVECTOR3 *vNormal)
{ m_MapInfo.GetNormal(x,z,vNormal);}
BOOL CTerrain::IsInTerrain(float x, float z)
{
return m_MapInfo.IsInTerrain(x, z);
}
float CTerrain::ComputeShade(D3DXVECTOR3 normal, D3DXVECTOR3 reverseLight)
{
float cos = D3DXVec3Dot(&normal, &reverseLight);
if (cos < 0)
cos = 0;
return cos;
}
BOOL CTerrain::PrepareRenderState()
{
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pDevice->SetTexture(0, m_pTexture.Get());
m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
m_pDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
return TRUE;
}
BOOL CTerrain::ResetRenderState()
{
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
m_pDevice->SetTexture(0, 0);
return TRUE;
}
BOOL CTerrain::Render()
{
PrepareRenderState();
m_pTerrain->DrawSubset(0);
ResetRenderState();
return TRUE;
}