700 lines
20 KiB
C++
700 lines
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;
|
|||
|
|
}
|