Beispiel #1
0
void CParticleSystemManager :: UpdateSystems( void )
{
	float		frametime;
	static int	framecount = -1;
	AURSTATE		state;

	// HACKHACK: don't evaluate particles when executes many times at same frame
	// e.g. mirror rendering
	if( framecount != tr.realframecount )
	{
		frametime = RI.refdef.frametime;
		framecount = tr.realframecount;
	}
	else frametime = 0.0f;
	
	CParticleSystem *pSystem;
	CParticleSystem *pLast = NULL;

	pSystem = m_pFirstSystem;

	while( pSystem )
	{
		state = pSystem->UpdateSystem( frametime );

		if( state != AURORA_REMOVE )
		{
			if( state == AURORA_DRAW )
				pSystem->DrawSystem();

			pLast = pSystem;
			pSystem = pSystem->m_pNextSystem;
		}
		else
		{
			// delete this system
			if( pLast )
			{
				pLast->m_pNextSystem = pSystem->m_pNextSystem;
				delete pSystem;
				pSystem = pLast->m_pNextSystem;
			}
			else
			{
				// deleting the first system
				m_pFirstSystem = pSystem->m_pNextSystem;
				delete pSystem;
				pSystem = m_pFirstSystem;
			}
		}
	}

	gEngfuncs.pTriAPI->RenderMode(kRenderNormal);
}
// updates all systems
void CParticleSystemManager::UpdateSystems( void )
{
	CParticleSystem *pSystem = NULL;
	signed int i = 0;
	signed int iSystems = (signed)m_pParticleSystems.size();
	// iterate through all the particle systems, drawing each
	for (; i < iSystems; i++)
	{
		pSystem = m_pParticleSystems[i];
		// remove the system if the system requests it
		if( pSystem && pSystem->DrawSystem() == false)
		{
			delete pSystem;
			m_pParticleSystems.erase((m_pParticleSystems.begin() + i));
			i--;
			iSystems--;
		}
	}

	// we couldn't return earlier as we need to have the sorting before the ps updating
	// however no sorting when we can't see the particles
	if(CheckDrawSystem() == false)
		return;

	int iParticles = m_pParticles.size();
	if(iParticles > 1) {
		// calculate the fraction of a second between sorts
		float flTimeSinceLastSort = (gEngfuncs.GetClientTime() - m_flLastSort);
		// 1 / time between sorts will give us a number like 5
		// if it is less than the particlesorts cvar then it is a small value 
		// and therefore a long time since last sort
		if((((int)(1 / flTimeSinceLastSort)) < g_ParticleSorts->value)) {
			m_flLastSort = gEngfuncs.GetClientTime();
			std::sort(m_pParticles.begin(), m_pParticles.end(), less_than);
		}
	}

	if(iParticles > 0) {
		// prepare opengl
		Particle_InitOpenGL();

		float flTimeSinceLastDraw = TimeSinceLastDraw();
		// loop through all particles drawing them
		// they have already been tested and updated in their pss' draw sys func
		// we've reversed the greater than order, so that oldest particles are at 0
		// further away particles and recently added particles get drawn first
		CParticle *pParticle = NULL;
		for(i = 0; i < iParticles ; i++)
		{
			if(m_pParticles[i]) {
				pParticle = m_pParticles[i];
				if(pParticle && pParticle->Test()) {
					pParticle->Update(flTimeSinceLastDraw);
					if(g_iUser1 != OBS_MAP_FREE && g_iUser1 != OBS_MAP_CHASE) {
						// unfortunately we have to prepare every particle now
						// as we can't prepare for a batch of the same type anymore
						pParticle->Prepare(); 
						pParticle->Draw();
					}
				} else {
					RemoveParticle(pParticle);
					i--;
					iParticles--;
				}
			}
		}
		Particle_FinishOpenGL();
	}

	// print out how fast we've been drawing the systems in debug mode
	if (g_ParticleDebug->value != 0 && ((m_flLastSort + 0.5) <= gEngfuncs.GetClientTime()))
	{
		gEngfuncs.Con_Printf("%i Particles Drawn this pass in %i systems ", m_pParticles.size(), m_pParticleSystems.size());
		gEngfuncs.Con_Printf("%i Textures in Cache\n\0", m_pTextures.size());
	}

	m_flLastDraw = gEngfuncs.GetClientTime();
}