📄 particle.cpp
字号:
// Particle.cpp: implementation of the CParticle class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Particle.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const DWORD POINTVERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
D3DXCOLOR g_clrColor[NUM_COLORS] =
{
D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ),
D3DXCOLOR( 1.0f, 0.5f, 0.5f, 1.0f ),
D3DXCOLOR( 0.5f, 1.0f, 0.5f, 1.0f ),
D3DXCOLOR( 0.125f, 0.5f, 1.0f, 1.0f )
};
DWORD g_clrColorFade[NUM_COLORS] =
{
D3DXCOLOR( 1.0f, 0.25f, 0.25f, 1.0f ),
D3DXCOLOR( 1.0f, 0.25f, 0.25f, 1.0f ),
D3DXCOLOR( 0.25f, 0.75f, 0.25f, 1.0f ),
D3DXCOLOR( 0.125f, 0.25f, 0.75f, 1.0f )
};
// Helper function to stuff a FLOAT into a DWORD argument
inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
CParticle::CParticle()
{
m_nParticleCount = 0;
m_pParticles = NULL;
m_pParticlesFree = NULL;
m_pVertexBuffer = NULL;
m_pTexture = NULL;
m_fTestTime = 0.0f;
}
CParticle::~CParticle()
{
while( m_pParticles )
{
PARTICLE* pSpark = m_pParticles;
m_pParticles = pSpark->m_pNext;
delete pSpark;
}
while( m_pParticlesFree )
{
PARTICLE *pSpark = m_pParticlesFree;
m_pParticlesFree = pSpark->m_pNext;
delete pSpark;
}
SAFE_RELEASE( m_pTexture );
SAFE_RELEASE( m_pVertexBuffer );
}
void CParticle::Create( DWORD dwFlush, DWORD dwDiscard, float fRadius )
{
m_fRadius = fRadius;
m_dwBase = dwDiscard;
m_dwFlush = dwFlush;
m_dwDiscard = dwDiscard;
m_dwParticles = 0;
m_dwParticlesLim = 2048;
m_pParticles = NULL;
m_pParticlesFree = NULL;
}
HRESULT CParticle::LoadTexture( char * szFileName )
{
HRESULT hr = S_OK;
// Create the texture using D3DX
if( FAILED( hr = D3DXCreateTextureFromFileEx( g_pApp->GetD3dDevice(), ".\\data\\Game\\Effect\\Particle.bmp",
D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
MEMORY_POOL, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR,
D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0, NULL, NULL, &m_pTexture ) ) )
return hr;
CreateVertexBuffer();
return S_OK;
}
HRESULT CParticle::CreateVertexBuffer()
{
if(FAILED( g_pApp->GetD3dDevice()->CreateVertexBuffer(m_dwDiscard* sizeof(POINTVERTEX),
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY|D3DUSAGE_POINTS,
POINTVERTEX::FVF,D3DPOOL_DEFAULT, &m_pVertexBuffer, NULL) ))
{
OutputDebugString("[角菩] CMD3Mesh::CreateVertexBuffer");
return E_FAIL;
}
/*
POINTVERTEX *pVertex=NULL;
if( FAILED( m_pVertexBuffer->Lock(0,0, (void **)&pVertex, D3DLOCK_DISCARD) ))
return E_FAIL;
for( int i=0; i<m_nParticleCount; i++) // 鞘夸 茄 何盒父 ..
{
// D3DXVECTOR3 vVector = m_pMCVertex[i].vVector;
// D3DXVec3TransformCoord(&vVector,&vVector,&m_matLocalTM);
// pVertex[i].vVector = vVector;
//
// pVertex[i].vNoraml = m_pMCVertex[i].vNoraml;
// pVertex[i].Tex = m_pMCVertex[i].Tex;
}
if( FAILED( m_pVertexBuffer->Unlock() ) )
return E_FAIL;
*/
return S_OK;
}
void CParticle::Update( FLOAT fSecsPerFrame )
{
// float sx = (float)(rand()%30)/10.0f;
// float sz = (float)(rand()%30)/10.0f;
// D3DXVECTOR3 vEmitterPostion( sx, 0.0f, sz );
D3DXVECTOR3 vEmitterPostion( 2.0f, 0.0f, 2.0f );
D3DXVECTOR3 vPosition = vEmitterPostion;
// FLOAT fSecsPerFrame = 10.0f;
DWORD dwNumParticlesToEmit = 10;
D3DXCOLOR clrEmitColor = g_clrColor[2];
D3DXCOLOR clrFadeColor = g_clrColorFade[1];
float fEmitVel = 8.0f;
PARTICLE *pParticle, **ppParticle;
static float fTime = 0.0f;
fTime += fSecsPerFrame;
ppParticle = &m_pParticles;
while( *ppParticle )
{
pParticle = *ppParticle;
// Calculate new position
float fT = fTime - pParticle->m_fTime0;
float fGravity;
if( pParticle->m_bSpark )
{
fGravity = -5.0f;
pParticle->m_fFade -= fSecsPerFrame * 2.25f;
}
else
{
fGravity = -9.8f;
pParticle->m_fFade -= fSecsPerFrame * 0.25f;
}
pParticle->m_vPos = pParticle->m_vVel0 * fT + pParticle->m_vPos0;
pParticle->m_vPos.y += (0.5f * fGravity) * (fT * fT);
// pParticle->m_vPos = vPosition;
// pParticle->m_vPos.y = 2.0f;
pParticle->m_vVel.y = pParticle->m_vVel0.y + fGravity * fT;
if( pParticle->m_fFade < 0.0f )
pParticle->m_fFade = 0.0f;
// Kill old particles
if( pParticle->m_vPos.y < m_fRadius ||
pParticle->m_bSpark && pParticle->m_fFade <= 0.0f )
{
// Emit sparks
if( !pParticle->m_bSpark )
{
for( int i=0; i<4; i++ )
{
PARTICLE *pSpark;
if( m_pParticlesFree )
{
pSpark = m_pParticlesFree;
m_pParticlesFree = pSpark->m_pNext;
}
else
{
if( NULL == ( pSpark = new PARTICLE ) )
return;
}
pSpark->m_pNext = pParticle->m_pNext;
pParticle->m_pNext = pSpark;
pSpark->m_bSpark = TRUE;
pSpark->m_vPos0 = pParticle->m_vPos;
pSpark->m_vPos0.y = m_fRadius;
FLOAT fRand1 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 2.00f;
FLOAT fRand2 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 0.25f;
pSpark->m_vVel0.x = pParticle->m_vVel.x * 0.25f + cosf(fRand1) * sinf(fRand2);
pSpark->m_vVel0.z = pParticle->m_vVel.z * 0.25f + sinf(fRand1) * sinf(fRand2);
pSpark->m_vVel0.y = cosf(fRand2);
pSpark->m_vVel0.y *= ((FLOAT)rand()/(FLOAT)RAND_MAX) * 1.5f;
pSpark->m_vPos = pSpark->m_vPos0;
pSpark->m_vVel = pSpark->m_vVel0;
D3DXColorLerp( &pSpark->m_clrDiffuse, &pParticle->m_clrFade,
&pParticle->m_clrDiffuse, pParticle->m_fFade );
pSpark->m_clrFade = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
pSpark->m_fFade = 1.0f;
pSpark->m_fTime0 = fTime;
}
}
// Kill particle
*ppParticle = pParticle->m_pNext;
pParticle->m_pNext = m_pParticlesFree;
m_pParticlesFree = pParticle;
if(!pParticle->m_bSpark)
m_dwParticles--;
}
else
{
ppParticle = &pParticle->m_pNext;
}
}
// Emit new particles
DWORD dwParticlesEmit = m_dwParticles + dwNumParticlesToEmit;
while( m_dwParticles < m_dwParticlesLim && m_dwParticles < dwParticlesEmit )
{
if( m_pParticlesFree )
{
pParticle = m_pParticlesFree;
m_pParticlesFree = pParticle->m_pNext;
}
else
{
if( NULL == ( pParticle = new PARTICLE ) )
return;
}
pParticle->m_pNext = m_pParticles;
m_pParticles = pParticle;
m_dwParticles++;
// Emit new particle
FLOAT fRand1 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 2.0f;
FLOAT fRand2 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 0.25f;
pParticle->m_bSpark = FALSE;
pParticle->m_vPos0 = vPosition + D3DXVECTOR3( 0.0f, m_fRadius, 0.0f );
pParticle->m_vVel0.x = cosf(fRand1) * sinf(fRand2) * 2.5f;
pParticle->m_vVel0.z = sinf(fRand1) * sinf(fRand2) * 2.5f;
pParticle->m_vVel0.y = cosf(fRand2);
pParticle->m_vVel0.y *= ((FLOAT)rand()/(FLOAT)RAND_MAX) * fEmitVel;
pParticle->m_vPos = pParticle->m_vPos0;
pParticle->m_vVel = pParticle->m_vVel0;
pParticle->m_clrDiffuse = clrEmitColor;
pParticle->m_clrFade = clrFadeColor;
pParticle->m_fFade = 1.0f;
pParticle->m_fTime0 = fTime;
}
}
void CParticle::Render()
{
m_fTestTime = 0.01f;
Update(m_fTestTime);
// m_fAddTime+=0.1f;
// if(m_fTestTime > 150.0f)
// m_fTestTime = 0.0f;
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
g_pApp->GetD3dDevice()->SetTransform( D3DTS_WORLD, &matWorld );
////////////////////////////////////////////////////
//D3DXVec3Project()
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
//
// // Enable alpha testing (skips pixels with less than a certain alpha.)
//// if( m_d3dCaps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL )
// {
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHAREF, 0x08 );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
// }
//
///////////////////////////////////
g_pApp->GetD3dDevice()->SetTexture(0, m_pTexture );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
// g_pApp->GetD3dDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSCALEENABLE, TRUE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSIZE, FtoDW(0.08f) );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.00f) );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSCALE_A, FtoDW(0.00f) );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSCALE_B, FtoDW(0.00f) );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSCALE_C, FtoDW(1.00f) );
g_pApp->GetD3dDevice()->SetStreamSource( 0, m_pVertexBuffer, 0, sizeof(POINTVERTEX) );
g_pApp->GetD3dDevice()->SetFVF( POINTVERTEX::FVF );
// Loop through and render all trees
// g_pApp->GetD3dDevice()->SetStreamSource( 0, m_pVertexBuffer, 0, m_nParticleCount * sizeof(POINTVERTEX) );
PARTICLE* pParticle = m_pParticles;
POINTVERTEX* pVertices;
DWORD dwNumParticlesToRender = 0;
m_dwBase += m_dwFlush;
if(m_dwBase >= m_dwDiscard)
m_dwBase = 0;
if( FAILED(m_pVertexBuffer->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),
(void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) )
{
return;
}
// D3DXVECTOR3 vPos(2.0f,1.0f,2.0f);
// pVertices->v = vPos;
// pVertices->color = 0xFFFF00FF;
//
// if(FAILED(g_pApp->GetD3dDevice()->DrawPrimitive( D3DPT_POINTLIST, 0, 1)))
// return;
/* */
while( pParticle )
{
D3DXVECTOR3 vPos(pParticle->m_vPos);
D3DXVECTOR3 vVel(pParticle->m_vVel);
FLOAT fLengthSq = D3DXVec3LengthSq(&vVel);
UINT dwSteps;
if( fLengthSq < 1.0f ) dwSteps = 2;
else if( fLengthSq < 4.00f ) dwSteps = 3;
else if( fLengthSq < 9.00f ) dwSteps = 4;
else if( fLengthSq < 12.25f ) dwSteps = 5;
else if( fLengthSq < 16.00f ) dwSteps = 6;
else if( fLengthSq < 20.25f ) dwSteps = 7;
else dwSteps = 8;
vVel *= -0.04f / (FLOAT)dwSteps;
D3DXCOLOR clrDiffuse;
D3DXColorLerp(&clrDiffuse, &pParticle->m_clrFade, &pParticle->m_clrDiffuse, pParticle->m_fFade);
DWORD dwDiffuse = (DWORD) clrDiffuse;
// Render each particle a bunch of times to get a blurring effect
for( DWORD i = 0; i < dwSteps; i++ )
{
pVertices->v = vPos;
pVertices->color = dwDiffuse;
pVertices++;
if( ++dwNumParticlesToRender == m_dwFlush )
{
// Done filling this chunk of the vertex buffer. Lets unlock and
// draw this portion so we can begin filling the next chunk.
m_pVertexBuffer->Unlock();
if(FAILED(g_pApp->GetD3dDevice()->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender)))
return;
// Lock the next chunk of the vertex buffer. If we are at the
// end of the vertex buffer, DISCARD the vertex buffer and start
// at the beginning. Otherwise, specify NOOVERWRITE, so we can
// continue filling the VB while the previous chunk is drawing.
m_dwBase += m_dwFlush;
if(m_dwBase >= m_dwDiscard)
m_dwBase = 0;
if( FAILED(m_pVertexBuffer->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),
(void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) )
{
return;
}
dwNumParticlesToRender = 0;
}
vPos += vVel;
}
pParticle = pParticle->m_pNext;
}
// Unlock the vertex buffer
m_pVertexBuffer->Unlock();
// Render any remaining particles
if( dwNumParticlesToRender )
{
if(FAILED(g_pApp->GetD3dDevice()->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender )))
return;
}
/** /
g_pApp->GetD3dDevice()->SetStreamSource( 0, m_pVertexBuffer, 0, sizeof(POINTVERTEX) );
g_pApp->GetD3dDevice()->SetFVF( POINTVERTEX::FVF );
// g_pApp->GetD3dDevice()->SetTexture( 0, m_pTreeTextures[m_Trees[i].dwTreeTexture] );
// Translate the billboard into place
// m_matBillboardMatrix._41 = m_Trees[i].vPos.x;
// m_matBillboardMatrix._42 = m_Trees[i].vPos.y;
// m_matBillboardMatrix._43 = m_Trees[i].vPos.z;
// 夸扁辑 局聪皋捞拣 贸府 窍伙..
D3DXMATRIX mBillboard = g_pCamera->GetBillboardMatrix();
g_pApp->GetD3dDevice()->SetTransform( D3DTS_WORLD, &mBillboard );
// g_pApp->GetD3dDevice()->DrawPrimitive( D3DPT_TRIANGLESTRIP, m_Trees[i].dwOffset, 2 );
*/
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
g_pApp->GetD3dDevice()->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -