Files
2026-06-01 12:46:52 +02:00

387 lines
9.9 KiB
C++

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