⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 particle.cpp

📁 国外网游源码....除工具源码缺少之外,其余程序都全...至于,什么游戏,因为国内还没有,所以找不到测试
💻 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 + -