#include "stdafx.h" #include "SGameWeatherFx.h" #include "KRenderDeviceDX.h" #include "KResourceManager.h" #include "KRenderObject.h" #include "SGame.h" namespace { const int c_nSnowParticleNum = 1000; const int c_nRainParticleNum = 1000; float RandomNumber(float fMin, float fMax) { if (fMin == fMax) return(fMin); float fRandom = (float)rand() / (float)RAND_MAX; return((fRandom * (float)fabs(fMax-fMin))+fMin); }; K3DVector RandomNumber(K3DVector vMin, K3DVector vMax) { float x = RandomNumber(vMin.x, vMax.x); float y = RandomNumber(vMin.y, vMax.y); float z = RandomNumber(vMin.z, vMax.z); return(K3DVector(x,y,z)); }; } //////////////////////////////////////////////////////// ///////날씨 효과 SGameWeatherFx::SGameWeatherFx() : m_pVertexBuffer( NULL ), m_pIndexBuffer( NULL ), m_pWtParticle( NULL ), m_nParticleNum( 0 ), m_nParticlesToRender( 0 ), m_nUsedElements( 0 ), m_dwOldTime( 0 ), m_pNatureInfo( NULL ) { m_dwDeadTime = 0; m_vWidth = K3DPoint( 0.5f, 1.5f ); m_vHeight = K3DPoint( 0.5f, 1.5f ); m_fGravity = -1.0f; m_vMinDir = K3DVector( 0.0f, 0.0f, 0.0f ); m_vMaxDir = K3DVector( 1.0f, 1.0f, 0.0f ); m_vPosition = K3DVector( 0.0f, 0.0f, 200.0f ); m_vEmitRadius = K3DVector( 200.0f, 200.0f, 0.0f ); m_vEmitRate = K3DPoint( 10.0f, 15.0f ); m_nCreateInterval = 100; } SGameWeatherFx::~SGameWeatherFx() { SAFE_DELETE_ARRAY( m_pVertexBuffer ); SAFE_DELETE_ARRAY( m_pIndexBuffer ); SAFE_DELETE_ARRAY( m_pWtParticle ); SAFE_DELETE( m_pNatureInfo ); m_pGame = NULL; } void SGameWeatherFx::Initialize( SGame* pGame ) { m_pGame = pGame; m_pWtParticle = new WeatherParticle[m_nParticleNum]; m_pVertexBuffer = new K3DSPRITEVERTEX[m_nParticleNum*4]; m_pIndexBuffer = new WORD[m_nParticleNum*6]; for(int i = 0; i < m_nParticleNum; ++i ) { m_pVertexBuffer[i*4].texel = K3DTexel( 0.0f, 0.0f ); m_pVertexBuffer[i*4+1].texel = K3DTexel( 1.0f, 0.0f ); m_pVertexBuffer[i*4+2].texel = K3DTexel( 0.0f, 1.0f ); m_pVertexBuffer[i*4+3].texel = K3DTexel( 1.0f, 1.0f ); for( int x = 0; x < 4; ++x ) { m_pVertexBuffer[i*4+x].diffuse = KColor( 255, 255, 255, 64 ); } m_pIndexBuffer[i*6] = (unsigned short)(i*4+2); m_pIndexBuffer[i*6+1] = (unsigned short)(i*4+1); m_pIndexBuffer[i*6+2] = (unsigned short)(i*4+0); m_pIndexBuffer[i*6+3] = (unsigned short)(i*4+1); m_pIndexBuffer[i*6+4] = (unsigned short)(i*4+2); m_pIndexBuffer[i*6+5] = (unsigned short)(i*4+3); } SetTransparent( true ); SetBlendMode( K3DMaterial::MBM_ADDITIVE ); m_nEmitRate = (int)RandomNumber( m_vEmitRate.x, m_vEmitRate.y ); m_pNatureInfo = new NatureInfo; m_pNatureInfo->m_vWind = K3DVector( 1.0f, 0.0f, 0.0f ); m_pNatureInfo->m_fWindSpeed = 1.0f; m_pNatureInfo->m_fGravity = -3.0f; m_pNatureInfo->m_fAcceleration = 1.0f; } void SGameWeatherFx::Render( KViewportObject *viewport, class K3DRenderDevice *dev, bool bUseAccum ) { if( m_nUsedElements <= 0 ) return; int nRenderToParticle = 0; for( int nParticle = 0; nParticle < m_nParticleNum; ++nParticle ) { WeatherParticle & particle = m_pWtParticle[nParticle]; if( particle.IsAlive() ) { float fWidth = particle.GetWidth(); float fHeight = particle.GetHeight(); const K3DVector* vPos = particle.GetPosition(); K3DMatrix matTrans; K3DMatrixTranslation( matTrans, vPos->x, vPos->y, vPos->z ); matTrans = matTrans * m_RootMat; m_matBillBoard._41 = matTrans._41; m_matBillBoard._42 = matTrans._42; m_matBillBoard._43 = matTrans._43; static const float square[4][2] = { {-1.f, 1.f} , {1.f, 1.f}, {-1.f, -1.f }, {1.f, -1.f} }; for( int x = 0; x < 4; ++x ) { m_pVertexBuffer[nRenderToParticle*4+x].pos.x = square[x][0] * fWidth; m_pVertexBuffer[nRenderToParticle*4+x].pos.y = 0.0f; m_pVertexBuffer[nRenderToParticle*4+x].pos.z = square[x][1] * fHeight; K3DVectorTransform( m_pVertexBuffer[nRenderToParticle*4+x].pos, m_pVertexBuffer[nRenderToParticle*4+x].pos, m_matBillBoard ); } ++nRenderToParticle; if( m_nUsedElements <= nRenderToParticle ) break; } } m_nParticlesToRender = nRenderToParticle; K3DMatrix matWorld; K3DMatrixIdentity( matWorld ); // matWorld = m_matBillBoard * m_RootMat; dev->SetTransform( K3DRenderDevice::TS_WORLD, &matWorld ); dev->SetTexture( 0, m_spTexture ); dev->SetCullMode( K3DRenderDevice::KCM_NONE ); dev->DrawTriangles( K3DFVF_SPRITE, m_pVertexBuffer, m_nParticlesToRender * 4, sizeof(K3DSPRITEVERTEX), m_pIndexBuffer, m_nParticlesToRender * 6); dev->SetCullMode( K3DRenderDevice::KCM_CCW ); } void SGameWeatherFx::SetPositioin( K3DVector & vPosition ) { m_vPosition = vPosition; } void SGameWeatherFx::SetEmitRadius( K3DVector & vEmitRadius ) { m_vEmitRadius = vEmitRadius; } void SGameWeatherFx::SetEmitRate( float fMin, float fMax ) { m_vEmitRate.x = fMin; m_vEmitRate.y = fMax; m_nEmitRate = (int)RandomNumber( m_vEmitRate.x, m_vEmitRate.y ); } void SGameWeatherFx::SetWidth( float fMin, float fMax ) { m_vWidth.x = fMin; m_vWidth.y = fMax; } void SGameWeatherFx::SetHeight( float fMin, float fMax ) { m_vHeight.x = fMin; m_vHeight.y = fMax; } //////////////////////////////////////////////////////// ///////눈 효과 SGameSnowFx::SGameSnowFx() { m_vWidth = K3DPoint( 0.5f, 0.5f ); m_vHeight = m_vWidth; } SGameSnowFx::~SGameSnowFx() { } void SGameSnowFx::Initialize( SGame* pGame ) { m_nParticleNum = c_nSnowParticleNum; NX3LoadPack loadpack; loadpack.Init(); m_spTexture = KTextureManager::GetManager()->GetTexture( "d001_dun_d001_p_magicalpowers_fx01.dds", &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); SGameWeatherFx::Initialize( pGame ); } void SGameSnowFx::Process( DWORD dwTime, K3DVector & vCurPos ) { if( m_dwOldTime == 0 ) { m_dwOldTime = dwTime; return; } int nNewParticle = 0; DWORD dwDelay = dwTime - m_dwOldTime ; if( (int)dwDelay > m_nCreateInterval ) { nNewParticle = (int)(dwDelay / m_nCreateInterval) * m_nEmitRate; m_dwOldTime = dwTime; } for( int nParticle = 0; nParticle < m_nParticleNum; ++nParticle ) { WeatherParticle & particle = m_pWtParticle[nParticle]; if( !particle.IsAlive() ) { K3DVector vPos = m_vPosition + RandomNumber( -m_vEmitRadius, m_vEmitRadius ); particle.SetPosition( vPos ); particle.SetWidth( RandomNumber( m_vWidth.x, m_vWidth.y ) ); particle.SetHeight( RandomNumber( m_vHeight.x, m_vHeight.y ) ); particle.SetLifeTime( 8000 ); particle.New(); ++m_nUsedElements; if( --nNewParticle <= 0 ) break; } } int nUsedElements = m_nUsedElements; for( int nParticle = 0; nParticle < m_nParticleNum; ++nParticle ) { WeatherParticle & particle = m_pWtParticle[nParticle]; if( particle.IsAlive() ) { if( !particle.Update( dwDelay, *m_pNatureInfo ) ) { particle.Delete(); --m_nUsedElements; } if( --nUsedElements <= 0 ) break; } } K3DMatrix matWorld; K3DMatrixTranslation( matWorld, vCurPos.x, vCurPos.y, vCurPos.z ); SetRootMat( &matWorld ); SetCenterPosition( vCurPos ); } void SGameSnowFx::RenderWeatherFx( KViewportObject *viewport ) { K3DMatrix matTransPos; K3DMatrixIdentity( m_matBillBoard ); K3DMatrixTranspose( matTransPos, *viewport->GetViewMatrix() ); m_matBillBoard._11 = matTransPos._11; m_matBillBoard._12 = matTransPos._12; m_matBillBoard._13 = matTransPos._13; m_matBillBoard._21 = matTransPos._31; m_matBillBoard._22 = matTransPos._32; m_matBillBoard._23 = matTransPos._33; m_matBillBoard._31 = matTransPos._21; m_matBillBoard._32 = matTransPos._22; m_matBillBoard._33 = matTransPos._23; viewport->Register( this, KRenderObject::RENDEREFX_NONE ); } //////////////////////////////////////////////////////// ///////비 효과 SGameRainFx::SGameRainFx() { m_fGravity = -3.0f; m_vEmitRate = K3DPoint( 10.0f, 15.0f ); m_vWidth = K3DPoint( 0.03f, 0.02f ); m_vHeight = K3DPoint( 5.0f, 5.0f ); } SGameRainFx::~SGameRainFx() { } void SGameRainFx::Initialize( SGame* pGame ) { m_nParticleNum = c_nRainParticleNum; NX3LoadPack loadpack; loadpack.Init(); m_spTexture = KTextureManager::GetManager()->GetTexture( "p.bmp", &loadpack, true, KTextureManager::GetManager()->GetMipMapBiasLevel() ); SGameWeatherFx::Initialize( pGame ); } void SGameRainFx::Process( DWORD dwTime, K3DVector & vCurPos ) { if( m_dwOldTime == 0 ) { m_dwOldTime = dwTime; return; } int nNewParticle = 0; DWORD dwDelay = dwTime - m_dwOldTime ; if( (int)dwDelay > m_nCreateInterval ) { nNewParticle = (int)(dwDelay / m_nCreateInterval) * m_nEmitRate; m_dwOldTime = dwTime; } for( int nParticle = 0; nParticle < m_nParticleNum; ++nParticle ) { WeatherParticle & particle = m_pWtParticle[nParticle]; if( !particle.IsAlive() ) { K3DVector vPos = m_vPosition + RandomNumber( -m_vEmitRadius, m_vEmitRadius ); particle.SetPosition( vPos ); particle.SetWidth( RandomNumber( m_vWidth.x, m_vWidth.y ) ); particle.SetHeight( RandomNumber( m_vHeight.x, m_vHeight.y ) ); particle.SetLifeTime( 2000 ); particle.New(); ++m_nUsedElements; if( --nNewParticle <= 0 ) break; } } int nUsedElements = m_nUsedElements; for( int nParticle = 0; nParticle < m_nParticleNum; ++nParticle ) { WeatherParticle & particle = m_pWtParticle[nParticle]; if( particle.IsAlive() ) { if( !particle.Update( dwDelay, *m_pNatureInfo ) ) { particle.Delete(); --m_nUsedElements; } if( --nUsedElements <= 0 ) break; } } K3DMatrix matWorld; K3DMatrixTranslation( matWorld, vCurPos.x, vCurPos.y, vCurPos.z ); SetRootMat( &matWorld ); SetCenterPosition( vCurPos ); } void SGameRainFx::RenderWeatherFx( KViewportObject *viewport ) { K3DMatrix matTransPos; K3DMatrixIdentity( m_matBillBoard ); K3DMatrixTranspose( matTransPos, *viewport->GetViewMatrix() ); m_matBillBoard._11 = matTransPos._11; m_matBillBoard._12 = matTransPos._12; m_matBillBoard._21 = matTransPos._21; m_matBillBoard._22 = matTransPos._22; viewport->Register( this, KRenderObject::RENDEREFX_NONE ); }