forked from mirrors/0ad
Delete non-working particle system code
This was SVN commit r9147.
This commit is contained in:
@@ -1,72 +0,0 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Default particle emitter implementation.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "DefaultEmitter.h"
|
||||
|
||||
CDefaultEmitter::CDefaultEmitter(const int MAX_PARTICLES, const int lifetime) : CEmitter(MAX_PARTICLES, lifetime)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
CDefaultEmitter::~CDefaultEmitter(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool CDefaultEmitter::Setup()
|
||||
{
|
||||
// XYZ Position
|
||||
m_pos.X = 0.0f;
|
||||
m_pos.Y = 20.0f;
|
||||
m_pos.Z = 0.0f;
|
||||
|
||||
m_yaw = DEGTORAD(0.0f);
|
||||
m_yawVar = DEGTORAD(360.0f);
|
||||
m_pitch = DEGTORAD(90.0f);
|
||||
m_pitchVar = DEGTORAD(45.0f);
|
||||
m_speed = 0.05f;
|
||||
m_speedVar = 0.001f;
|
||||
|
||||
m_blendMode = 1;
|
||||
m_particleCount = 0;
|
||||
m_emitsPerFrame = 100;
|
||||
m_emitsVar = 15;
|
||||
m_life = 90;
|
||||
m_lifeVar = 65;
|
||||
m_startColor.r = 100;
|
||||
m_startColor.g = 100;
|
||||
m_startColor.b = 100;
|
||||
m_startColorVar.r = 15;
|
||||
m_startColorVar.g = 15;
|
||||
m_startColorVar.b = 15;
|
||||
m_endColor.r = 0;
|
||||
m_endColor.g = 0;
|
||||
m_endColor.b = 0;
|
||||
m_endColorVar.r = 15;
|
||||
m_endColorVar.g = 15;
|
||||
m_endColorVar.b = 15;
|
||||
|
||||
m_force.X = 0.000f;
|
||||
m_force.Y = 0.001f;
|
||||
m_force.Z = 0.0f;
|
||||
return true;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/* Copyright (C) 2009 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Default particle emitter implementation.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_DEFAULTEMITTER
|
||||
#define INCLUDED_DEFAULTEMITTER
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
|
||||
class CDefaultEmitter : public CEmitter
|
||||
{
|
||||
public:
|
||||
CDefaultEmitter(const int MAX_PARTICLES = 4000, const int lifetime = -1);
|
||||
virtual ~CDefaultEmitter(void);
|
||||
|
||||
// Sets up emitter to the default particle effect.
|
||||
virtual bool Setup();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,556 +0,0 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Particle and Emitter base classes.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
|
||||
#include "ParticleEngine.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "ps/Filesystem.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
|
||||
//forward declaration
|
||||
void GetValueAndVariation(CXeromyces XeroFile, XMBElement parent, CStr& value, CStr& variation);
|
||||
|
||||
CEmitter::CEmitter(const int MAX_PARTICLES, const int lifetime, int UNUSED(textureID))
|
||||
{
|
||||
m_particleCount = 0;
|
||||
// declare the pool of nodes
|
||||
m_maxParticles = MAX_PARTICLES;
|
||||
m_heap = new tParticle[m_maxParticles];
|
||||
m_emitterLife = lifetime;
|
||||
m_decrementLife = true;
|
||||
m_decrementAlpha = true;
|
||||
m_renderParticles = true;
|
||||
isFinished = false;
|
||||
|
||||
// init the used/open list
|
||||
m_usedList = NULL;
|
||||
m_openList = NULL;
|
||||
|
||||
// link all the particles in the heap
|
||||
// into one large open list
|
||||
for(int i = 0; i < m_maxParticles - 1; i++)
|
||||
{
|
||||
m_heap[i].next = &(m_heap[i + 1]);
|
||||
}
|
||||
m_openList = m_heap;
|
||||
}
|
||||
|
||||
CEmitter::~CEmitter(void)
|
||||
{
|
||||
delete [] m_heap;
|
||||
}
|
||||
|
||||
bool CEmitter::LoadXml(const VfsPath& pathname)
|
||||
{
|
||||
CXeromyces XeroFile;
|
||||
if (XeroFile.Load(g_VFS, pathname) != PSRETURN_OK)
|
||||
// Fail
|
||||
return false;
|
||||
|
||||
// Define all the elements and attributes used in the XML file
|
||||
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
|
||||
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
|
||||
// Only the ones we can't load using normal methods.
|
||||
EL(Emitter);
|
||||
AT(Type);
|
||||
EL(Lifetime);
|
||||
EL(Particles);
|
||||
AT(MaxNumber);
|
||||
EL(EmitsPerFrame);
|
||||
EL(Texture);
|
||||
EL(Size);
|
||||
EL(Value);
|
||||
EL(Variation);
|
||||
EL(Color);
|
||||
EL(Start);
|
||||
EL(End);
|
||||
AT(r);
|
||||
AT(g);
|
||||
AT(b);
|
||||
EL(Alpha);
|
||||
AT(BlendMode);
|
||||
AT(Decrement);
|
||||
EL(Direction);
|
||||
EL(Yaw);
|
||||
EL(Pitch);
|
||||
EL(Speed);
|
||||
EL(Life);
|
||||
EL(Force);
|
||||
EL(X);
|
||||
EL(Y);
|
||||
EL(Z);
|
||||
#undef AT
|
||||
#undef EL
|
||||
|
||||
XMBElement root = XeroFile.GetRoot();
|
||||
|
||||
if( root.GetNodeName() != el_Emitter )
|
||||
{
|
||||
LOGERROR(L"CEmitter::LoadXml: XML root was not \"Emitter\" in file %ls. Load failed.", pathname.string().c_str() );
|
||||
return( false );
|
||||
}
|
||||
|
||||
m_tag = pathname.Basename().string();
|
||||
|
||||
//TODO figure out if we need to use Type attribute to construct different emitter types,
|
||||
// probably have to move some of this code into a static factory method or out into ParticleEngine class
|
||||
XMBAttributeList attributes = root.GetAttributes();
|
||||
CStr type = attributes.GetNamedItem(at_Type);
|
||||
|
||||
CStr stringValue;
|
||||
XMBElementList children = root.GetChildNodes();
|
||||
for (int i = 0; i < children.Count; ++i)
|
||||
{
|
||||
XMBElement child = children.Item(i);
|
||||
int childName = child.GetNodeName();
|
||||
if( childName == el_Lifetime )
|
||||
{
|
||||
stringValue = child.GetText();
|
||||
m_emitterLife = stringValue.ToInt();
|
||||
if( m_emitterLife < 0 )
|
||||
m_emitterLife = -1;
|
||||
}
|
||||
else if( childName == el_Particles )
|
||||
{
|
||||
attributes = child.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_MaxNumber);
|
||||
m_maxParticles = stringValue.ToInt();
|
||||
|
||||
XMBElementList particleSettings = child.GetChildNodes();
|
||||
for (int j = 0; j < particleSettings.Count; ++j)
|
||||
{
|
||||
XMBElement settingElement = particleSettings.Item(j);
|
||||
int settingName = settingElement.GetNodeName();
|
||||
if( settingName == el_EmitsPerFrame )
|
||||
{
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, settingElement, value, variation);
|
||||
m_emitsPerFrame = value.ToInt();
|
||||
m_emitsVar = variation.ToInt();
|
||||
}
|
||||
else if( settingName == el_Texture )
|
||||
{
|
||||
CTextureProperties textureProps(settingElement.GetText().FromUTF8());
|
||||
m_texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
|
||||
}
|
||||
else if( settingName == el_Size )
|
||||
{
|
||||
stringValue = settingElement.GetText();
|
||||
m_size = stringValue.ToFloat();
|
||||
}
|
||||
else if( settingName == el_Color )
|
||||
{
|
||||
XMBElementList colorElementList = settingElement.GetChildNodes();
|
||||
for (int k = 0; k < colorElementList.Count; ++k)
|
||||
{
|
||||
XMBElement colorElement = colorElementList.Item(k);
|
||||
int colorName = colorElement.GetNodeName();
|
||||
if( colorName == el_Start )
|
||||
{
|
||||
XMBElementList startColorElementList = colorElement.GetChildNodes();
|
||||
for (int m = 0; m < startColorElementList.Count; ++m)
|
||||
{
|
||||
XMBElement startColorElement = startColorElementList.Item(m);
|
||||
int startColorElementName = startColorElement.GetNodeName();
|
||||
if( startColorElementName == el_Value )
|
||||
{
|
||||
attributes = startColorElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_r);
|
||||
m_startColor.r = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_g);
|
||||
m_startColor.g = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_b);
|
||||
m_startColor.b = stringValue.ToInt();
|
||||
}
|
||||
else if( startColorElementName == el_Variation )
|
||||
{
|
||||
attributes = startColorElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_r);
|
||||
m_startColorVar.r = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_g);
|
||||
m_startColorVar.g = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_b);
|
||||
m_startColorVar.b = stringValue.ToInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( colorName == el_End )
|
||||
{
|
||||
XMBElementList endColorElementList = colorElement.GetChildNodes();
|
||||
for (int m = 0; m < endColorElementList.Count; ++m)
|
||||
{
|
||||
XMBElement endColorElement = endColorElementList.Item(m);
|
||||
int endColorElementName = endColorElement.GetNodeName();
|
||||
if( endColorElementName == el_Value )
|
||||
{
|
||||
attributes = endColorElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_r);
|
||||
m_endColor.r = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_g);
|
||||
m_endColor.g = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_b);
|
||||
m_endColor.b = stringValue.ToInt();
|
||||
}
|
||||
else if( endColorElementName == el_Variation )
|
||||
{
|
||||
attributes = endColorElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_r);
|
||||
m_endColorVar.r = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_g);
|
||||
m_endColorVar.g = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_b);
|
||||
m_endColorVar.b = stringValue.ToInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( settingName == el_Alpha )
|
||||
{
|
||||
attributes = settingElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_BlendMode);
|
||||
m_blendMode = stringValue.ToInt();
|
||||
stringValue = attributes.GetNamedItem(at_Decrement);
|
||||
if (stringValue == "True" || stringValue == "true")
|
||||
m_decrementAlpha = true;
|
||||
else
|
||||
m_decrementAlpha = false;
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, settingElement, value, variation);
|
||||
m_alpha = value.ToInt();
|
||||
m_alphaVar = value.ToInt();
|
||||
}
|
||||
else if( settingName == el_Direction )
|
||||
{
|
||||
XMBElementList directionElementList = settingElement.GetChildNodes();
|
||||
for (int k = 0; k < directionElementList.Count; ++k)
|
||||
{
|
||||
XMBElement directionElement = directionElementList.Item(k);
|
||||
int directionElementName = directionElement.GetNodeName();
|
||||
if( directionElementName == el_Yaw )
|
||||
{
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, directionElement, value, variation);
|
||||
m_yaw = value.ToInt();
|
||||
m_yawVar = variation.ToInt();
|
||||
}
|
||||
else if( directionElementName == el_Pitch )
|
||||
{
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, directionElement, value, variation);
|
||||
m_pitch = value.ToInt();
|
||||
m_pitchVar = variation.ToInt();
|
||||
}
|
||||
else if( directionElementName == el_Speed )
|
||||
{
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, directionElement, value, variation);
|
||||
m_speed = value.ToFloat();
|
||||
m_speedVar = variation.ToFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( settingName == el_Life )
|
||||
{
|
||||
attributes = settingElement.GetAttributes();
|
||||
stringValue = attributes.GetNamedItem(at_Decrement);
|
||||
if (stringValue == "True" || stringValue == "true")
|
||||
m_decrementLife = true;
|
||||
else
|
||||
m_decrementLife = false;
|
||||
CStr value, variation;
|
||||
GetValueAndVariation(XeroFile, settingElement, value, variation);
|
||||
m_life = value.ToInt();
|
||||
m_lifeVar = variation.ToInt();
|
||||
}
|
||||
else if( settingName == el_Force )
|
||||
{
|
||||
XMBElementList forceElementList = settingElement.GetChildNodes();
|
||||
for (int k = 0; k < forceElementList.Count; ++k)
|
||||
{
|
||||
XMBElement forceElement = forceElementList.Item(k);
|
||||
int forceElementName = forceElement.GetNodeName();
|
||||
if( forceElementName == el_X )
|
||||
{
|
||||
stringValue = forceElement.GetText();
|
||||
m_force.X = stringValue.ToFloat();
|
||||
}
|
||||
else if( forceElementName == el_Y )
|
||||
{
|
||||
stringValue = forceElement.GetText();
|
||||
m_force.Y = stringValue.ToFloat();
|
||||
}
|
||||
else if( forceElementName == el_Z )
|
||||
{
|
||||
stringValue = forceElement.GetText();
|
||||
m_force.Z = stringValue.ToFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CEmitter::AddParticle()
|
||||
{
|
||||
tColor start, end;
|
||||
float fYaw, fPitch, fSpeed;
|
||||
|
||||
if(!m_openList)
|
||||
return false;
|
||||
|
||||
if(m_particleCount < m_maxParticles)
|
||||
{
|
||||
// get a particle from the open list
|
||||
tParticle *particle = m_openList;
|
||||
|
||||
// set it's initial position to the emitter's position
|
||||
particle->pos.X = m_pos.X;
|
||||
particle->pos.Y = m_pos.Y;
|
||||
particle->pos.Z = m_pos.Z;
|
||||
|
||||
// Calculate the starting direction vector
|
||||
fYaw = m_yaw + (m_yawVar * RandomNum());
|
||||
fPitch = m_pitch + (m_pitchVar * RandomNum());
|
||||
|
||||
// Convert the rotations to a vector
|
||||
RotationToDirection(fPitch,fYaw,&particle->dir);
|
||||
|
||||
// Multiply in the speed factor
|
||||
fSpeed = m_speed + (m_speedVar * RandomNum());
|
||||
particle->dir.X *= fSpeed;
|
||||
particle->dir.Y *= fSpeed;
|
||||
particle->dir.Z *= fSpeed;
|
||||
|
||||
// Calculate the life span
|
||||
particle->life = m_life + (int)((float)m_lifeVar * RandomNum());
|
||||
|
||||
// Calculate the colors
|
||||
start.r = m_startColor.r + (m_startColorVar.r * RandomChar());
|
||||
start.g = m_startColor.g + (m_startColorVar.g * RandomChar());
|
||||
start.b = m_startColor.b + (m_startColorVar.b * RandomChar());
|
||||
end.r = m_endColor.r + (m_endColorVar.r * RandomChar());
|
||||
end.g = m_endColor.g + (m_endColorVar.g * RandomChar());
|
||||
end.b = m_endColor.b + (m_endColorVar.b * RandomChar());
|
||||
|
||||
// set the initial color of the particle
|
||||
particle->color.r = start.r;
|
||||
particle->color.g = start.g;
|
||||
particle->color.b = start.b;
|
||||
|
||||
// Create the color delta
|
||||
particle->deltaColor.r = (end.r - start.r) / particle->life;
|
||||
particle->deltaColor.g = (end.g - start.g) / particle->life;
|
||||
particle->deltaColor.b = (end.b - start.b) / particle->life;
|
||||
|
||||
//TODO: make this settable
|
||||
particle->alpha = 255.0f;
|
||||
particle->alphaDelta = particle->alpha / particle->life;
|
||||
|
||||
particle->inPos = false;
|
||||
|
||||
// Now, we pop a node from the open list and put it into the used list
|
||||
m_openList = particle->next;
|
||||
particle->next = m_usedList;
|
||||
m_usedList = particle;
|
||||
|
||||
// update the length of the used list (particle Count)
|
||||
m_particleCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEmitter::Render()
|
||||
{
|
||||
if(m_renderParticles)
|
||||
{
|
||||
switch(m_blendMode)
|
||||
{
|
||||
case 1:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Fire
|
||||
break;
|
||||
case 2:
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE); // Crappy Fire
|
||||
break;
|
||||
case 3:
|
||||
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); // Plain Particles
|
||||
break;
|
||||
case 4:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); // Nice fade out effect
|
||||
break;
|
||||
}
|
||||
|
||||
m_texture->Bind();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
tParticle *tempParticle = m_usedList;
|
||||
|
||||
while(tempParticle)
|
||||
{
|
||||
tColor *pColor = &(tempParticle->color);
|
||||
glColor4ub(pColor->r,pColor->g, pColor->b, (GLubyte)tempParticle->alpha);
|
||||
glTexCoord2d(0.0, 0.0);
|
||||
CVector3D *pPos = &(tempParticle->pos);
|
||||
glVertex3f(pPos->X - m_size, pPos->Y + m_size, pPos->Z);
|
||||
glTexCoord2d(0.0, 1.0);
|
||||
glVertex3f(pPos->X - m_size, pPos->Y - m_size, pPos->Z);
|
||||
glTexCoord2d(1.0, 1.0);
|
||||
glVertex3f(pPos->X + m_size, pPos->Y - m_size, pPos->Z);
|
||||
glTexCoord2d(1.0, 0.0);
|
||||
glVertex3f(pPos->X + m_size, pPos->Y + m_size, pPos->Z);
|
||||
tempParticle = tempParticle->next;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEmitter::Update()
|
||||
{
|
||||
int emits;
|
||||
// walk through the used list, and update each of the particles
|
||||
tParticle *tempParticle = m_usedList; // start at the beginning of the used list
|
||||
tParticle *prev = m_usedList;
|
||||
while(tempParticle) // loop on a valid particle
|
||||
{
|
||||
// don't update if the particle is supposed to be dead
|
||||
if(tempParticle->life > 0)
|
||||
{
|
||||
// update the particle
|
||||
// Calculate the new pos
|
||||
tempParticle->pos.X += tempParticle->dir.X;
|
||||
tempParticle->pos.Y += tempParticle->dir.Y;
|
||||
tempParticle->pos.Z += tempParticle->dir.Z;
|
||||
|
||||
// Add global force to direction
|
||||
tempParticle->dir.X += m_force.X;
|
||||
tempParticle->dir.Y += m_force.Y;
|
||||
tempParticle->dir.Z += m_force.Z;
|
||||
|
||||
// Get the new color
|
||||
tempParticle->color.r += tempParticle->deltaColor.r;
|
||||
tempParticle->color.g += tempParticle->deltaColor.g;
|
||||
tempParticle->color.b += tempParticle->deltaColor.b;
|
||||
|
||||
// fade it out
|
||||
if(m_decrementAlpha)
|
||||
tempParticle->alpha -= tempParticle->alphaDelta;
|
||||
|
||||
// gets a little older
|
||||
if(m_decrementLife)
|
||||
tempParticle->life--;
|
||||
|
||||
// move to the next particle in the list
|
||||
prev = tempParticle;
|
||||
tempParticle = tempParticle->next;
|
||||
}
|
||||
else // this means the particle lifetime is over
|
||||
{
|
||||
// if this is the first particle in usedList
|
||||
// then set the pointers to the next in the usedList
|
||||
// and open up the tempParticle
|
||||
if(tempParticle == m_usedList)
|
||||
{
|
||||
m_usedList = tempParticle->next;
|
||||
tempParticle->next = m_openList;
|
||||
// set the open list head to the particle
|
||||
m_openList = tempParticle;
|
||||
prev = m_usedList;
|
||||
tempParticle = m_usedList;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//// We need to pull the particle out of the
|
||||
//// used list and insert it into the open list
|
||||
|
||||
// fix the previous node in the list to skip over the one we are pulling out
|
||||
prev->next = tempParticle->next;
|
||||
// set the particle to point to the head of the open list
|
||||
tempParticle->next = m_openList;
|
||||
// set the open list head to the particle
|
||||
m_openList = tempParticle;
|
||||
// move on to the next iteration
|
||||
tempParticle = prev->next;
|
||||
}
|
||||
// and there is one less
|
||||
m_particleCount--;
|
||||
}
|
||||
} // end of while
|
||||
if(m_emitterLife > 0 || m_emitterLife == -1)
|
||||
{
|
||||
// Emit particles for this frame
|
||||
emits = m_emitsPerFrame + (int)((float)m_emitsVar * RandomNum());
|
||||
|
||||
// if the emitter life is -1 that means it's infinite
|
||||
if(m_emitterLife != -1)
|
||||
m_emitterLife--;
|
||||
|
||||
for(int i = 0; i < emits; i++)
|
||||
AddParticle();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_particleCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFinished = true;
|
||||
return false; // this will be checked for and then it will be deleted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GetValueAndVariation(CXeromyces XeroFile, XMBElement parent, CStr& value, CStr& variation)
|
||||
{
|
||||
int el_Value = XeroFile.GetElementID("value");
|
||||
int el_Variation = XeroFile.GetElementID("variation");
|
||||
|
||||
XMBElementList elementList = parent.GetChildNodes();
|
||||
for (int i = 0; i < elementList.Count; ++i)
|
||||
{
|
||||
XMBElement child = elementList.Item(i);
|
||||
int childName = child.GetNodeName();
|
||||
if( childName == el_Value )
|
||||
{
|
||||
value = child.GetText();
|
||||
}
|
||||
else if( childName == el_Variation )
|
||||
{
|
||||
variation = child.GetText();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,233 +0,0 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Particle and Emitter base classes.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_PARTICLEEMITTER
|
||||
#define INCLUDED_PARTICLEEMITTER
|
||||
|
||||
#include "graphics/Texture.h"
|
||||
#include "lib/file/vfs/vfs_path.h"
|
||||
#include "maths/Vector3D.h"
|
||||
#include "ps/CStr.h"
|
||||
|
||||
class CEmitter
|
||||
{
|
||||
static const int HALF_RAND = (RAND_MAX / 2);
|
||||
|
||||
public:
|
||||
struct tColor
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
struct tParticle
|
||||
{
|
||||
// base stuff
|
||||
CVector3D pos; // Current position 12
|
||||
CVector3D dir; // Current direction with speed 12
|
||||
float alpha; // Fade value 4
|
||||
float alphaDelta; // Change of fade 4
|
||||
tColor color; // Current color of particle 3
|
||||
tColor deltaColor; // Change of color 3
|
||||
short life; // How long it will last 2
|
||||
|
||||
// particle text stuff
|
||||
CVector3D endPos; // For particle texture 12
|
||||
bool inPos; // 1
|
||||
|
||||
tParticle* next; // pointer for link lists 4
|
||||
|
||||
tParticle()
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
};
|
||||
|
||||
//struct tParticleNode
|
||||
//{
|
||||
// tParticle* pParticle;
|
||||
// tParticleNode* next;
|
||||
//};
|
||||
|
||||
protected:
|
||||
|
||||
CStrW m_tag;
|
||||
int m_maxParticles; // Maximum particles emitter can put out
|
||||
int m_particleCount; // Total emitted right now
|
||||
int m_emitsPerFrame, m_emitsVar; // Emits per frame and variation
|
||||
int m_emitterLife; // Life of the emitter
|
||||
|
||||
bool isFinished; // tells the engine it's ready to be deleted
|
||||
|
||||
// Transformation Info
|
||||
CVector3D m_pos; // XYZ Position of emitter
|
||||
float m_yaw, m_yawVar; // Yaw of emitted particles
|
||||
float m_pitch, m_pitchVar; // Pitch of emitted particles
|
||||
float m_speed, m_speedVar; // Speed of emitted particles
|
||||
|
||||
// Particle linked lists
|
||||
tParticle* m_heap; // Pointer to beginning of array
|
||||
tParticle* m_openList; // linked list of unused particles
|
||||
tParticle* m_usedList; // linked list of used particles
|
||||
|
||||
//Particle appearence
|
||||
CTexturePtr m_texture; // Texture
|
||||
float m_size; // size of the particles (if point sprites is not enabled)
|
||||
tColor m_startColor, m_startColorVar; // Current color of particle
|
||||
tColor m_endColor, m_endColorVar; // End color of particle
|
||||
int m_blendMode; // Method used to blend particles
|
||||
int m_alpha, m_alphaVar; // Alpha value for particles
|
||||
int m_life, m_lifeVar; // Life count and variation (in Frames)
|
||||
bool m_decrementLife; // Controls whether or not the particles life is decremented every update.
|
||||
bool m_decrementAlpha; // Controls whether or not the particles alpha is decremented every update.
|
||||
bool m_renderParticles; // Controls the rendering of the particles.
|
||||
|
||||
// Physics
|
||||
CVector3D m_force; // Forces that affect the particles
|
||||
|
||||
public:
|
||||
CEmitter(const int MAX_PARTICLES = 4000, const int lifetime = -1, int textureID = 0);
|
||||
virtual ~CEmitter(void);
|
||||
|
||||
// note: methods are virtual and overridable so as to suit the
|
||||
// specific particle needs.
|
||||
|
||||
virtual bool LoadXml(const VfsPath& pathname);
|
||||
|
||||
virtual bool Setup() { return false; }
|
||||
|
||||
virtual bool AddParticle();
|
||||
|
||||
virtual bool Update();
|
||||
|
||||
virtual bool Render();
|
||||
|
||||
// Helper functions
|
||||
inline float RandomNum()
|
||||
{
|
||||
int rn;
|
||||
rn = rand();
|
||||
return ((float)(rn - HALF_RAND) / (float)HALF_RAND);
|
||||
}
|
||||
|
||||
inline char RandomChar()
|
||||
{
|
||||
return (unsigned char)(rand() >> 24);
|
||||
}
|
||||
|
||||
inline void RotationToDirection(float pitch, float yaw, CVector3D* direction)
|
||||
{
|
||||
direction->X = (float)(-sin(yaw)* cos(pitch));
|
||||
direction->Y = (float)sin(pitch);
|
||||
direction->Z = (float)(cos(pitch)* cos(yaw));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
CStrW GetTag() { return m_tag; }
|
||||
float GetPosX() { return m_pos.X; }
|
||||
float GetPosY() { return m_pos.Y; }
|
||||
float GetPosZ() { return m_pos.Z; }
|
||||
CVector3D GetPosVec() { return m_pos; }
|
||||
bool IsFinished(void) { return isFinished; }
|
||||
int GetEmitterLife() { return m_emitterLife; }
|
||||
int GetParticleCount() { return m_particleCount; }
|
||||
int GetMaxParticles(void) { return m_maxParticles; }
|
||||
tColor GetStartColor(void) { return m_startColor; }
|
||||
tColor GetStartColorVar(void) { return m_startColorVar; }
|
||||
tColor GetEndColor(void) { return m_endColor; }
|
||||
tColor GetEndColorVar(void) { return m_endColorVar; }
|
||||
int GetBlendMode(void) { return m_blendMode; }
|
||||
float GetSize(void) { return m_size; }
|
||||
float GetYaw(void) { return m_yaw; }
|
||||
float GetYawVar(void) { return m_yawVar; }
|
||||
float GetPitch(void) { return m_pitch; }
|
||||
float GetPitchVar(void) { return m_pitchVar; }
|
||||
float GetSpeed(void) { return m_speed; }
|
||||
float GetSpeedVar(void) { return m_speedVar; }
|
||||
int GetEmitsPerFrame(void) { return m_emitsPerFrame; }
|
||||
int GetEmitVar(void) { return m_emitsVar; }
|
||||
int GetLife(void) { return m_life; }
|
||||
int GetLifeVar(void) { return m_lifeVar; }
|
||||
float GetForceX(void) { return m_force.X; }
|
||||
float GetForceY(void) { return m_force.Y; }
|
||||
float GetForceZ(void) { return m_force.Z; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Mutators
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
void SetTag(CStrW tag) { m_tag = tag; }
|
||||
void SetPosX(float posX) { m_pos.X = posX; }
|
||||
void SetPosY(float posY) { m_pos.Y = posY; }
|
||||
void SetPosZ(float posZ) { m_pos.Z = posZ; }
|
||||
inline void SetPosVec(const CVector3D& newPos)
|
||||
{
|
||||
m_pos = newPos;
|
||||
}
|
||||
void SetTexture(CTexturePtr id) { m_texture = id; }
|
||||
void SetIsFinished(bool finished) { isFinished = finished; }
|
||||
void SetEmitterLife(int life) { m_emitterLife = life; }
|
||||
void SetLife(int newlife) { m_life = newlife; }
|
||||
void SetLifeVar(int newlifevar) { m_lifeVar = newlifevar; }
|
||||
void SetSpeed(float newspeed) { m_speed = newspeed; }
|
||||
void SetSpeedVar(float newspeedvar) { m_speedVar = newspeedvar; }
|
||||
void SetYaw(float newyaw) { m_yaw = newyaw; }
|
||||
void SetYawVar(float newyawvar) { m_yawVar = newyawvar; }
|
||||
void SetPitch(float newpitch) { m_pitch = newpitch; }
|
||||
void SetPitchVar(float newpitchvar) { m_pitchVar = newpitchvar; }
|
||||
void SetStartColor(tColor newColor) { m_startColor = newColor; }
|
||||
void SetStartColorVar(tColor newColorVar) { m_startColorVar = newColorVar; }
|
||||
void SetEndColor(tColor newColor) { m_endColor = newColor; }
|
||||
void SetEndColorVar(tColor newColorVar) { m_endColorVar = newColorVar; }
|
||||
void SetStartColorR(int newColorR) { m_startColor.r = newColorR; }
|
||||
void SetStartColorG(int newColorG) { m_startColor.g = newColorG; }
|
||||
void SetStartColorB(int newColorB) { m_startColor.b = newColorB; }
|
||||
void SetStartColorVarR(int newColorVarR) { m_startColorVar.r = newColorVarR; }
|
||||
void SetStartColorVarG(int newColorVarG) { m_startColorVar.g = newColorVarG; }
|
||||
void SetStartColorVarB(int newColorVarB) { m_startColorVar.b = newColorVarB; }
|
||||
void SetEndColorR(int newColorR) { m_endColor.r = newColorR; }
|
||||
void SetEndColorG(int newColorG) { m_endColor.g = newColorG; }
|
||||
void SetEndColorB(int newColorB) { m_endColor.b = newColorB; }
|
||||
void SetEndColorVarR(int newColorVarR) { m_endColorVar.r = newColorVarR; }
|
||||
void SetEndColorVarG(int newColorVarG) { m_endColorVar.g = newColorVarG; }
|
||||
void SetEndColorVarB(int newColorVarB) { m_endColorVar.b = newColorVarB; }
|
||||
inline void SetBlendMode(int blendmode)
|
||||
{
|
||||
if(blendmode >= 1 && blendmode <= 4)
|
||||
m_blendMode = blendmode;
|
||||
else
|
||||
m_blendMode = 1;
|
||||
}
|
||||
void SetEmitsPerFrame(int emitsperframe) { m_emitsPerFrame = emitsperframe; }
|
||||
void SetEmitVar(int emitvar) { m_emitsVar = emitvar; }
|
||||
void SetForceX(float forceX) { m_force.X = forceX; }
|
||||
void SetForceY(float forceY) { m_force.Y = forceY; }
|
||||
void SetForceZ(float forceZ) { m_force.Z = forceZ; }
|
||||
void SetSize(float newSize) { m_size = newSize; }
|
||||
void SetRenderParticles(bool render) { m_renderParticles = render; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,256 +0,0 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Particle engine implementation
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ParticleEngine.h"
|
||||
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "ps/Profile.h"
|
||||
|
||||
CParticleEngine *CParticleEngine::m_pInstance = 0;
|
||||
CParticleEngine::CParticleEngine(void)
|
||||
{
|
||||
m_pHead = NULL;
|
||||
totalParticles = 0;
|
||||
}
|
||||
|
||||
CParticleEngine::~CParticleEngine(void)
|
||||
{
|
||||
}
|
||||
|
||||
void CParticleEngine::Cleanup()
|
||||
{
|
||||
tEmitterNode *temp = m_pHead;
|
||||
totalParticles = 0;
|
||||
while(temp)
|
||||
{
|
||||
tEmitterNode *pTemp = temp->next;
|
||||
if(!temp->prev)
|
||||
m_pHead = temp->next;
|
||||
else
|
||||
temp->prev->next = temp->next;
|
||||
|
||||
if(pTemp)
|
||||
temp->next->prev = temp->prev;
|
||||
|
||||
delete temp->pEmitter;
|
||||
delete temp;
|
||||
temp = pTemp;
|
||||
}
|
||||
|
||||
DeleteInstance();
|
||||
}
|
||||
|
||||
CParticleEngine *CParticleEngine::GetInstance(void)
|
||||
{
|
||||
// Check to see if one hasn't been made yet.
|
||||
if (m_pInstance == 0)
|
||||
m_pInstance = new CParticleEngine;
|
||||
|
||||
// Return the address of the instance.
|
||||
return m_pInstance;
|
||||
}
|
||||
|
||||
void CParticleEngine::DeleteInstance()
|
||||
{
|
||||
if (m_pInstance)
|
||||
delete m_pInstance;
|
||||
m_pInstance = 0;
|
||||
}
|
||||
|
||||
bool CParticleEngine::InitParticleSystem()
|
||||
{
|
||||
// Texture Loading
|
||||
CTextureProperties textureProps(L"art/textures/particles/sprite.tga");
|
||||
CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
|
||||
|
||||
idTexture[DEFAULTTEXT] = texture;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParticleEngine::AddEmitter(CEmitter *emitter, int type, int ID)
|
||||
{
|
||||
emitter->SetTexture(idTexture[type]);
|
||||
if(m_pHead == NULL)
|
||||
{
|
||||
tEmitterNode *temp = new tEmitterNode;
|
||||
temp->pEmitter = emitter;
|
||||
temp->prev = NULL;
|
||||
temp->next = NULL;
|
||||
temp->ID = ID;
|
||||
m_pHead = temp;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tEmitterNode *temp = new tEmitterNode;
|
||||
temp->pEmitter = emitter;
|
||||
temp->next = m_pHead;
|
||||
temp->prev = NULL;
|
||||
temp->ID = ID;
|
||||
m_pHead->prev = temp;
|
||||
m_pHead = temp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
CEmitter* CParticleEngine::FindEmitter(int ID)
|
||||
{
|
||||
tEmitterNode *temp = m_pHead;
|
||||
while(temp)
|
||||
{
|
||||
if(temp->ID < 0 || temp->ID > MAX_EMIT)
|
||||
continue;
|
||||
|
||||
// NOTE: In the event that there are two different
|
||||
// emitters with the same ID, this will only
|
||||
// return the first one that it finds. So
|
||||
// make sure your emitter has a unique ID
|
||||
// if you want to use this function.
|
||||
if(temp->ID == ID)
|
||||
return temp->pEmitter;
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
// NOTE: Just in case this happens, it's VERY important
|
||||
// that you wrap this function in a if statement
|
||||
// to check for this condition because you could
|
||||
// end up with a crash if you try to change an
|
||||
// emitter when you couldn't find it and returned
|
||||
// NULL instead.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CParticleEngine::UpdateEmitters()
|
||||
{
|
||||
PROFILE("update particles");
|
||||
|
||||
tEmitterNode *temp = m_pHead;
|
||||
totalParticles = 0;
|
||||
while(temp)
|
||||
{
|
||||
// are we ready for deletion?
|
||||
if(temp->pEmitter->IsFinished())
|
||||
{
|
||||
// store a pointer to the next node
|
||||
tEmitterNode *pTemp = temp->next;
|
||||
|
||||
// check for the head
|
||||
if(!temp->prev)
|
||||
m_pHead = pTemp;
|
||||
else
|
||||
// forward the previous's pointer
|
||||
temp->prev->next = pTemp;
|
||||
|
||||
// if there is any next one,
|
||||
if(pTemp)
|
||||
// fix the backwards pointer
|
||||
pTemp->prev = temp->prev;
|
||||
|
||||
delete temp->pEmitter;
|
||||
delete temp;
|
||||
temp = pTemp;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp->pEmitter->Update();
|
||||
|
||||
// Add current emitter to particle count
|
||||
totalParticles += temp->pEmitter->GetParticleCount();
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CParticleEngine::RenderParticles()
|
||||
{
|
||||
PROFILE("render particles");
|
||||
|
||||
EnterParticleContext();
|
||||
|
||||
tEmitterNode *temp = m_pHead;
|
||||
while(temp)
|
||||
{
|
||||
temp->pEmitter->Render();
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
LeaveParticleContext();
|
||||
}
|
||||
|
||||
void CParticleEngine::DestroyAllEmitters(bool fade)
|
||||
{
|
||||
tEmitterNode *temp = m_pHead;
|
||||
while(temp)
|
||||
{
|
||||
if(fade)
|
||||
{
|
||||
temp->pEmitter->SetEmitterLife(0);
|
||||
temp = temp->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// store a pointer to the next node
|
||||
tEmitterNode *pTemp = temp->next;
|
||||
|
||||
// check for the head
|
||||
if(!temp->prev)
|
||||
m_pHead = pTemp;
|
||||
else
|
||||
// forward the previous's pointer
|
||||
temp->prev->next = pTemp;
|
||||
|
||||
// if there is any next one,
|
||||
if(pTemp)
|
||||
// fix the backwards pointer
|
||||
pTemp->prev = temp->prev;
|
||||
|
||||
delete temp->pEmitter;
|
||||
delete temp;
|
||||
temp = pTemp;
|
||||
}
|
||||
}
|
||||
m_pHead = NULL;
|
||||
UpdateEmitters();
|
||||
}
|
||||
|
||||
void CParticleEngine::EnterParticleContext(void)
|
||||
{
|
||||
//glEnable(GL_DEPTH_TEST); // Enable depth testing for hidden surface removal.
|
||||
glDepthMask(false);
|
||||
//glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D); // Enable texture mapping.
|
||||
glPushMatrix();
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
void CParticleEngine::LeaveParticleContext(void)
|
||||
{
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
//glEnable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glPopMatrix();
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Particle engine implementation
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_PARTICLEENGINE
|
||||
#define INCLUDED_PARTICLEENGINE
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
#include "lib/tex/tex.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
#include "graphics/Texture.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Loader.h"
|
||||
|
||||
#include "lib/ogl.h"
|
||||
#include "renderer/Renderer.h"
|
||||
|
||||
// Different textures
|
||||
enum PText { DEFAULTTEXT, MAX_TEXTURES };
|
||||
// Different emitters
|
||||
enum PEmit { DEFAULTEMIT, MAX_EMIT };
|
||||
|
||||
class CParticleEngine
|
||||
{
|
||||
public:
|
||||
virtual ~CParticleEngine(void);
|
||||
|
||||
|
||||
/// @return instance of the singleton class
|
||||
static CParticleEngine* GetInstance();
|
||||
|
||||
/// delete the instance of the singleton class
|
||||
static void DeleteInstance();
|
||||
|
||||
/// @return true on success, false on failure
|
||||
bool InitParticleSystem(void);
|
||||
|
||||
/**
|
||||
* add the emitter to the engine's list.
|
||||
* @return indicator of success.
|
||||
**/
|
||||
bool AddEmitter(CEmitter *emitter, int type = DEFAULTTEXT, int ID = DEFAULTEMIT);
|
||||
|
||||
/// @return emitter with the given ID or 0 if not found.
|
||||
CEmitter* FindEmitter(int ID);
|
||||
|
||||
/**
|
||||
* Check if the emitters are ready to be deleted and removed.
|
||||
* If not, call Update() on them.
|
||||
**/
|
||||
void UpdateEmitters();
|
||||
|
||||
/// render each emitter and their particles
|
||||
void RenderParticles();
|
||||
|
||||
/**
|
||||
* destroy all active emitters on screen.
|
||||
* @param fade if true, allows emitters to fade out. if false,
|
||||
* they disappear instantly.
|
||||
**/
|
||||
void DestroyAllEmitters(bool fade = true);
|
||||
|
||||
/// do cleanup that's not done in the destructor.
|
||||
void Cleanup();
|
||||
|
||||
void EnterParticleContext(void);
|
||||
void LeaveParticleContext(void);
|
||||
|
||||
int GetTotalParticles() { return totalParticles; }
|
||||
void SetTotalParticles(int particles) { totalParticles = particles; }
|
||||
void AddToTotalParticles(int addAmount) { totalParticles += addAmount; }
|
||||
void SubToTotalParticles(int subAmount) { totalParticles -= subAmount; }
|
||||
|
||||
private:
|
||||
CParticleEngine(void);
|
||||
static CParticleEngine* m_pInstance; // The singleton instance
|
||||
|
||||
CTexturePtr idTexture[MAX_TEXTURES];
|
||||
int totalParticles; // Total Amount of particles of all emitters.
|
||||
|
||||
struct tEmitterNode
|
||||
{
|
||||
CEmitter *pEmitter;
|
||||
tEmitterNode *prev, *next;
|
||||
int ID;
|
||||
};
|
||||
|
||||
tEmitterNode *m_pHead;
|
||||
friend class CEmitter;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user