2024-12-21 10:04:04 +08:00
|
|
|
#include "StdAfx.h"
|
|
|
|
|
#include "EtRainDropSplash.h"
|
|
|
|
|
#include "EngineUtil.h"
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern float g_fTotalElapsedTime;
|
|
|
|
|
|
|
|
|
|
CEtRainDropSplash::CEtRainDropSplash(void)
|
|
|
|
|
{
|
|
|
|
|
m_fLifeTime = 0.2f;
|
|
|
|
|
m_fInvLifeTime = 1.0f / m_fLifeTime;
|
|
|
|
|
m_fCreationRadius = 1000.0f;
|
|
|
|
|
m_nSplashPerSecond = 100;
|
|
|
|
|
m_fRemainCreationTime = 0.0f;
|
|
|
|
|
m_nBaseIndex = 0;
|
|
|
|
|
m_nAllocSize = 0;
|
|
|
|
|
m_nPositionParamIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CEtRainDropSplash::~CEtRainDropSplash(void)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::Initialize( const char *pSplashTexture, float fSplashSize )
|
|
|
|
|
{
|
|
|
|
|
int i, nIndexCount, nVertexCount;
|
|
|
|
|
float fHalfSplashSize, fSplashHeight;
|
|
|
|
|
EtVector3 *pvPosition;
|
|
|
|
|
EtVector2 *pTexCoord;
|
|
|
|
|
WORD *pwIndex, *pwVertexIndex;
|
|
|
|
|
|
|
|
|
|
nVertexCount = MAX_RAIN_DROP_SPLASH_COUNT * 4;
|
|
|
|
|
nIndexCount = MAX_RAIN_DROP_SPLASH_COUNT * 6;
|
|
|
|
|
|
|
|
|
|
pvPosition = new EtVector3[ nVertexCount ];
|
|
|
|
|
pTexCoord = new EtVector2[ nVertexCount ];
|
|
|
|
|
pwVertexIndex = new WORD[ nVertexCount * 4 ];
|
|
|
|
|
pwIndex = new WORD[ nIndexCount ];
|
|
|
|
|
|
|
|
|
|
fHalfSplashSize = fSplashSize * 0.5f;
|
|
|
|
|
fSplashHeight = fSplashSize / ( GetEtDevice()->Height() / ( float )GetEtDevice()->Width() );
|
|
|
|
|
for( i = 0; i < MAX_RAIN_DROP_SPLASH_COUNT; i++ )
|
|
|
|
|
{
|
|
|
|
|
pvPosition[ i * 4 ] = EtVector3( -fHalfSplashSize, fSplashHeight, 0.0f );
|
|
|
|
|
pvPosition[ i * 4 + 1 ] = EtVector3( fHalfSplashSize, fSplashHeight, 0.0f );
|
|
|
|
|
pvPosition[ i * 4 + 2 ] = EtVector3( -fHalfSplashSize, 0.0f, 0.0f );
|
|
|
|
|
pvPosition[ i * 4 + 3 ] = EtVector3( fHalfSplashSize, 0.0f, 0.0f );
|
|
|
|
|
|
|
|
|
|
pTexCoord[ i * 4 ] = EtVector2( 0.0f, 0.0f );
|
|
|
|
|
pTexCoord[ i * 4 + 1 ] = EtVector2( 1.0f, 0.0f );
|
|
|
|
|
pTexCoord[ i * 4 + 2 ] = EtVector2( 0.0f, 1.0f );
|
|
|
|
|
pTexCoord[ i * 4 + 3 ] = EtVector2( 1.0f, 1.0f );
|
|
|
|
|
|
|
|
|
|
pwVertexIndex[ i * 4 * 4 ] = i;
|
|
|
|
|
pwVertexIndex[ ( i * 4 + 1 ) * 4 ] = i;
|
|
|
|
|
pwVertexIndex[ ( i * 4 + 2 ) * 4 ] = i;
|
|
|
|
|
pwVertexIndex[ ( i * 4 + 3 ) * 4 ] = i;
|
|
|
|
|
|
|
|
|
|
pwIndex[ i * 6 ] = i * 4;
|
|
|
|
|
pwIndex[ i * 6 + 1 ] = i * 4 + 1;
|
|
|
|
|
pwIndex[ i * 6 + 2 ] = i * 4 + 2;
|
|
|
|
|
pwIndex[ i * 6 + 3 ] = i * 4 + 1;
|
|
|
|
|
pwIndex[ i * 6 + 4 ] = i * 4 + 3;
|
|
|
|
|
pwIndex[ i * 6 + 5 ] = i * 4 + 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CMemoryStream Stream;
|
|
|
|
|
|
|
|
|
|
Stream.Initialize( pvPosition, nVertexCount * sizeof( EtVector3 ) );
|
|
|
|
|
m_MeshStream.LoadVertexStream( &Stream, MST_POSITION, 0, nVertexCount );
|
|
|
|
|
Stream.Initialize( pTexCoord, nVertexCount * sizeof( EtVector2 ) );
|
|
|
|
|
m_MeshStream.LoadVertexStream( &Stream, MST_TEXCOORD, 0, nVertexCount );
|
|
|
|
|
Stream.Initialize( pwVertexIndex, nVertexCount * sizeof( WORD ) * 4 );
|
|
|
|
|
m_MeshStream.LoadVertexStream( &Stream, MST_BONEINDEX, 0, nVertexCount );
|
|
|
|
|
Stream.Initialize( pwIndex, nIndexCount * sizeof( WORD ) );
|
|
|
|
|
m_MeshStream.LoadIndexStream( &Stream, false, nIndexCount );
|
|
|
|
|
|
|
|
|
|
delete [] pvPosition;
|
|
|
|
|
delete [] pTexCoord;
|
|
|
|
|
delete [] pwVertexIndex;
|
|
|
|
|
delete [] pwIndex;
|
|
|
|
|
|
|
|
|
|
int nTexIndex;
|
|
|
|
|
|
|
|
|
|
CalcAllocSize();
|
|
|
|
|
m_hMaterial = LoadResource( "RainDropSplash.fx", RT_SHADER );
|
|
|
|
|
m_hTexture = LoadResource( pSplashTexture, RT_TEXTURE );
|
|
|
|
|
if( m_hTexture )
|
|
|
|
|
{
|
|
|
|
|
nTexIndex = m_hTexture->GetMyIndex();
|
|
|
|
|
AddCustomParam( m_vecCustomParam, EPT_TEX, m_hMaterial, "g_RainDropSplashTex", &nTexIndex );
|
|
|
|
|
}
|
|
|
|
|
m_nPositionParamIndex = AddCustomParam( m_vecCustomParam, EPT_VECTOR_PTR, m_hMaterial, "g_RainDropSplashPos", NULL, MAX_RAIN_DROP_SPLASH_COUNT );
|
|
|
|
|
AddCustomParam( m_vecCustomParam, EPT_FLOAT_PTR, m_hMaterial, "g_fInvLifeTime", &m_fInvLifeTime );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::CalcAllocSize()
|
|
|
|
|
{
|
|
|
|
|
m_nAllocSize = ( int )( m_nSplashPerSecond * m_fLifeTime * 2 );
|
|
|
|
|
m_vecPosition.reserve( m_nAllocSize );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::SetLifeTime( float fLifeTime )
|
|
|
|
|
{
|
|
|
|
|
m_fLifeTime = fLifeTime;
|
|
|
|
|
m_fInvLifeTime = 1.0f / m_fLifeTime;
|
|
|
|
|
CalcAllocSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::SetSplashPerSecond( int nSplash )
|
|
|
|
|
{
|
|
|
|
|
m_nSplashPerSecond = nSplash;
|
|
|
|
|
CalcAllocSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::Process( float fElapsedTime )
|
|
|
|
|
{
|
|
|
|
|
int i, nCreationCount;
|
|
|
|
|
|
|
|
|
|
for( i = m_nBaseIndex; i < ( int )m_vecPosition.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
if( m_vecPosition[ i ].w >= ( g_fTotalElapsedTime - m_fLifeTime ) )
|
|
|
|
|
{
|
|
|
|
|
m_nBaseIndex = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EtCameraHandle hCamera;
|
|
|
|
|
EtVector3 *pvCamPosition, vCenterPosition;
|
|
|
|
|
EtMatrix *pInvViewMat;
|
|
|
|
|
|
|
|
|
|
hCamera = CEtCamera::GetActiveCamera();
|
|
|
|
|
pvCamPosition = hCamera->GetPosition();
|
|
|
|
|
pInvViewMat = hCamera->GetInvViewMat();
|
|
|
|
|
vCenterPosition.x = pvCamPosition->x + pInvViewMat->_31 * ( m_fCreationRadius * 1.0f );
|
|
|
|
|
vCenterPosition.y = pvCamPosition->y + pInvViewMat->_32 * ( m_fCreationRadius * 1.0f );
|
|
|
|
|
vCenterPosition.z = pvCamPosition->z + pInvViewMat->_33 * ( m_fCreationRadius * 1.0f );
|
|
|
|
|
|
|
|
|
|
m_fRemainCreationTime += fElapsedTime;
|
|
|
|
|
nCreationCount = ( int )( m_fRemainCreationTime * m_nSplashPerSecond );
|
|
|
|
|
m_fRemainCreationTime -= nCreationCount / ( float )m_nSplashPerSecond;
|
|
|
|
|
for( i = 0; i < nCreationCount; i++ )
|
|
|
|
|
{
|
|
|
|
|
EtVector4 vSplashPosition;
|
|
|
|
|
EtTerrainHandle hTerrain;
|
|
|
|
|
|
|
|
|
|
if( ( int )m_vecPosition.size() >= m_nAllocSize )
|
|
|
|
|
{
|
|
|
|
|
if( m_nBaseIndex <= 0 )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_vecPosition.erase( m_vecPosition.begin(), m_vecPosition.begin() + m_nBaseIndex );
|
|
|
|
|
m_nBaseIndex = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vSplashPosition.x = RandomNumberInRange( -m_fCreationRadius, m_fCreationRadius ) + vCenterPosition.x;
|
|
|
|
|
vSplashPosition.y = 0.0f;
|
|
|
|
|
vSplashPosition.z = RandomNumberInRange( -m_fCreationRadius, m_fCreationRadius ) + vCenterPosition.z;
|
|
|
|
|
hTerrain = CEtTerrainArea::GetTerrainArea( vSplashPosition.x, vSplashPosition.z );
|
|
|
|
|
if( hTerrain )
|
|
|
|
|
{
|
|
|
|
|
vSplashPosition.y = hTerrain->GetLandHeight( vSplashPosition.x, vSplashPosition.z, NULL );
|
|
|
|
|
}
|
|
|
|
|
vSplashPosition.w = g_fTotalElapsedTime;
|
|
|
|
|
|
|
|
|
|
m_vecPosition.push_back( vSplashPosition );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEtRainDropSplash::Render( float fElapsedTime )
|
|
|
|
|
{
|
|
|
|
|
Process( fElapsedTime );
|
|
|
|
|
|
|
|
|
|
EtMatrix WorldMat;
|
|
|
|
|
int nDrawCount, nCurBaseIndex;
|
|
|
|
|
EtCameraHandle hCamera;
|
|
|
|
|
|
|
|
|
|
nDrawCount = ( int )m_vecPosition.size() - m_nBaseIndex;
|
|
|
|
|
|
|
|
|
|
hCamera = CEtCamera::GetActiveCamera();
|
|
|
|
|
memcpy( &WorldMat, hCamera->GetInvViewMat(), sizeof( EtMatrix ) );
|
|
|
|
|
WorldMat._21 = 0.0f;
|
|
|
|
|
WorldMat._22 = 1.0f;
|
|
|
|
|
WorldMat._23 = 0.0f;
|
|
|
|
|
WorldMat._41 = 0.0f;
|
|
|
|
|
WorldMat._42 = 0.0f;
|
|
|
|
|
WorldMat._43 = 0.0f;
|
|
|
|
|
|
|
|
|
|
nCurBaseIndex = m_nBaseIndex;
|
|
|
|
|
while( nDrawCount > 0 )
|
|
|
|
|
{
|
|
|
|
|
int nDraw;
|
|
|
|
|
if( nDrawCount > MAX_RAIN_DROP_SPLASH_COUNT )
|
|
|
|
|
{
|
|
|
|
|
nDraw = MAX_RAIN_DROP_SPLASH_COUNT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nDraw = nDrawCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vecCustomParam[ m_nPositionParamIndex ].nVariableCount = nDraw;
|
|
|
|
|
if( nDraw <= 1 )
|
|
|
|
|
{
|
|
|
|
|
m_vecCustomParam[ m_nPositionParamIndex ].nVariableCount = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( (int)m_vecPosition.capacity() < m_vecCustomParam[ m_nPositionParamIndex ].nVariableCount + nCurBaseIndex ) {
|
|
|
|
|
_ASSERT( false );
|
|
|
|
|
m_vecPosition.reserve( m_vecCustomParam[ m_nPositionParamIndex ].nVariableCount + nCurBaseIndex );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vecCustomParam[ m_nPositionParamIndex ].pPointer = &m_vecPosition[ nCurBaseIndex ];
|
|
|
|
|
|
|
|
|
|
SRenderStackElement RenderElement;
|
|
|
|
|
|
|
|
|
|
RenderElement.hMaterial = m_hMaterial;
|
|
|
|
|
RenderElement.nTechniqueIndex = 0;
|
|
|
|
|
RenderElement.WorldMat = WorldMat;
|
|
|
|
|
RenderElement.nSaveMatIndex = -1;
|
|
|
|
|
RenderElement.pvecCustomParam = &m_vecCustomParam;
|
|
|
|
|
RenderElement.pRenderMeshStream = &m_MeshStream;
|
|
|
|
|
RenderElement.nDrawCount = nDraw * 2;
|
|
|
|
|
RenderElement.nBakeDepthIndex = DT_NONE;
|
|
|
|
|
GetCurRenderStack()->AddAlphaRenderElement( RenderElement );
|
|
|
|
|
|
|
|
|
|
nDrawCount -= nDraw;
|
|
|
|
|
nCurBaseIndex += nDraw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EtRainDropSplashHandle CEtRainDropSplash::CreateRainDropSplash( const char *pSplashTexture, float fSplashSize )
|
|
|
|
|
{
|
|
|
|
|
CEtRainDropSplash *pSplashEffect;
|
|
|
|
|
|
|
|
|
|
pSplashEffect = new CEtRainDropSplash();
|
|
|
|
|
pSplashEffect->Initialize( pSplashTexture, fSplashSize );
|
|
|
|
|
|
|
|
|
|
return pSplashEffect->GetMySmartPtr();
|
|
|
|
|
}
|