/**
* ParticleEngine class by Justin Klein, 2003
* Major Overhaul in 2004
*
* This class implements a particle engine in
OpenGL that supports gravity, local attractors, varying particle
* lifetimes, velocities, emission angles, point
sources, line sources, and real-time level of detail adjustments.
* Each of these features can be set with a
call to one of the functions that are documented below.
**/
class ParticleEngine
{
public:
ParticleEngine();
~ParticleEngine();
/**
* Initializes the particle engine. Params:
*
* -texture: Pointer
to a texture that will be applied to each particle emitted by this engine.
* -numOfParticles: The MAXIMUM number of particles that can be emitted at one
time by this emitter
* (the number that's currently
emitting can be altered in realtime with a different function call)
*
* There are a large number of other
parameters needed by this engine that get initialized to default values.
* These can be changed by calling any of the
other functions listed below.
**/
int Init(int texture,int
numOfParticles );
/**
* Updates the particles' velocity,
brightness, position, and possibly activating/deactivating particles.
* If this is not called during every frame (along
with Render()), the engine will appear to freeze.
* frameTime must contain the time (in
seconds) taken to render the last frame; this is used for time-based movement
* of the particles.
**/
void Update(float frameTime);
/**
* Renders each particle; this must be called
once for every frame, or nothing will be drawn.
Also, for the
* particles to update their positions,
Update() must be called for every frame.
*
* Nothing will be drawn if the particle
engine has not been initialized with a call to Init().
*
* NOTE: For particles to visibly fade (i.e.
smoke or fire), blending must be enabled; if blending is
*
not enabled, the lifetime of each particle will be the same, but they
will not fade to death
*
(i.e. rocks or water drops).
BlendFunc must be glBlendFunc(GL_SRC_ALPHA, GL_ONE);
*
* NOTE: For particles to be textured,
texturing MUST be enabled before drawParticles() is called.
*
* NOTE: For particle backgrounds to
disasppear (particles to not be square), AlphaTesting MUST be
*
enabled, with its func set as glAlphaFunc(GL_GREATER, 0);
(initParticleEngine automatically does this,
*
however if you change it anywhere, it must be changed back before
rendering particles).
*
* Returns the number of particles that were
actually drawn.
**/
int Render();
/**
* Cleans up our particle engine by
deallocating the memory used to store the particles.
**/
void Cleanup();
/**
* Sets the texture to be used for each particle
emitted by this engine. This must have already been loaded by OpenGL.
**/
int setTexture(unsigned int
/**
* Sets the edge-length of each particle;
return 0 for invalid value. Default is 1.0.
**/
int setParticleSize(float size);
/**
* May be used to reduce or increase the
number of particles currently being rendered, for purposes
* of level-of-detail; valid values are
between 0 and the numOfParticles that was specified when the
* engine was initialized (this is the maximum
number of particles it's capable of rendering without
* re-initializing it).
*
* Returns 1 for success, 0 for error.
**/
int setNumOfParticles(int howMany);
/**
* Returns the number of particles that
currently EXIST. This may be more or
less than the
* number that was specified by
setNumOfParticle (for instance, if the desired number was
* recently changed, this number will be
higher until enough particles die out)
**/
int getNumOfParticles();
/**
* Sets the particle-emitter's color to
(colorR, colorG, colorB);
* every particle that's emitted AFTER the
color-change will be
* emitted in the new color. Returns 1 for success, 0 for bad range.
Default is white.
**/
int setColor(float colorR, float
colorG, float colorB);
/**
* Changes the location from which particles originate.
Default is (0,0,0).
* Note that just calling glTranslatef before
rendering the engine moves the ENTIRE engine, including
* any particles that have already been
emitted, where this only changes the location that new particles
* will be emitted (the SOURCE of the
emitter).
**/
int setPos(float x, float y, float z);
/**
* Changes area over which particles
originate. (0,0,0) is default, and
creates a point source.
* (1,0,0), for example, creates a line source
of length 1 along the X-axis.
**/
int setPosVar(float x, float y, float z);
/**
* Specifies the angle of emission. Note that this is NOT the same as calling
glRotate, which will rotate
* the entire engine and any particles that
have been emitted so far; this changes the direction in which new
* particles are emitted. The specifed angles are AROUND the x-axis and
AROUND the y-axis. Angles are in
degrees.
**/
void setAngle(float x, float y);
/**
* Sets the amount that angles are allowed to
vary in degrees. 0 causes a perfect
line-stream of particles;
* 45 degrees looks like a "spout",
etc.
**/
void setAngleVar(float x, float y);
/**
* Sets the base percentage of the particle's
life that decreases for each frame rendered.
For instance,
* a particle with fadeSpeed = .5 will die
after 2 frames (fades 50% per frame).
Fade speed of 0 is not
* allowed, and will be rounded to a very
small number. Default is 0.05.
**/
int setFade(float fadeSpeed);
/**
* Sets the amount by which the fadeSpeed is
allowed to vary. This causes the
particles to die at
* a variety of different times, so the
emitter is "smooth" (if fadeVar is zero, it will emit
"bursts"
* where every particle dies and is re-emitted
at the same times.) Default is 0.05.
**/
int setFadeVar(float fadeVar);
/**
* Specifies the speed with which particles
are launched (0->1; greater values are allowed). Default is 0.15.
**/
int setVelocity(float velocity);
/**
* Specifies the maximum allowed variation in
velocity (0->1; greater values allowed), so that the particles
* can move at more randomized speeds. Default
is 0.05.
**/
int setVelocityVar(float var);
/**
* Sets the gravity in the x, y, and z
directions. Values can be from -1 to 1,
where
* 0 is no gravity and 1 is the strongest
gravity, -1 is reverse-gravity. Default is 0, 0, 0.
**/
int setGravity(float x, float y, float z);
/**
* Sets the strength of an attractor (aka a
"point" source for gravity, instead of directional).
* Negative strengths repel particles.
Magnitudes normally range between -1 and 1, but can be greater.
* Default is 0 (turned off).
**/
void setAttractorStr(float attractorStrength);
/**
* Sets the position of an attractor. Note that local attractors are off by default
(strength = 0).
**/
void setAttractorPos(float x, float y, float z);