This is the new particle engine. It's in and it compiles, but it's not implemented fully yet. Will get to that soon.
This was SVN commit r3369.
This commit is contained in:
parent
30b83db67b
commit
aef0a42780
157
source/graphics/DefaultEmitter.cpp
Normal file
157
source/graphics/DefaultEmitter.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: DefaultEmitter.cpp
|
||||
// Date: 7/20/05
|
||||
// Author: Will Dull
|
||||
// Purpose: Implementation of the default
|
||||
// emitter class.
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "DefaultEmitter.h"
|
||||
|
||||
CDefaultEmitter::CDefaultEmitter(const int MAX_PARTICLES, const int lifetime) : CEmitter(MAX_PARTICLES, lifetime)
|
||||
{
|
||||
setupEmitter();
|
||||
}
|
||||
|
||||
CDefaultEmitter::~CDefaultEmitter(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool CDefaultEmitter::setupEmitter()
|
||||
{
|
||||
pos.x = 0.0f; // XYZ Position
|
||||
pos.y = 0.0f; // XYZ Position
|
||||
pos.z = 0.0f; // XYZ Position
|
||||
|
||||
yaw = DEGTORAD(0.0f);
|
||||
yawVar = DEGTORAD(360.0f);
|
||||
pitch = DEGTORAD(90.0f);
|
||||
pitchVar = DEGTORAD(45.0f);
|
||||
speed = 0.05f;
|
||||
speedVar = 0.001f;
|
||||
|
||||
blend_mode = 1;
|
||||
particleCount = 0;
|
||||
emitsPerFrame = 100;
|
||||
emitVar = 15;
|
||||
life = 90;
|
||||
lifeVar = 65;
|
||||
startColor.r = 240;
|
||||
startColor.g = 240;
|
||||
startColor.b = 15;
|
||||
startColorVar.r = 15;
|
||||
startColorVar.g = 15;
|
||||
startColorVar.b = 15;
|
||||
endColor.r = 240;
|
||||
endColor.g = 15;
|
||||
endColor.b = 15;
|
||||
endColorVar.r = 15;
|
||||
endColorVar.g = 15;
|
||||
endColorVar.b = 15;
|
||||
|
||||
force.x = 0.000f;
|
||||
force.y = -0.001f;
|
||||
force.z = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDefaultEmitter::updateEmitter()
|
||||
{
|
||||
int emits;
|
||||
// walk through the used list, and update each of the particles
|
||||
tParticle *tempParticle = usedList; // start at the beginning of the used list
|
||||
tParticle *prev = 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 += force.x;
|
||||
tempParticle->dir.y += force.y;
|
||||
tempParticle->dir.z += 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(decrementAlpha)
|
||||
tempParticle->alpha -= tempParticle->alphaDelta;
|
||||
|
||||
// gets a little older
|
||||
if(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 == usedList)
|
||||
{
|
||||
usedList = tempParticle->next;
|
||||
tempParticle->next = openList;
|
||||
// set the open list head to the particle
|
||||
openList = tempParticle;
|
||||
prev = usedList;
|
||||
tempParticle = 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 = openList;
|
||||
// set the open list head to the particle
|
||||
openList = tempParticle;
|
||||
// move on to the next iteration
|
||||
tempParticle = prev->next;
|
||||
}
|
||||
// and there is one less
|
||||
particleCount--;
|
||||
}
|
||||
} // end of while
|
||||
if(emitterLife > 0 || emitterLife == -1)
|
||||
{
|
||||
// Emit particles for this frame
|
||||
emits = emitsPerFrame + (int)((float)emitVar * RandomNum());
|
||||
|
||||
// if the particle life is -1 that means it's infinite
|
||||
if(emitterLife != -1)
|
||||
emitterLife--;
|
||||
|
||||
for(int i = 0; i < emits; i++)
|
||||
addParticle();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(particleCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isFinished = true;
|
||||
return false; // this will be checked for and then it will be deleted
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
38
source/graphics/DefaultEmitter.h
Normal file
38
source/graphics/DefaultEmitter.h
Normal file
@ -0,0 +1,38 @@
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: DefaultEmitter.h
|
||||
// Date: 7/20/05
|
||||
// Author: Will Dull
|
||||
// Purpose: Default emitter
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _DEFAULTEMITTER_H_
|
||||
#define _DEFAULTEMITTER_H_
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
|
||||
class CDefaultEmitter : public CEmitter
|
||||
{
|
||||
public:
|
||||
CDefaultEmitter(const int MAX_PARTICLES = 4000, const int lifetime = -1);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: setupEmitter
|
||||
//Date: 7/19/05
|
||||
//Author: Will Dull
|
||||
//Notes: Sets up emitter to the default particle
|
||||
// effect.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool setupEmitter();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: updateEmitter
|
||||
//Date: 7/19/05
|
||||
//Author: Will Dull
|
||||
//Notes: Updates emitter.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool updateEmitter();
|
||||
|
||||
virtual ~CDefaultEmitter(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,280 +1,189 @@
|
||||
/*==================================================================
|
||||
|
|
||||
| Name: ParticleEmitter.cpp
|
||||
|
|
||||
|===================================================================
|
||||
|
|
||||
| Author: Ben Vinegar
|
||||
| Contact: benvinegar () hotmail ! com
|
||||
|
|
||||
|
|
||||
| Last Modified: 03/08/04
|
||||
|
|
||||
| Overview: Particle emitter class that emits particles from
|
||||
| an origin (or area) with a variety of set colours,
|
||||
| durations, forces and a single common sprite.
|
||||
|
|
||||
|
|
||||
| Usage: Instantiate one emitter per desired effect. Set the
|
||||
| various fields (preferably all, the defaults are rather
|
||||
| boring) and then call Frame() - you guessed it - every
|
||||
| frame.
|
||||
|
|
||||
| To do: TBA
|
||||
|
|
||||
| More Information: TBA
|
||||
|
|
||||
==================================================================*/
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: ParticleEmitter.cpp
|
||||
// Date: 6/29/05
|
||||
// Author: Will Dull
|
||||
// Purpose: The base particle and emitter
|
||||
// classes implementations.
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
#include "timer.h"
|
||||
#include "ogl.h"
|
||||
#include <stdlib.h>
|
||||
#include "ParticleEngine.h"
|
||||
|
||||
using namespace std;
|
||||
#define PAR_LOG(a,b,c) LOG_SYS::GetInstance()->WriteC(a, LOG_SYS::OBJ, b, c)
|
||||
|
||||
CParticleEmitter::CParticleEmitter() :
|
||||
m_origin(0.0f, 0.0f, 0.0f),
|
||||
m_originSpread(0.0f, 0.0f, 0.0f),
|
||||
m_velocity(0.0f, 0.0f, 0.0f),
|
||||
m_velocitySpread(0.0f, 0.0f, 0.0f),
|
||||
m_gravity(0.0f, 0.0f, 0.0f),
|
||||
m_maxParticles(0),
|
||||
m_minParticles(0),
|
||||
m_numParticles(0),
|
||||
m_maxLifetime(0),
|
||||
m_minLifetime(0),
|
||||
m_timeOfLastFrame(0.0f),
|
||||
m_timeSinceLastEmit(0.0f)
|
||||
{
|
||||
m_particles.clear();
|
||||
}
|
||||
|
||||
CParticleEmitter::~CParticleEmitter()
|
||||
{
|
||||
}
|
||||
|
||||
void CParticleEmitter::Frame()
|
||||
{
|
||||
Update();
|
||||
Render();
|
||||
}
|
||||
|
||||
void CParticleEmitter::Render()
|
||||
CEmitter::CEmitter(const int MAX_PARTICLES, const int lifetime, int textureID)
|
||||
{
|
||||
particleCount = 0;
|
||||
// declare the pool of nodes
|
||||
max_particles = MAX_PARTICLES;
|
||||
heap = new tParticle[max_particles];
|
||||
emitterLife = lifetime;
|
||||
decrementLife = true;
|
||||
decrementAlpha = true;
|
||||
renderParticles = true;
|
||||
isFinished = false;
|
||||
updateSpeed = 0.02f;
|
||||
blend_mode = 1;
|
||||
size = 0.15f;
|
||||
texture = textureID;
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
// init the used/open list
|
||||
usedList = NULL;
|
||||
openList = NULL;
|
||||
|
||||
glAlphaFunc(GL_GREATER, 0.0f);
|
||||
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
|
||||
vector<CParticle *>::iterator itor = m_particles.begin();
|
||||
while (itor != m_particles.end())
|
||||
// link all the particles in the heap
|
||||
// into one large open list
|
||||
for(int i = 0; i < max_particles - 1; i++)
|
||||
{
|
||||
CParticle * curParticle = (*itor);
|
||||
|
||||
curParticle->Frame();
|
||||
++itor;
|
||||
heap[i].next = &(heap[i + 1]);
|
||||
}
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
openList = heap;
|
||||
}
|
||||
|
||||
void CParticleEmitter::Update()
|
||||
CEmitter::~CEmitter(void)
|
||||
{
|
||||
double timeElapsed = get_time() - m_timeOfLastFrame;
|
||||
|
||||
// update existing particles
|
||||
vector<CParticle *>::iterator itor = m_particles.begin();
|
||||
while (itor != m_particles.end())
|
||||
/*int open = 0;
|
||||
int used = 0;
|
||||
int final = 0;
|
||||
tParticle *iter = openList;
|
||||
while(iter)
|
||||
{
|
||||
CParticle * curParticle = (*itor);
|
||||
open++;
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
curParticle->Update();
|
||||
iter = usedList;
|
||||
while(iter)
|
||||
{
|
||||
used++;
|
||||
iter = iter->next;
|
||||
}
|
||||
final = open + used;*/
|
||||
|
||||
// destroy particle if it has lived beyond its duration
|
||||
if (curParticle->m_timeElapsedTotal >= curParticle->m_duration)
|
||||
delete [] heap;
|
||||
}
|
||||
|
||||
bool CEmitter::addParticle()
|
||||
{
|
||||
tColor start, end;
|
||||
float fYaw, fPitch, fSpeed;
|
||||
|
||||
if(!openList)
|
||||
return false;
|
||||
|
||||
if(particleCount < max_particles)
|
||||
{
|
||||
// get a particle from the open list
|
||||
tParticle *particle = openList;
|
||||
|
||||
// set it's initial position to the emitter's position
|
||||
particle->pos.x = pos.x;
|
||||
particle->pos.y = pos.y;
|
||||
particle->pos.z = pos.z;
|
||||
|
||||
// Calculate the starting direction vector
|
||||
fYaw = yaw + (yawVar * RandomNum());
|
||||
fPitch = pitch + (pitchVar * RandomNum());
|
||||
|
||||
// Convert the rotations to a vector
|
||||
RotationToDirection(fPitch,fYaw,&particle->dir);
|
||||
|
||||
// Multiply in the speed factor
|
||||
fSpeed = speed + (speedVar * RandomNum());
|
||||
particle->dir.x *= fSpeed;
|
||||
particle->dir.y *= fSpeed;
|
||||
particle->dir.z *= fSpeed;
|
||||
|
||||
// Calculate the life span
|
||||
particle->life = life + (int)((float)lifeVar * RandomNum());
|
||||
|
||||
// Calculate the colors
|
||||
start.r = startColor.r + (startColorVar.r * RandomChar());
|
||||
start.g = startColor.g + (startColorVar.g * RandomChar());
|
||||
start.b = startColor.b + (startColorVar.b * RandomChar());
|
||||
end.r = endColor.r + (endColorVar.r * RandomChar());
|
||||
end.g = endColor.g + (endColorVar.g * RandomChar());
|
||||
end.b = endColor.b + (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;
|
||||
|
||||
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
|
||||
//tParticleNode *tempNode = openList; // get the top of the list that we have been filling in
|
||||
//openList = tempNode->next;
|
||||
//tempNode->next = usedList; // have it link to the top of the used list
|
||||
//usedList = tempNode; // set the new linked node as the start of the list
|
||||
openList = particle->next;
|
||||
particle->next = usedList;
|
||||
usedList = particle;
|
||||
|
||||
// update the length of the used list (particle Count)
|
||||
particleCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CEmitter::renderEmitter()
|
||||
{
|
||||
if(renderParticles)
|
||||
{
|
||||
switch(blend_mode)
|
||||
{
|
||||
m_particles.erase(itor);
|
||||
delete curParticle;
|
||||
--m_numParticles;
|
||||
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;
|
||||
}
|
||||
|
||||
++itor;
|
||||
}
|
||||
// Bind the texture. Use the texture assigned to this emitter.
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
double secondsPerEmit = 1 / (m_minParticles / m_minLifetime);
|
||||
|
||||
if (m_timeSinceLastEmit > secondsPerEmit)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
{
|
||||
tParticle *tempParticle = usedList;
|
||||
|
||||
float duration;
|
||||
CVector3D position, velocity;
|
||||
float colour[4];
|
||||
|
||||
bool moreParticlesToEmit = true;
|
||||
while (moreParticlesToEmit) {
|
||||
CParticle * newParticle = new CParticle();
|
||||
|
||||
// calculate particle duration
|
||||
duration = (float)m_minLifetime;
|
||||
duration += (rand() % (int)((m_maxLifetime - m_minLifetime) * 1000.0f + 1)) / 1000.0f;
|
||||
newParticle->m_duration = duration;
|
||||
|
||||
// calculate particle start position from spread
|
||||
position = m_origin;
|
||||
position.X += (rand() % (int)(m_originSpread.X * 2000.0f + 1)) / 1000.0f - m_originSpread.X;
|
||||
position.Y += (rand() % (int)(m_originSpread.Y * 2000.0f + 1)) / 1000.0f - m_originSpread.Y;
|
||||
position.Z += (rand() % (int)(m_originSpread.Z * 2000.0f + 1)) / 1000.0f - m_originSpread.Z;
|
||||
newParticle->m_position = position;
|
||||
|
||||
// calculate particle velocity from spread
|
||||
velocity = m_velocity;
|
||||
velocity.X += (rand() % (int)(m_velocitySpread.X * 2000.0f + 1)) / 1000.0f - m_velocitySpread.X;
|
||||
velocity.Y += (rand() % (int)(m_velocitySpread.Y * 2000.0f + 1)) / 1000.0f - m_velocitySpread.Y;
|
||||
velocity.Z += (rand() % (int)(m_velocitySpread.Z * 2000.0f + 1)) / 1000.0f - m_velocitySpread.Z;
|
||||
newParticle->m_velocity = velocity;
|
||||
|
||||
newParticle->m_gravity = m_gravity;
|
||||
|
||||
// calculate and assign colour
|
||||
memcpy2(colour, m_startColour, sizeof(float) * 4);
|
||||
colour[0] += (rand() % (int)((m_endColour[0] - m_startColour[0]) * 1000.0f + 1)) / 1000.0f;
|
||||
colour[1] += (rand() % (int)((m_endColour[1] - m_startColour[1]) * 1000.0f + 1)) / 1000.0f;
|
||||
colour[2] += (rand() % (int)((m_endColour[2] - m_startColour[2]) * 1000.0f + 1)) / 1000.0f;
|
||||
colour[3] += (rand() % (int)((m_endColour[3] - m_startColour[3]) * 1000.0f + 1)) / 1000.0f;
|
||||
memcpy2(newParticle->m_colour, colour, sizeof(float) * 4);
|
||||
|
||||
// assign sprite
|
||||
newParticle->m_sprite = m_sprite;
|
||||
|
||||
// final pre-processing init call
|
||||
newParticle->Init();
|
||||
|
||||
// add to vector of particles
|
||||
m_particles.push_back(newParticle);
|
||||
|
||||
timeElapsed -= secondsPerEmit;
|
||||
if (timeElapsed < secondsPerEmit)
|
||||
while(tempParticle)
|
||||
{
|
||||
moreParticlesToEmit = false;
|
||||
tColor *pColor = &(tempParticle->color);
|
||||
glColor4ub(pColor->r,pColor->g, pColor->b, (GLubyte)tempParticle->alpha);
|
||||
glTexCoord2d(0.0, 0.0);
|
||||
tVector *pPos = &(tempParticle->pos);
|
||||
glVertex3f(pPos->x - size, pPos->y + size, pPos->z);
|
||||
glTexCoord2d(0.0, 1.0);
|
||||
glVertex3f(pPos->x - size, pPos->y - size, pPos->z);
|
||||
glTexCoord2d(1.0, 1.0);
|
||||
glVertex3f(pPos->x + size, pPos->y - size, pPos->z);
|
||||
glTexCoord2d(1.0, 0.0);
|
||||
glVertex3f(pPos->x + size, pPos->y + size, pPos->z);
|
||||
tempParticle = tempParticle->next;
|
||||
}
|
||||
|
||||
|
||||
++m_numParticles;
|
||||
}
|
||||
m_timeSinceLastEmit = 0.0f;
|
||||
glEnd();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
m_timeSinceLastEmit += (float)timeElapsed;
|
||||
|
||||
m_timeOfLastFrame = get_time();
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetSprite(CSprite * sprite)
|
||||
{
|
||||
m_sprite = sprite;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetOrigin(CVector3D origin)
|
||||
{
|
||||
m_origin = origin;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetOrigin(float x, float y, float z)
|
||||
{
|
||||
m_origin.X = x;
|
||||
m_origin.Y = y;
|
||||
m_origin.Z = z;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetOriginSpread(CVector3D spread)
|
||||
{
|
||||
m_originSpread = spread;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetOriginSpread(float x, float y, float z)
|
||||
{
|
||||
m_originSpread.X = x;
|
||||
m_originSpread.Y = y;
|
||||
m_originSpread.Z = z;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetGravity(CVector3D gravity)
|
||||
{
|
||||
m_gravity = gravity;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetGravity(float x, float y, float z)
|
||||
{
|
||||
m_gravity.X = x;
|
||||
m_gravity.Y = y;
|
||||
m_gravity.Z = z;
|
||||
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetVelocity(CVector3D velocity)
|
||||
{
|
||||
m_velocity = velocity;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetVelocity(float x, float y, float z)
|
||||
{
|
||||
m_velocity.X = x;
|
||||
m_velocity.Y = y;
|
||||
m_velocity.Z = z;
|
||||
}
|
||||
|
||||
|
||||
void CParticleEmitter::SetVelocitySpread(CVector3D spread)
|
||||
{
|
||||
m_velocitySpread = spread;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetVelocitySpread(float x, float y, float z)
|
||||
{
|
||||
m_velocitySpread.X = x;
|
||||
m_velocitySpread.Y = y;
|
||||
m_velocitySpread.Z = z;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetStartColour(float r, float g, float b, float a)
|
||||
{
|
||||
m_startColour[0] = r;
|
||||
m_startColour[1] = g;
|
||||
m_startColour[2] = b;
|
||||
m_startColour[3] = a;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetEndColour(float r, float g, float b, float a)
|
||||
{
|
||||
m_endColour[0] = r;
|
||||
m_endColour[1] = g;
|
||||
m_endColour[2] = b;
|
||||
m_endColour[3] = a;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetMaxLifetime(double maxLife)
|
||||
{
|
||||
m_maxLifetime = maxLife;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetMinLifetime(double minLife)
|
||||
{
|
||||
m_minLifetime = minLife;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetMaxParticles(int maxParticles)
|
||||
{
|
||||
m_maxParticles = maxParticles;
|
||||
}
|
||||
|
||||
void CParticleEmitter::SetMinParticles(int minParticles)
|
||||
{
|
||||
m_minParticles = minParticles;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -1,119 +1,268 @@
|
||||
/*==================================================================
|
||||
|
|
||||
| Name: ParticleEmitter.h
|
||||
|
|
||||
|===================================================================
|
||||
|
|
||||
| Author: Ben Vinegar
|
||||
| Contact: benvinegar () hotmail ! com
|
||||
|
|
||||
|
|
||||
| Last Modified: 03/08/04
|
||||
|
|
||||
| Overview: Particle emitter class that emits particles from
|
||||
| an origin (or area) with a variety of set colours,
|
||||
| durations, forces and a single common sprite.
|
||||
|
|
||||
|
|
||||
| Usage: Instantiate one emitter per desired effect. Set the
|
||||
| various fields (preferably all, the defaults are rather
|
||||
| boring) and then call Frame() - you guessed it - every
|
||||
| frame.
|
||||
|
|
||||
| To do: TBA
|
||||
|
|
||||
| More Information: TBA
|
||||
|
|
||||
==================================================================*/
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: ParticleEmitter.h
|
||||
// Date: 6/29/05
|
||||
// Author: Will Dull
|
||||
// Purpose: The base particle and emitter
|
||||
// classes.
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PARTICLE_EMITTER_H
|
||||
#define PARTICLE_EMITTER_H
|
||||
#ifndef _PARTICLEEMITTER_H_
|
||||
#define _PARTICLEEMITTER_H_
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Includes / Compiler directives
|
||||
//--------------------------------------------------------
|
||||
#include "precompiled.h"
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include "ogl.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "Particle.h"
|
||||
#include "Sprite.h"
|
||||
#include "Vector3D.h"
|
||||
#include <vector>
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#define HALF_PI 1.57079632679489661923f
|
||||
|
||||
#define DEGTORAD(d) ((d * (float)M_PI) / 180.0f);
|
||||
#define RADTODEG(r) ((r * 180.0f) /(float)M_PI);
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Declarations
|
||||
//--------------------------------------------------------
|
||||
const int HALF_RAND = (RAND_MAX / 2);
|
||||
|
||||
class CParticleEmitter
|
||||
struct tVector
|
||||
{
|
||||
public:
|
||||
CParticleEmitter();
|
||||
~CParticleEmitter();
|
||||
|
||||
// must be performed before first frame/render/update call
|
||||
bool Init();
|
||||
|
||||
// renders and updates particles
|
||||
void Frame();
|
||||
|
||||
// renders without updating particles
|
||||
void Render();
|
||||
|
||||
void Update();
|
||||
|
||||
void SetSprite(CSprite * sprite);
|
||||
|
||||
void SetOrigin(CVector3D origin);
|
||||
void SetOrigin(float x, float y, float z);
|
||||
|
||||
void SetOriginSpread(CVector3D spread);
|
||||
void SetOriginSpread(float x, float y, float z);
|
||||
|
||||
void SetGravity(CVector3D gravity);
|
||||
void SetGravity(float x, float y, float z);
|
||||
|
||||
void SetVelocity(CVector3D direction);
|
||||
void SetVelocity(float x, float y, float z);
|
||||
|
||||
void SetVelocitySpread(CVector3D spread);
|
||||
void SetVelocitySpread(float x, float y, float z);
|
||||
|
||||
void SetStartColour(float r, float g, float b, float a);
|
||||
void SetEndColour(float r, float g, float b, float a);
|
||||
|
||||
// in milliseconds
|
||||
void SetMaxLifetime(double maxLife);
|
||||
|
||||
// in milliseconds
|
||||
void SetMinLifetime(double minLife);
|
||||
|
||||
void SetMaxParticles(int maxParticles);
|
||||
void SetMinParticles(int minParticles);
|
||||
|
||||
private:
|
||||
CSprite * m_sprite;
|
||||
|
||||
std::vector<CParticle *> m_particles;
|
||||
|
||||
CVector3D m_origin;
|
||||
CVector3D m_originSpread;
|
||||
|
||||
CVector3D m_velocity;
|
||||
CVector3D m_velocitySpread;
|
||||
|
||||
CVector3D m_gravity;
|
||||
|
||||
float m_startColour[4];
|
||||
float m_endColour[4];
|
||||
|
||||
int m_maxParticles;
|
||||
int m_minParticles;
|
||||
int m_numParticles;
|
||||
|
||||
double m_maxLifetime;
|
||||
double m_minLifetime;
|
||||
|
||||
double m_timeOfLastFrame;
|
||||
float m_timeSinceLastEmit;
|
||||
float x,y,z;
|
||||
};
|
||||
|
||||
#endif // PARTICLE_EMITTER_H
|
||||
class CEmitter
|
||||
{
|
||||
public:
|
||||
struct tColor
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
struct tParticle
|
||||
{
|
||||
// base stuff
|
||||
tVector pos; // Current position 12
|
||||
tVector 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
|
||||
tVector 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:
|
||||
int texture; // Texture ID
|
||||
bool isFinished; // tells the engine it's ready to be deleted
|
||||
|
||||
// Transformation Info
|
||||
tVector pos; // XYZ Position
|
||||
tVector finalPos; // Final position of the particles (IF IMPLOSION)
|
||||
float yaw, yawVar; // Yaw and variation
|
||||
float pitch, pitchVar; // Pitch and variation
|
||||
float speed, speedVar; // Speed and variation
|
||||
float updateSpeed; // Controls how fast emitter is updated.
|
||||
float size; // size of the particles (if point sprites is not enabled)
|
||||
|
||||
// Particle
|
||||
tParticle *heap; // Pointer to beginning of array
|
||||
|
||||
tParticle *openList; // linked list of unused particles
|
||||
tParticle *usedList; // linked list of used particles
|
||||
|
||||
int blend_mode; // Method used to blend particles.
|
||||
int max_particles; // Maximum particles emitter can put out
|
||||
int particleCount; // Total emitted right now
|
||||
int emitsPerFrame, emitVar; // Emits per frame and variation
|
||||
int life, lifeVar; // Life count and variation (in Frames)
|
||||
int emitterLife; // Life of the emitter
|
||||
bool decrementLife; // Controls whether or not the particles life is decremented every update.
|
||||
bool decrementAlpha; // Controls whether or not the particles alpha is decremented every update.
|
||||
bool renderParticles; // Controls the rendering of the particles.
|
||||
tColor startColor, startColorVar; // Current color of particle
|
||||
tColor endColor, endColorVar; // Current color of particle
|
||||
|
||||
// Physics
|
||||
tVector force; // Forces that affect the particles
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
CEmitter(const int MAX_PARTICLES = 4000, const int lifetime = -1, int textureID = 0);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: setupEmitter
|
||||
//Date: 9/18/05
|
||||
//Author: Will Dull
|
||||
//Notes: Setup emitter. Setup so that a derived class can
|
||||
// overload this function to suit the specific particles
|
||||
// needs.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool setupEmitter() { return false;}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: addParticle
|
||||
//Date: 9/18/05
|
||||
//Author: Will Dull
|
||||
//Notes: Sets up and adds a particle to an emitter. Setup so
|
||||
// that a derived class can overload this function to
|
||||
// suit the specific particles needs.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool addParticle();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: updateEmitter
|
||||
//Date: 9/18/05
|
||||
//Author: Will Dull
|
||||
//Notes: Updates emitter. Setup so that a derived class can
|
||||
// overload this function to suit the specific particles
|
||||
// needs.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool updateEmitter() { return false; }
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: renderEmitter
|
||||
//Date: 9/18/05
|
||||
//Author: Will Dull
|
||||
//Notes: Renders emitter. Setup so that a derived class can
|
||||
// overload this function to suit the specific particles
|
||||
// needs.
|
||||
//////////////////////////////////////////////////////////////
|
||||
virtual bool renderEmitter();
|
||||
|
||||
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, tVector *direction)
|
||||
{
|
||||
direction->x = (float)(-sin(yaw) * cos(pitch));
|
||||
direction->y = (float)sin(pitch);
|
||||
direction->z = (float)(cos(pitch) * cos(yaw));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
float getPosX() { return pos.x; }
|
||||
float getPosY() { return pos.y; }
|
||||
float getPosZ() { return pos.z; }
|
||||
tVector getPosVec() { return pos; }
|
||||
float getFinalPosX() { return finalPos.x; }
|
||||
float getFinalPosY() { return finalPos.y; }
|
||||
float getFinalPosZ() { return finalPos.z; }
|
||||
bool getIsFinished(void) { return isFinished; }
|
||||
int getEmitterLife() { return emitterLife; }
|
||||
int getParticleCount() { return particleCount; }
|
||||
float getUpdateSpeed() { return updateSpeed; }
|
||||
int getMaxParticles(void) { return max_particles; }
|
||||
tColor getStartColor(void) { return startColor; }
|
||||
tColor getStartColorVar(void) { return startColorVar; }
|
||||
tColor getEndColor(void) { return endColor; }
|
||||
tColor getEndColorVar(void) { return endColorVar; }
|
||||
int getBlendMode(void) { return blend_mode; }
|
||||
float getSize(void) { return size; }
|
||||
float getYaw(void) { return yaw; }
|
||||
float getYawVar(void) { return yawVar; }
|
||||
float getPitch(void) { return pitch; }
|
||||
float getPitchVar(void) { return pitchVar; }
|
||||
float getSpeed(void) { return speed; }
|
||||
float getSpeedVar(void) { return speedVar; }
|
||||
int getEmitsPerFrame(void) { return emitsPerFrame; }
|
||||
int getEmitVar(void) { return emitVar; }
|
||||
int getLife(void) { return life; }
|
||||
int getLifeVar(void) { return lifeVar; }
|
||||
float getForceX(void) { return force.x; }
|
||||
float getForceY(void) { return force.y; }
|
||||
float getForceZ(void) { return force.z; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Mutators
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
void setPosX(float posX) { pos.x = posX; }
|
||||
void setPosY(float posY) { pos.y = posY; }
|
||||
void setPosZ(float posZ) { pos.z = posZ; }
|
||||
inline void setPosVec(tVector newPos)
|
||||
{
|
||||
pos.x = newPos.x;
|
||||
pos.y = newPos.y;
|
||||
pos.z = newPos.z;
|
||||
}
|
||||
void setFinalPosX(float finalposX) { finalPos.x = finalposX; }
|
||||
void setFinalPosY(float finalposY) { finalPos.y = finalposY; }
|
||||
void setFinalPosZ(float finalposZ) { finalPos.z = finalposZ; }
|
||||
void setTexture(int id) { texture = id; }
|
||||
void setIsFinished(bool finished) { isFinished = finished; }
|
||||
void setEmitterLife(int life) { emitterLife = life; }
|
||||
void setUpdateSpeed(float speed) { updateSpeed = speed; }
|
||||
void setLife(int newlife) { life = newlife; }
|
||||
void setLifeVar(int newlifevar) { lifeVar = newlifevar; }
|
||||
void setSpeed(float newspeed) { speed = newspeed; }
|
||||
void setSpeedVar(float newspeedvar) { speedVar = newspeedvar; }
|
||||
void setYaw(float newyaw) { yaw = newyaw; }
|
||||
void setYawVar(float newyawvar) { yawVar = newyawvar; }
|
||||
void setPitch(float newpitch) { pitch = newpitch; }
|
||||
void setPitchVar(float newpitchvar) { pitchVar = newpitchvar; }
|
||||
void setStartColor(tColor newColor) { startColor = newColor; }
|
||||
void setStartColorVar(tColor newColorVar) { startColorVar = newColorVar; }
|
||||
void setEndColor(tColor newColor) { endColor = newColor; }
|
||||
void setEndColorVar(tColor newColorVar) { endColorVar = newColorVar; }
|
||||
void setStartColorR(int newColorR) { startColor.r = newColorR; }
|
||||
void setStartColorG(int newColorG) { startColor.g = newColorG; }
|
||||
void setStartColorB(int newColorB) { startColor.b = newColorB; }
|
||||
void setStartColorVarR(int newColorVarR) { startColorVar.r = newColorVarR; }
|
||||
void setStartColorVarG(int newColorVarG) { startColorVar.g = newColorVarG; }
|
||||
void setStartColorVarB(int newColorVarB) { startColorVar.b = newColorVarB; }
|
||||
void setEndColorR(int newColorR) { endColor.r = newColorR; }
|
||||
void setEndColorG(int newColorG) { endColor.g = newColorG; }
|
||||
void setEndColorB(int newColorB) { endColor.b = newColorB; }
|
||||
void setEndColorVarR(int newColorVarR) { endColorVar.r = newColorVarR; }
|
||||
void setEndColorVarG(int newColorVarG) { endColorVar.g = newColorVarG; }
|
||||
void setEndColorVarB(int newColorVarB) { endColorVar.b = newColorVarB; }
|
||||
inline void setBlendMode(int blendmode)
|
||||
{
|
||||
if(blendmode >= 1 && blendmode <= 4)
|
||||
blend_mode = blendmode;
|
||||
else
|
||||
blend_mode = 1;
|
||||
}
|
||||
void setEmitsPerFrame(int emitsperframe) { emitsPerFrame = emitsperframe; }
|
||||
void setEmitVar(int emitvar) { emitVar = emitvar; }
|
||||
void setForceX(float forceX) { force.x = forceX; }
|
||||
void setForceY(float forceY) { force.y = forceY; }
|
||||
void setForceZ(float forceZ) { force.z = forceZ; }
|
||||
void setSize(float newSize) { size = newSize; }
|
||||
void setRenderParticles(bool render) { renderParticles = render; }
|
||||
|
||||
|
||||
// Destructor
|
||||
virtual ~CEmitter(void);
|
||||
};
|
||||
|
||||
#endif
|
253
source/graphics/ParticleEngine.cpp
Normal file
253
source/graphics/ParticleEngine.cpp
Normal file
@ -0,0 +1,253 @@
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: ParticleEngine.cpp
|
||||
// Date: 6/29/05
|
||||
// Author: Will Dull
|
||||
// Purpose: The particle engine system
|
||||
// implementation.
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "ParticleEngine.h"
|
||||
#include <windows.h>
|
||||
#include "ogl.h"
|
||||
|
||||
CParticleEngine *CParticleEngine::m_pInstance = 0;
|
||||
CParticleEngine::CParticleEngine(void)
|
||||
{
|
||||
m_pHead = NULL;
|
||||
totalParticles = 0;
|
||||
}
|
||||
|
||||
CParticleEngine::~CParticleEngine(void)
|
||||
{
|
||||
//// Release all resources.
|
||||
//for(int i = 0; i < MAX_TEXTURES; i++)
|
||||
// glDeleteTextures(1, &idTexture[i]);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// Needs error checking and testing.
|
||||
idTexture[DEFAULTTEXT] = ogl_tex_load("art/textures/particles/sprite.tga");
|
||||
idTexture[DEFAULTTEXT] = ogl_tex_bind(idTexture[DEFAULTTEXT], 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, idTexture[DEFAULTTEXT]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
|
||||
//glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
|
||||
//glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);
|
||||
//glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CParticleEngine::addEmitter(CEmitter *emitter, int type, int ID)
|
||||
{
|
||||
// without array you could do:
|
||||
//emitter->texture = type + idTextureBase;
|
||||
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()
|
||||
{
|
||||
tEmitterNode *temp = m_pHead;
|
||||
totalParticles = 0;
|
||||
while(temp)
|
||||
{
|
||||
// are we ready for deletion?
|
||||
if(temp->pEmitter->getIsFinished())
|
||||
{
|
||||
// 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->updateEmitter();
|
||||
|
||||
// Add current emitter to particle count
|
||||
totalParticles += temp->pEmitter->getParticleCount();
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CParticleEngine::renderParticles()
|
||||
{
|
||||
EnterParticleContext();
|
||||
|
||||
tEmitterNode *temp = m_pHead;
|
||||
while(temp)
|
||||
{
|
||||
temp->pEmitter->renderEmitter();
|
||||
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);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDepthMask(true);
|
||||
glPopMatrix();
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
142
source/graphics/ParticleEngine.h
Normal file
142
source/graphics/ParticleEngine.h
Normal file
@ -0,0 +1,142 @@
|
||||
/////////////////////////////////////////////////////
|
||||
// File Name: ParticleEngine.h
|
||||
// Date: 6/29/05
|
||||
// Author: Will Dull
|
||||
// Purpose: The particle engine system.
|
||||
// controls and maintain particles
|
||||
// through emitters that are passed
|
||||
// into each of the main functions.
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _PARTICLEENGINE_H_
|
||||
#define _PARTICLEENGINE_H_
|
||||
|
||||
#include "ParticleEmitter.h"
|
||||
#include "lib/res/graphics/tex.h"
|
||||
#include "lib/res/graphics/ogl_tex.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Loader.h"
|
||||
|
||||
// Different textures
|
||||
enum PText { DEFAULTTEXT, MAX_TEXTURES };
|
||||
// Different emitters
|
||||
enum PEmit { DEFAULTEMIT, MAX_EMIT };
|
||||
|
||||
class CParticleEngine
|
||||
{
|
||||
public:
|
||||
virtual ~CParticleEngine(void);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: GetInstance
|
||||
//Date: 8/1/05
|
||||
//Author: Will Dull
|
||||
//Purpose: returns the instance of the singleton class
|
||||
//////////////////////////////////////////////////////////////
|
||||
static CParticleEngine* GetInstance();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: DeleteInstance
|
||||
//Date: 8/1/05
|
||||
//Author: Will Dull
|
||||
//Purpose: deletes the instance of the singleton class
|
||||
//////////////////////////////////////////////////////////////
|
||||
static void DeleteInstance();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: initParticleSystem
|
||||
//Date: 6/29/05
|
||||
//Author: Will Dull
|
||||
//Out: True if particle system initialized correctly,
|
||||
// false otherwise
|
||||
//Purpose: inits particle system.
|
||||
//////////////////////////////////////////////////////////////
|
||||
bool initParticleSystem(void);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: addEmitter
|
||||
//Date: 7/20/05
|
||||
//Author: Will Dull
|
||||
//In: emitter to add, texture type, id of emitter
|
||||
//Out: True if emitter added correctly,
|
||||
// false otherwise
|
||||
//Purpose: adds the emitter to the engines list
|
||||
//////////////////////////////////////////////////////////////
|
||||
bool addEmitter(CEmitter *emitter, int type = DEFAULTTEXT, int ID = DEFAULTEMIT);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: findEmitter
|
||||
//Date: 7/21/05
|
||||
//Author: Will Dull
|
||||
//In: id of emitter to find
|
||||
//Out: the emitter if found,
|
||||
// NULL otherwise
|
||||
//Purpose: finds the emitter using its ID
|
||||
//////////////////////////////////////////////////////////////
|
||||
CEmitter* findEmitter(int ID);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: updateEmitters
|
||||
//Date: 7/20/05
|
||||
//Author: Will Dull
|
||||
//Purpose: Checks if the emitter is ready to be deleted
|
||||
// and removed. If not it calls the emitters update
|
||||
// function.
|
||||
//////////////////////////////////////////////////////////////
|
||||
void updateEmitters();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: renderParticles
|
||||
//Date: 7/20/05
|
||||
//Author: Will Dull
|
||||
//Purpose: Renders the emitter and all it's particles
|
||||
//////////////////////////////////////////////////////////////
|
||||
void renderParticles();
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: destroyAllEmitters
|
||||
//Date: 8/1/05
|
||||
//Author: Will Dull
|
||||
//In: fade - if true, will allow the emitter to fade itself out
|
||||
// if false, emitter and particles will disappear instantly
|
||||
//Purpose: Destroys every active emitter on screen.
|
||||
//////////////////////////////////////////////////////////////
|
||||
void destroyAllEmitters(bool fade = true);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//Func Name: cleanup
|
||||
//Date: 8/3/05
|
||||
//Author: Will Dull
|
||||
//Purpose: Any cleanup 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
|
||||
|
||||
Handle 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
|
Loading…
Reference in New Issue
Block a user