700 lines
No EOL
20 KiB
C++
700 lines
No EOL
20 KiB
C++
#include "StdAfx.h"
|
||
#include "EtLoader.h"
|
||
#include "EtLayeredMultiUVTerrain.h"
|
||
|
||
#ifdef _DEBUG
|
||
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
||
#endif
|
||
|
||
extern CSyncLock *g_pEtRenderLock;
|
||
|
||
CEtCliffTerrain::CEtCliffTerrain(void)
|
||
{
|
||
m_nTechniqueIndex = 0;
|
||
SetTextureLayerCount( 4 );
|
||
m_nMaterialName = 1;
|
||
}
|
||
|
||
CEtCliffTerrain::~CEtCliffTerrain(void)
|
||
{
|
||
}
|
||
|
||
void CEtCliffTerrain::GenerateTexureCoord()
|
||
{
|
||
int i, j;
|
||
EtVector2 *pTexCoord1, *pTexCoord2;
|
||
DWORD *pTerrainAlpha;
|
||
float *pValueX, *pValueZ;
|
||
int nVertexCount;
|
||
|
||
nVertexCount = ( m_TerrainInfo.nSizeX + 1 ) * ( m_TerrainInfo.nSizeY + 1 );
|
||
pTexCoord1 = new EtVector2[ nVertexCount ];
|
||
pTexCoord2 = new EtVector2[ nVertexCount ];
|
||
pTerrainAlpha = new DWORD[ nVertexCount ];
|
||
pValueX = new float[ nVertexCount ];
|
||
pValueZ = new float[ nVertexCount ];
|
||
for( i = 0; i <= m_TerrainInfo.nSizeY; i++ )
|
||
{
|
||
for( j = 0; j <= m_TerrainInfo.nSizeX; j++ )
|
||
{
|
||
int nCoordOffset;
|
||
EtVector3 Normal;
|
||
|
||
nCoordOffset = VertexOffset( j, i );
|
||
Normal = GetVertexNormal( j, i );
|
||
|
||
pValueX[ nCoordOffset ] = CalcAddOffsetX( &Normal );
|
||
pValueZ[ nCoordOffset ] = CalcAddOffsetZ( &Normal );
|
||
pTerrainAlpha[ nCoordOffset ] = CalcBlendWeight( &Normal );
|
||
}
|
||
}
|
||
for( i = 0; i <= m_TerrainInfo.nSizeY; i++ )
|
||
{
|
||
for( j = 0; j <= m_TerrainInfo.nSizeX; j++ )
|
||
{
|
||
int nCoordOffset, nCopyOffset;
|
||
|
||
nCoordOffset = VertexOffset( j, i );
|
||
if( pValueX[ nCoordOffset ] == 0.0f )
|
||
{
|
||
pValueX[ nCoordOffset ] = 1.0f;
|
||
nCopyOffset = -1;
|
||
if( ( j < m_TerrainInfo.nSizeX - 2 ) && ( pValueX[ nCoordOffset + 2 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset + 2;
|
||
}
|
||
else if( ( j < m_TerrainInfo.nSizeX - 1 ) && ( pValueX[ nCoordOffset + 1 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset + 1;
|
||
}
|
||
else if( ( j != 0 ) && ( pValueX[ nCoordOffset - 1 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset - 1;
|
||
}
|
||
if( nCopyOffset != -1 )
|
||
{
|
||
pValueX[ nCoordOffset ] = pValueX[ nCopyOffset ];
|
||
pTerrainAlpha[ nCoordOffset ] = pTerrainAlpha[ nCopyOffset ];
|
||
}
|
||
}
|
||
if( pValueZ[ nCoordOffset ] == 0.0f )
|
||
{
|
||
pValueZ[ nCoordOffset ] = 1.0f;
|
||
nCopyOffset = -1;
|
||
if( ( i < m_TerrainInfo.nSizeY - 2 ) && ( pValueZ[ nCoordOffset + m_TerrainInfo.nSizeX + 2 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset + m_TerrainInfo.nSizeX + 2;
|
||
pValueZ[ nCoordOffset ] = pValueZ[ nCoordOffset + m_TerrainInfo.nSizeX + 2 ];
|
||
pTerrainAlpha[ nCoordOffset ] = pTerrainAlpha[ nCoordOffset + m_TerrainInfo.nSizeX + 2 ];
|
||
}
|
||
else if( ( i < m_TerrainInfo.nSizeY - 1 ) && ( pValueZ[ nCoordOffset + m_TerrainInfo.nSizeX + 1 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset + m_TerrainInfo.nSizeX + 1;
|
||
}
|
||
else if( ( i != 0 ) && ( pValueZ[ nCoordOffset - m_TerrainInfo.nSizeX - 1 ] != 0.0f ) )
|
||
{
|
||
nCopyOffset = nCoordOffset - m_TerrainInfo.nSizeX - 1;
|
||
}
|
||
if( nCopyOffset != -1 )
|
||
{
|
||
pValueZ[ nCoordOffset ] = pValueZ[ nCopyOffset ];
|
||
pTerrainAlpha[ nCoordOffset ] = pTerrainAlpha[ nCopyOffset ];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
float fTextureDistance;
|
||
|
||
fTextureDistance = m_TerrainInfo.fTileSize / m_vecTextureDist[ 3 ];
|
||
for( i = 0; i <= m_TerrainInfo.nSizeY; i++ )
|
||
{
|
||
for( j = 0; j <= m_TerrainInfo.nSizeX; j++ )
|
||
{
|
||
int nCoordOffset;
|
||
float fAddCoord, fValue;
|
||
|
||
nCoordOffset = VertexOffset( j, i );
|
||
fValue = pValueX[ nCoordOffset ];
|
||
fAddCoord = fValue * GetHeight( j, i ) * m_TerrainInfo.fHeightMultiply / fTextureDistance;
|
||
pTexCoord1[ nCoordOffset ].x = ( m_TerrainInfo.TerrainOffset.z + i * m_TerrainInfo.fTileSize )
|
||
/ fTextureDistance;
|
||
pTexCoord1[ nCoordOffset ].y = ( ( m_TerrainInfo.TerrainOffset.x + j * m_TerrainInfo.fTileSize )
|
||
/ fTextureDistance - fAddCoord ) * fValue;
|
||
|
||
fValue = -pValueZ[ nCoordOffset ];
|
||
fAddCoord = fValue * GetHeight( j, i ) * m_TerrainInfo.fHeightMultiply / fTextureDistance;
|
||
pTexCoord2[ nCoordOffset ].x = ( m_TerrainInfo.TerrainOffset.x + j * m_TerrainInfo.fTileSize )
|
||
/ fTextureDistance;
|
||
pTexCoord2[ nCoordOffset ].y = ( ( m_TerrainInfo.TerrainOffset.z + i * m_TerrainInfo.fTileSize )
|
||
/ fTextureDistance - fAddCoord ) * fValue;
|
||
}
|
||
}
|
||
|
||
CMemoryStream *pStream;
|
||
|
||
pStream = new CMemoryStream( pTexCoord1, nVertexCount * sizeof( EtVector2 ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_TEXCOORD, 0, nVertexCount );
|
||
pStream->Initialize( pTexCoord2, nVertexCount * sizeof( EtVector2 ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_TEXCOORD, 1, nVertexCount );
|
||
pStream->Initialize( pTerrainAlpha, nVertexCount * sizeof( DWORD ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_COLOR, 1, nVertexCount );
|
||
|
||
delete [] pValueX;
|
||
delete [] pValueZ;
|
||
delete [] pTexCoord1;
|
||
delete [] pTexCoord2;
|
||
delete [] pTerrainAlpha;
|
||
delete pStream;
|
||
}
|
||
|
||
DWORD CEtCliffTerrain::CalcBlendWeight( EtVector3 *pNormal )
|
||
{
|
||
DWORD dwRet;
|
||
EtVector2 Weight, BlendWeight;
|
||
|
||
Weight.x = fabs( EtVec3Dot( pNormal, &EtVector3( 0.0f, 0.0f, 1.0f ) ) );
|
||
if( Weight.x == 0 )
|
||
{
|
||
return 0xff000000;
|
||
}
|
||
Weight.y = fabs( EtVec3Dot( pNormal, &EtVector3( 1.0f, 0.0f, 0.0f ) ) );
|
||
if( Weight.y == 0 )
|
||
{
|
||
return 0x00ff0000;
|
||
}
|
||
BlendWeight.x = max( 0.0f, Weight.x - TERRAIN_BLEND_THRESH_HOLD );
|
||
BlendWeight.y = max( 0.0f, Weight.y - TERRAIN_BLEND_THRESH_HOLD );
|
||
if( BlendWeight.x + BlendWeight.y <= 0.0f )
|
||
{
|
||
if( Weight.x >= Weight.y )
|
||
{
|
||
BlendWeight.x = 1.0f;
|
||
}
|
||
else
|
||
{
|
||
BlendWeight.y = 1.0f;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float fAddBlend;
|
||
|
||
fAddBlend = BlendWeight.x + BlendWeight.y;
|
||
BlendWeight.x /= fAddBlend;
|
||
BlendWeight.y /= fAddBlend;
|
||
}
|
||
|
||
dwRet = ( ( DWORD )( BlendWeight.y * 255 ) << 24 ) + ( ( DWORD )( BlendWeight.x * 255 ) << 16 );
|
||
|
||
return dwRet;
|
||
}
|
||
|
||
float CEtCliffTerrain::CalcAddOffsetX( EtVector3 *pFaceNormal )
|
||
{
|
||
float fDot1, fDot2;
|
||
|
||
if( EtVec3Dot( &EtVector3( 0.0f, 1.0f, 0.0f ), pFaceNormal ) > 0.995f )
|
||
{
|
||
return 0.0f;
|
||
}
|
||
fDot1 = EtVec3Dot( &EtVector3( -1.0f, 0.0f, 0.0f ), pFaceNormal );
|
||
fDot2 = EtVec3Dot( &EtVector3( 1.0f, 0.0f, 0.0f ), pFaceNormal );
|
||
|
||
if( fDot1 > fDot2 )
|
||
{
|
||
return -1.0f;
|
||
}
|
||
else if( fDot1 < fDot2 )
|
||
{
|
||
return 1.0f;
|
||
}
|
||
else
|
||
{
|
||
return 0.0f;
|
||
}
|
||
}
|
||
|
||
|
||
float CEtCliffTerrain::CalcAddOffsetZ( EtVector3 *pFaceNormal )
|
||
{
|
||
float fDot1, fDot2;
|
||
|
||
if( EtVec3Dot( &EtVector3( 0.0f, 1.0f, 0.0f ), pFaceNormal ) > 0.995f )
|
||
{
|
||
return 0.0f;
|
||
}
|
||
fDot1 = EtVec3Dot( &EtVector3( 0.0f, 0.0f, -1.0f ), pFaceNormal );
|
||
fDot2 = EtVec3Dot( &EtVector3( 0.0f, 0.0f, 1.0f ), pFaceNormal );
|
||
if( fDot1 > fDot2 )
|
||
{
|
||
return 1.0f;
|
||
}
|
||
else if( fDot1 < fDot2 )
|
||
{
|
||
return -1.0f;
|
||
}
|
||
else
|
||
{
|
||
return 0.0f;
|
||
}
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
// CEtDetailCliffTerrain
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
CEtDetailCliffTerrain::CEtDetailCliffTerrain()
|
||
{
|
||
m_nTechniqueIndex = 1;
|
||
SetTextureLayerCount( 8 );
|
||
}
|
||
|
||
CEtDetailCliffTerrain::~CEtDetailCliffTerrain()
|
||
{
|
||
}
|
||
|
||
void CEtDetailCliffTerrain::CreateMaterial( const char *pEffectName )
|
||
{
|
||
CEtCliffTerrain::CreateMaterial( pEffectName );
|
||
|
||
int i;
|
||
char szParamName[ 64 ];
|
||
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_fTextureDistance2", &m_vecTextureDist[ 4 ] );
|
||
for( i = 0; i < 4; i++ )
|
||
{
|
||
int nTexIndex = -1;
|
||
sprintf( szParamName, "g_LayerFarTex%d", i + 1 );
|
||
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, szParamName, &nTexIndex );
|
||
SetTextureParam( i + 4 );
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
// CEtLowDetailTerrain
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
CEtLowDetailTerrain::CEtLowDetailTerrain()
|
||
{
|
||
m_nMaterialName = 0;
|
||
}
|
||
|
||
CEtLowDetailTerrain::~CEtLowDetailTerrain()
|
||
{
|
||
}
|
||
|
||
void CEtLowDetailTerrain::Clear()
|
||
{
|
||
SAFE_RELEASE_SPTR( m_hEntireMap );
|
||
CEtTerrain::Clear();
|
||
}
|
||
|
||
void CEtLowDetailTerrain::InitializeTerrain()
|
||
{
|
||
SAFE_RELEASE_SPTR( m_hMaterial ) ;
|
||
m_hMaterial = LoadResource( "LowDetailTerrain.fx", RT_SHADER, true );
|
||
SAFE_RELEASE_SPTR( m_hLightMap );
|
||
|
||
for( int i = 0; i < ( int )m_vecCustomParam.size(); i++ ) {
|
||
if( m_vecCustomParam[ i ].Type == EPT_TEX ) {
|
||
EtResourceHandle hHandle;
|
||
if( m_vecCustomParam[ i ].nTextureIndex != -1 ) {
|
||
hHandle = CEtResource::GetResource( m_vecCustomParam[ i ].nTextureIndex );
|
||
SAFE_RELEASE_SPTR( hHandle );
|
||
}
|
||
}
|
||
}
|
||
m_vecCustomParam.clear();
|
||
m_MeshStream.Clear();
|
||
|
||
int nVertexCount = ( m_TerrainInfo.nSizeX / 2 + 1 ) * ( m_TerrainInfo.nSizeY / 2 + 1 );
|
||
EtVector3 *pPosition = new EtVector3[ nVertexCount ];
|
||
|
||
int i, j;
|
||
int nSizeX, nSizeY;
|
||
nSizeX = m_TerrainInfo.nSizeX / 2 + 1;
|
||
nSizeY = m_TerrainInfo.nSizeY / 2 + 1;
|
||
for( i = 0; i < nSizeY; i++ )
|
||
{
|
||
for( j = 0; j < nSizeX; j++ )
|
||
{
|
||
pPosition[ i * nSizeX + j ].x = j * m_TerrainInfo.fTileSize * 2;
|
||
pPosition[ i * nSizeX + j ].y = GetHeight( j * 2, i * 2 );
|
||
pPosition[ i * nSizeX + j ].z = i * m_TerrainInfo.fTileSize * 2;
|
||
if( pPosition[ i * nSizeX + j ].y > m_BoundingBox.Max.y )
|
||
{
|
||
m_BoundingBox.Max.y = pPosition[ i * nSizeX + j ].y;
|
||
}
|
||
if( pPosition[ i * nSizeX + j ].y < m_BoundingBox.Min.y )
|
||
{
|
||
m_BoundingBox.Min.y = pPosition[ i * nSizeX + j ].y;
|
||
}
|
||
}
|
||
}
|
||
|
||
CMemoryStream *pStream = new CMemoryStream( pPosition, nVertexCount * sizeof( EtVector3 ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_POSITION, 0, nVertexCount );
|
||
delete pStream;
|
||
delete [] pPosition;
|
||
|
||
int nTexIndex = -1;
|
||
nTexIndex = m_hEntireMap->GetMyIndex();
|
||
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, "g_EntireTex", &nTexIndex );
|
||
|
||
int nMapSize = m_hEntireMap->Width() * 2;
|
||
EtVector4 TerrainBlockSize;
|
||
TerrainBlockSize.x = ( m_TerrainInfo.nSizeX + m_TerrainInfo.nSizeX * 2.0f / nMapSize ) * m_TerrainInfo.fTileSize;
|
||
TerrainBlockSize.y = ( m_TerrainInfo.nSizeY + m_TerrainInfo.nSizeY * 2.0f / nMapSize ) * m_TerrainInfo.fTileSize;
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR, m_hMaterial, "g_TerrainBlockSize", &TerrainBlockSize );
|
||
|
||
EtVector4 vPixelSize;
|
||
vPixelSize.x = 1.0f / nMapSize;
|
||
vPixelSize.y = 1.0f / nMapSize;
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR, m_hMaterial, "g_fPixelSize", &vPixelSize );
|
||
}
|
||
|
||
void CEtLowDetailTerrain::BakeLowDetailMap()
|
||
{
|
||
//const int TEXTURE_SIZE = 512;
|
||
// #40097 Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>۾<EFBFBD><DBBE><EFBFBD> <20><><EFBFBD><EFBFBD> 64<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3>.
|
||
const int TEXTURE_SIZE = 64;
|
||
|
||
m_hEntireMap = CEtTexture::CreateRenderTargetTexture( TEXTURE_SIZE, TEXTURE_SIZE, FMT_A8R8G8B8 );
|
||
|
||
EtSurface *pBackupRenderTarget = GetEtDevice()->GetRenderTarget();
|
||
EtSurface *pBackupDepthTarget = GetEtDevice()->GetDepthStencilSurface();
|
||
GetEtDevice()->SetRenderTarget( m_hEntireMap->GetSurfaceLevel() );
|
||
GetEtDevice()->SetDepthStencilSurface( NULL);
|
||
GetEtDevice()->ClearBuffer( 0xffffffff, 1.0f, 0, true, false, false);
|
||
|
||
GetEtDevice()->BeginScene();
|
||
GetEtDevice()->EnableZ( false );
|
||
GetEtDevice()->SetCullMode( CULL_NONE );
|
||
|
||
SCameraInfo CamInfo;
|
||
CamInfo.Type = CT_ORTHOGONAL;
|
||
CamInfo.Target = CT_RENDERTARGET_NO_GENERATE_BACKBUFFER;
|
||
CamInfo.fWidth = TEXTURE_SIZE;
|
||
CamInfo.fHeight = TEXTURE_SIZE;
|
||
CamInfo.fViewWidth = m_TerrainInfo.fTileSize*m_TerrainInfo.nSizeX;
|
||
CamInfo.fViewHeight = m_TerrainInfo.fTileSize*m_TerrainInfo.nSizeY;
|
||
|
||
EtCameraHandle hCamera = EternityEngine::CreateCamera( &CamInfo );
|
||
hCamera->LookAt( EtVector3(0,5000,0), EtVector3(0,0,0), EtVector3( 0.0f, 0.0f, 1.0f ) );
|
||
EtMatrix MatScale, *ViewMat;
|
||
EtMatrixScaling(&MatScale, 1.f, -1.f, 1.f);
|
||
ViewMat = hCamera->GetViewMat();
|
||
EtMatrixMultiply(ViewMat, ViewMat, &MatScale);
|
||
|
||
EtCameraHandle hCameraBackup = CEtCamera::GetActiveCamera();
|
||
hCamera->Activate();
|
||
EtViewPort m_BackupViewport;
|
||
GetEtDevice()->GetViewport( &m_BackupViewport );
|
||
EtViewPort terrainViewport;
|
||
terrainViewport.X = 0;
|
||
terrainViewport.Y = 0;
|
||
terrainViewport.Width = TEXTURE_SIZE;
|
||
terrainViewport.Height = TEXTURE_SIZE;
|
||
terrainViewport.MinZ = 0;
|
||
terrainViewport.MaxZ = 1;
|
||
GetEtDevice()->SetViewport( &terrainViewport );
|
||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
EtMatrix WorldMat;
|
||
EtMatrixTranslation(&WorldMat, -(m_TerrainInfo.fTileSize*m_TerrainInfo.nSizeX/2), 0, -(m_TerrainInfo.fTileSize*m_TerrainInfo.nSizeY/2) );
|
||
|
||
CEtLight::SetDirLightAttenuation( 1.f );
|
||
m_hMaterial->SetTechnique( m_nTechniqueIndex );
|
||
int nPasses;
|
||
m_hMaterial->BeginEffect( nPasses );
|
||
m_hMaterial->BeginPass( 0 );
|
||
m_hMaterial->SetGlobalParams();
|
||
|
||
m_hMaterial->SetWorldMatParams( &WorldMat, &WorldMat );
|
||
m_hMaterial->SetCustomParamList( m_vecCustomParam );
|
||
m_hMaterial->CommitChanges();
|
||
m_MeshStream.Draw( m_hMaterial->GetVertexDeclIndex( m_nTechniqueIndex, 0 ) );
|
||
m_hMaterial->EndPass();
|
||
m_hMaterial->EndEffect();
|
||
///////////////////////////////////////////////////////////////////////////////////////
|
||
GetEtDevice()->SetViewport( &m_BackupViewport );
|
||
GetEtDevice()->SetRenderTarget( pBackupRenderTarget );
|
||
GetEtDevice()->SetDepthStencilSurface( pBackupDepthTarget );
|
||
GetEtDevice()->EndScene();
|
||
SAFE_RELEASE_SPTR( hCamera );
|
||
if( hCameraBackup )
|
||
{
|
||
hCameraBackup->Activate();
|
||
}
|
||
|
||
GetEtDevice()->EnableZ( true );
|
||
|
||
m_hEntireMap->RemoveRenderTarget();
|
||
|
||
InitializeTerrain();
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
// CEtTerrainOpti
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
CEtTerrainOpti::CEtTerrainOpti(void)
|
||
{
|
||
m_bProcessLayer = false;
|
||
m_nBakeDepthType = DT_TERRAIN;
|
||
memset(m_nLayerConvertTable, 0, sizeof(m_nLayerConvertTable));
|
||
}
|
||
|
||
CEtTerrainOpti::~CEtTerrainOpti(void)
|
||
{
|
||
}
|
||
|
||
void CEtTerrainOpti::CheckLayerCount()
|
||
{
|
||
if( m_bProcessLayer )
|
||
{
|
||
return;
|
||
}
|
||
|
||
int i, j;
|
||
int nLayerCount[ 4 ];
|
||
|
||
memset( nLayerCount, 0, sizeof( int ) * 4 );
|
||
for( i = 0; i < ( m_TerrainInfo.nSizeY + 1 ); i++ )
|
||
{
|
||
for( j = 0; j < ( m_TerrainInfo.nSizeX + 1 ); j++ )
|
||
{
|
||
DWORD dwValue = GetLayerValue( j, i );
|
||
if( dwValue & 0xff000000 )
|
||
{
|
||
nLayerCount[ 0 ]++;
|
||
}
|
||
if( dwValue & 0xff0000 )
|
||
{
|
||
nLayerCount[ 1 ]++;
|
||
}
|
||
if( dwValue & 0xff00 )
|
||
{
|
||
nLayerCount[ 2 ]++;
|
||
}
|
||
if( dwValue & 0xff )
|
||
{
|
||
nLayerCount[ 3 ]++;
|
||
}
|
||
}
|
||
}
|
||
|
||
int nCurLayer = 0;
|
||
int nAvailableCount = 0;
|
||
for( i = 0; i < 4; i++ )
|
||
{
|
||
if( nLayerCount[ i ] > 0 )
|
||
{
|
||
m_nLayerConvertTable[ i ] = nCurLayer;
|
||
nCurLayer++;
|
||
nAvailableCount++;
|
||
}
|
||
else
|
||
{
|
||
m_nLayerConvertTable[ i ] = -1;
|
||
}
|
||
}
|
||
|
||
for( i = 0; i < ( m_TerrainInfo.nSizeY + 1 ); i++ )
|
||
{
|
||
for( j = 0; j < ( m_TerrainInfo.nSizeX + 1 ); j++ )
|
||
{
|
||
DWORD dwValue = GetLayerValue( j, i );
|
||
EtColor TestColor( dwValue );
|
||
if( m_nLayerConvertTable[ 2 ] == -1 )
|
||
{
|
||
( ( char * )&dwValue )[ 1 ] = ( ( char * )&dwValue )[ 0 ];
|
||
}
|
||
if( m_nLayerConvertTable[ 1 ] == -1 )
|
||
{
|
||
( ( char * )&dwValue )[ 2 ] = ( ( char * )&dwValue )[ 1 ];
|
||
( ( char * )&dwValue )[ 1 ] = ( ( char * )&dwValue )[ 0 ];
|
||
}
|
||
if( m_nLayerConvertTable[ 0 ] == -1 )
|
||
{
|
||
( ( char * )&dwValue )[ 3 ] = ( ( char * )&dwValue )[ 2 ];
|
||
( ( char * )&dwValue )[ 2 ] = ( ( char * )&dwValue )[ 1 ];
|
||
( ( char * )&dwValue )[ 1 ] = ( ( char * )&dwValue )[ 0 ];
|
||
}
|
||
SetLayerValue( j, i, dwValue );
|
||
}
|
||
}
|
||
|
||
m_nTechniqueIndex = nAvailableCount - 1;
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20>ٲ<EFBFBD><D9B2>ش<EFBFBD>.
|
||
if( nLayerCount[ 3 ] == 0 )
|
||
{
|
||
m_nMaterialName = 3;
|
||
}
|
||
else
|
||
{
|
||
m_nMaterialName = 4;
|
||
}
|
||
m_bProcessLayer = true;
|
||
}
|
||
|
||
bool CEtTerrainOpti::SetTexture( int nTexIndex, const char *pTexName )
|
||
{
|
||
if( m_nLayerConvertTable[ nTexIndex ] == -1 )
|
||
{
|
||
return true;
|
||
}
|
||
return CEtTerrain::SetTexture( m_nLayerConvertTable[ nTexIndex ], pTexName );
|
||
}
|
||
|
||
void CEtTerrainOpti::GenerateTexureCoord()
|
||
{
|
||
if( m_nMaterialName == 3 )
|
||
{
|
||
CEtTerrain::GenerateTexureCoord();
|
||
}
|
||
else
|
||
{
|
||
CEtCliffTerrain::GenerateTexureCoord();
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
// CEtLowSplatTerrain
|
||
/////////////////////////////////////////////////////////////////////////////////////////
|
||
CEtLowSplatTerrain::CEtLowSplatTerrain( void )
|
||
{
|
||
m_nTechniqueIndex = 0;
|
||
|
||
// <20>ܺο<DCBA><CEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ƽ<EFBFBD> <20><><EFBFBD>⼭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4<><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> 2<><32><EFBFBD>̴<EFBFBD>.
|
||
SetTextureLayerCount( 4 );
|
||
m_nMaterialName = 5;
|
||
}
|
||
|
||
CEtLowSplatTerrain::~CEtLowSplatTerrain( void )
|
||
{
|
||
|
||
}
|
||
|
||
void CEtLowSplatTerrain::CreateMaterial( const char* pEffectName )
|
||
{
|
||
// <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20>ؽ<EFBFBD><D8BD><EFBFBD> 2<><32><EFBFBD><EFBFBD> ã<>Ƽ<EFBFBD> 2<>常 <20>ٸ<EFBFBD><D9B8><EFBFBD>.
|
||
char szParamName[ 64 ] = { 0 };
|
||
m_hMaterial = LoadResource( pEffectName, RT_SHADER, true );
|
||
|
||
// <20>ؽ<EFBFBD><D8BD>Ĵ<EFBFBD> 2<>常..
|
||
for( int i = 0; i < 2; i++ )
|
||
{
|
||
if( m_vecTextureDist[ i ] == FLT_MAX )
|
||
{
|
||
m_vecTextureDist[ i ] = m_TerrainInfo.fTileSize / m_TerrainInfo.fTextureDistance;
|
||
}
|
||
}
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_fTextureDistance", &m_vecTextureDist[ 0 ] );
|
||
AddCustomParam( m_vecCustomParam, EPT_FLOAT_PTR, m_hMaterial, "g_fTileSize", &m_TerrainInfo.fTileSize );
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_WorldOffset", &m_TerrainInfo.TerrainOffset );
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_fTextureRotate12", &m_vecTextureRotationParam[ 0 ] );
|
||
AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_fTextureRotate34", &m_vecTextureRotationParam[ 4 ] );
|
||
for( int i = 0; i < 2; i++ )
|
||
{
|
||
int nTexIndex = -1;
|
||
sprintf( szParamName, "g_LayerTex%d", i + 1 );
|
||
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, szParamName, &nTexIndex );
|
||
SetTextureParam( i );
|
||
}
|
||
}
|
||
|
||
bool CEtLowSplatTerrain::SetTexture( int nTexIndex, const char *pTexName )
|
||
{
|
||
if( nTexIndex <= 2 )
|
||
{
|
||
return __super::SetTexture( nTexIndex, pTexName );
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
void CEtLowSplatTerrain::SetTextureDistance( int nTexLayer, float fDistance )
|
||
{
|
||
if( nTexLayer <= 2 )
|
||
__super::SetTextureDistance( nTexLayer, fDistance );
|
||
}
|
||
|
||
void CEtLowSplatTerrain::GenerateVertexBuffer( void )
|
||
{
|
||
// <20><><EFBFBD>ؽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ݸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͵鵵 <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||
int nVertexCount = ( m_TerrainInfo.nSizeX / 2 + 1 ) * ( m_TerrainInfo.nSizeY / 2 + 1 );
|
||
EtVector3 *pPositionNormalBuffer = new EtVector3[ nVertexCount ];
|
||
|
||
int i, j;
|
||
int nSizeX, nSizeY;
|
||
nSizeX = m_TerrainInfo.nSizeX / 2 + 1;
|
||
nSizeY = m_TerrainInfo.nSizeY / 2 + 1;
|
||
for( i = 0; i < nSizeY; i++ )
|
||
{
|
||
for( j = 0; j < nSizeX; j++ )
|
||
{
|
||
pPositionNormalBuffer[ i * nSizeX + j ].x = j * m_TerrainInfo.fTileSize * 2;
|
||
pPositionNormalBuffer[ i * nSizeX + j ].y = GetHeight( j * 2, i * 2 );
|
||
pPositionNormalBuffer[ i * nSizeX + j ].z = i * m_TerrainInfo.fTileSize * 2;
|
||
if( pPositionNormalBuffer[ i * nSizeX + j ].y > m_BoundingBox.Max.y )
|
||
{
|
||
m_BoundingBox.Max.y = pPositionNormalBuffer[ i * nSizeX + j ].y;
|
||
}
|
||
if( pPositionNormalBuffer[ i * nSizeX + j ].y < m_BoundingBox.Min.y )
|
||
{
|
||
m_BoundingBox.Min.y = pPositionNormalBuffer[ i * nSizeX + j ].y;
|
||
}
|
||
}
|
||
}
|
||
|
||
CMemoryStream *pStream = new CMemoryStream( pPositionNormalBuffer, nVertexCount * sizeof( EtVector3 ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_POSITION, 0, nVertexCount );
|
||
delete pStream;
|
||
|
||
SecureZeroMemory( pPositionNormalBuffer, sizeof(EtVector3)*nVertexCount );
|
||
nSizeX = m_TerrainInfo.nSizeX/2 + 1;
|
||
nSizeY = m_TerrainInfo.nSizeY/2 + 1;
|
||
for( i = 0; i < nSizeY; i++ )
|
||
{
|
||
for( j = 0; j < nSizeX; j++ )
|
||
{
|
||
int iBufferPos = i * nSizeX + j;
|
||
if( iBufferPos < nVertexCount )
|
||
{
|
||
pPositionNormalBuffer[ iBufferPos ] = GetVertexNormal( j, i );
|
||
}
|
||
}
|
||
}
|
||
pStream = new CMemoryStream( pPositionNormalBuffer, nVertexCount * sizeof( EtVector3 ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_NORMAL, 0, nVertexCount );
|
||
delete pStream;
|
||
delete [] pPositionNormalBuffer;
|
||
|
||
DWORD* pBuffer = new DWORD[ nVertexCount+1 ];
|
||
for( i = 0; i <= m_TerrainInfo.nSizeY; i += 2 )
|
||
{
|
||
int nVertexOffset = (i/2) * ( m_TerrainInfo.nSizeX/2 + 1 );
|
||
for( j = 0; j <= m_TerrainInfo.nSizeX; j += 2 )
|
||
{
|
||
int iLayerValue = 0;
|
||
if( ( j + m_nBlockOffsetX >= m_nStride ) || ( i + m_nBlockOffsetY >= m_nStrideVert ) )
|
||
{
|
||
iLayerValue = 0;
|
||
}
|
||
else
|
||
{
|
||
iLayerValue = m_TerrainInfo.pLayerDensity[ i * m_nStride + j ];
|
||
}
|
||
|
||
int iBufferPos = nVertexOffset + j/2;
|
||
if( iBufferPos < nVertexCount+1 )
|
||
{
|
||
pBuffer[ iBufferPos ] = ConvertLayerValue( iLayerValue );
|
||
}
|
||
}
|
||
}
|
||
pStream = new CMemoryStream( pBuffer, (nVertexCount+1) * sizeof( DWORD ) );
|
||
m_MeshStream.LoadVertexStream( pStream, MST_COLOR, 0, nVertexCount );
|
||
delete pStream;
|
||
delete [] pBuffer;
|
||
} |