client/GameLib/TerrainPatch.cpp

241 lines
6.0 KiB
C++

// TerrainPatch.cpp: implementation of the CTerrainPatch class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TerrainPatch.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch()
{
__Initialize();
}
CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch()
{
Destroy();
}
void CTerrainPatch::SSoftwareTransformPatch::Create()
{
assert(NULL==m_akTerrainVertex);
m_akTerrainVertex=new SoftwareTransformPatch_SSourceVertex[TERRAIN_VERTEX_COUNT];
}
void CTerrainPatch::SSoftwareTransformPatch::Destroy()
{
if (m_akTerrainVertex)
delete [] m_akTerrainVertex;
__Initialize();
}
void CTerrainPatch::SSoftwareTransformPatch::__Initialize()
{
m_akTerrainVertex=NULL;
}
bool CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=TRUE;
void CTerrainPatch::Clear()
{
m_kHT.m_kVB.Destroy();
m_kST.Destroy();
m_WaterVertexBuffer.Destroy();
ClearID();
SetUse(false);
m_bWaterExist = false;
m_bNeedUpdate = true;
m_dwWaterPriCount = 0;
m_byType = PATCH_TYPE_PLAIN;
m_fMinX = m_fMaxX = m_fMinY = m_fMaxY = m_fMinZ = m_fMaxZ = 0.0f;
m_dwVersion=0;
}
void CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount)
{
CGraphicVertexBuffer& rkVB=m_WaterVertexBuffer;
if (!rkVB.Create(uWaterVertexCount, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return;
SWaterVertex* akDstWaterVertex;
if (rkVB.Lock((void **) &akDstWaterVertex))
{
UINT uVBSize=sizeof(SWaterVertex)*uWaterVertexCount;
memcpy(akDstWaterVertex, akSrcVertex, uVBSize);
m_dwWaterPriCount=uWaterVertexCount/3;
rkVB.Unlock();
}
}
void CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
if (SOFTWARE_TRANSFORM_PATCH_ENABLE)
__BuildSoftwareTerrainVertexBuffer(akSrcVertex);
else
__BuildHardwareTerrainVertexBuffer(akSrcVertex);
}
void CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
//DWORD dwVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
m_kST.Create();
SoftwareTransformPatch_SSourceVertex* akDstVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
for (UINT uIndex=0; uIndex!=TERRAIN_VERTEX_COUNT; ++uIndex)
{
*((HardwareTransformPatch_SSourceVertex*)(akDstVertex+uIndex))=*(akSrcVertex+uIndex);
akDstVertex[uIndex].dwDiffuse=0xFFFFFFFF;
}
}
void CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
CGraphicVertexBuffer& rkVB=m_kHT.m_kVB;
if (!rkVB.Create(TERRAIN_VERTEX_COUNT, D3DFVF_XYZ | D3DFVF_NORMAL, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return;
HardwareTransformPatch_SSourceVertex* akDstVertex;
if (rkVB.Lock((void **) &akDstVertex))
{
UINT uVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
memcpy(akDstVertex, akSrcVertex, uVBSize);
rkVB.Unlock();
}
}
void CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
{
if (m_dwVersion==dwVersion)
return;
m_dwVersion=dwVersion;
SoftwareTransformPatch_SSourceVertex* akSrcVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
if (!akSrcVertex)
return;
D3DXVECTOR3 kLightDir=c_rkLight.Direction;
DWORD dwDot;
DWORD dwAmbientR=(c_rkMtrl.Ambient.r*c_rkLight.Ambient.r+c_rkMtrl.Emissive.r)*255.0f;
DWORD dwAmbientG=(c_rkMtrl.Ambient.g*c_rkLight.Ambient.g+c_rkMtrl.Emissive.g)*255.0f;
DWORD dwAmbientB=(c_rkMtrl.Ambient.b*c_rkLight.Ambient.b+c_rkMtrl.Emissive.b)*255.0f;
DWORD dwDiffuseR=(c_rkMtrl.Diffuse.r*c_rkLight.Diffuse.r)*255.0f;
DWORD dwDiffuseG=(c_rkMtrl.Diffuse.g*c_rkLight.Diffuse.g)*255.0f;
DWORD dwDiffuseB=(c_rkMtrl.Diffuse.b*c_rkLight.Diffuse.b)*255.0f;
if (dwDiffuseR>255-dwAmbientR)
dwDiffuseR=255-dwAmbientR;
if (dwDiffuseG+dwAmbientG>255)
dwDiffuseG=255-dwAmbientG;
if (dwDiffuseB+dwAmbientB>255)
dwDiffuseB=255-dwAmbientB;
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
{
float fDot=D3DXVec3Dot(&akSrcVertex[uIndex].kNormal, &kLightDir);
const float N=0xffffff;
const int S=24;
if (fDot<0.0f)
dwDot=(N*-fDot);
else
dwDot=(N*+fDot);
akSrcVertex[uIndex].dwDiffuse=(0xff000000)|
(((dwDiffuseR*dwDot>>S)+dwAmbientR)<<16)|
(((dwDiffuseG*dwDot>>S)+dwAmbientG)<<8)|
((dwDiffuseB*dwDot>>S)+dwAmbientB);
}
}
UINT CTerrainPatch::GetWaterFaceCount()
{
return m_dwWaterPriCount;
}
CTerrainPatchProxy::CTerrainPatchProxy()
{
Clear();
}
CTerrainPatchProxy::~CTerrainPatchProxy()
{
Clear();
}
void CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3& c_rv3Center)
{
m_v3Center=c_rv3Center;
}
bool CTerrainPatchProxy::IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius)
{
float dx=m_v3Center.x-c_rv3Target.x;
float dy=m_v3Center.y-c_rv3Target.y;
float fDist=dx*dx+dy*dy;
float fCheck=fRadius*fRadius;
if (fDist<fCheck)
return true;
return false;
}
void CTerrainPatchProxy::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
{
if (m_pTerrainPatch)
m_pTerrainPatch->SoftwareTransformPatch_UpdateTerrainLighting(dwVersion, c_rkLight, c_rkMtrl);
}
CGraphicVertexBuffer* CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->HardwareTransformPatch_GetVertexBufferPtr();
return NULL;
}
SoftwareTransformPatch_SSourceVertex* CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->SoftwareTransformPatch_GetTerrainVertexDataPtr();
return NULL;
}
UINT CTerrainPatchProxy::GetWaterFaceCount()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->GetWaterFaceCount();
return 0;
}
void CTerrainPatchProxy::Clear()
{
m_bUsed = false;
m_sPatchNum = 0;
m_byTerrainNum = 0xFF;
m_pTerrainPatch = NULL;
}