DragonNest/Common/EternityEngine/EtRainDropSplash.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

248 lines
7.3 KiB
C++

#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();
}