This page was last undated: September 13, 2022
You get to create your own particle system. Your choice of exactly what it does is up to you. You must start out with random positions, random birth times, and random death times. You must also randomize at least two other components of the animation (velocity, color, point size, opacity, etc.). The particles must follow some sort of prescribed motion (that is, it must look intentional).
Warning! Particle system programs are addictive. They should be banned as a controlled substance. Ten years from now, you will still be enhancing this program. :-)
It is often useful to hold the particles in an array of structures. Here is the structure that Joe Graphics used for a single particle in his sample program:
struct particle { float x0, y0, z0; // starting location float vx0, vy0, vz0; // starting velocity float r0, g0, b0; // starting color float birthtime, deathtime; // birth time, death time float x, y, z; // current location float vx, vy, vz; // current velocity float r, g, b; // current color };
You can then create an array of particles by saying:
#define NUMPARTICLES 10000 struct particle Particles[NUMPARTICLES];
You are certainly free to add more features into this structure to make your particle system more sophisticated.
The sample program is setup to display particles whose initial coordinate positions are between -100. and +100. If you use the same range, then all the viewing information will work.
Randomize the particle parameters in the InitGraphics( ) function.
Set all the particle parameters back to their initial conditions in the Reset( ) function.
Yeah, I know. I said that this was not a graphics course, but you do need to know some graphics to do this.
If you were not required to birth and death times, your code would look like this, using a Time that gets incremented in Animate( )::
Time += DT; for( int i = 0; i < NUMPARTICLES; i++ ) { Particles[i].x = << some function of Time >> . . . }
Time += DT; for( int i = 0; i < NUMPARTICLES; i++ ) { if( Particles[i].birthtime <= Time && Time <= Particles[i].deathtime ) { float timeInFlight = Time - Particles[i].birthtime; Particles[i].x = << some function of timeInFlight >> . . . } }
glutSetWindow( MainWindow ); glutPostRedisplay();
stay at the end of Animate( ). They are what force the graphics system to redraw your scene with the newly-computed values.
glBegin( GL_POINTS ); for( int i = 0; i < NUMPARTICLES; i++ ) { if( Particles[i].birthtime <= Time && Time <= Particles[i].deathtime ) { glColor3f( Particles[i].r, Particles[i].g, Particles[i].b ); glVertex3f( Particles[i].x, Particles[i].y, Particles[i].z ); } } glEnd( );Note that you don't draw a particle that has not been born yet or has already died.
glColor3f( Particles[i].r, Particles[i].g, Particles[i].b );
before the call to glVertex3f( ). The red, green, and blue color components are each a floating point number in the range 0.-1. (0. means none of that component, 1. means as much of that component as the display can deliver.)
Color | R | G | B |
---|---|---|---|
Black | 0. | 0. | 0. |
White | 1. | 1. | 1. |
Red | 1. | 0. | 0. |
Orange | 1. | 0.5 | 0. |
Yellow | 1. | 1. | 0. |
Green | 0. | 1. | 0. |
Cyan | 0. | 1. | 1. |
Blue | 0. | 0. | 1. |
Magenta | 1. | 0. | 1. |
glPointSize( size );
before the call to glBegin( GL_POINTS ). size is a floating point number. A size of 1.0 is a single-pixel dot on the screen.
The following code allows you to set random values easily.
#include <stdlib.h> float Ranf( float low, float high ) { float r = (float) rand(); // 0 - RAND_MAX float v = r / (float) RAND_MAX; // 0. - 1. return low + v * ( high - low ); } int Ranf( int ilow, int ihigh ) { float low = (float)ilow; float high = ceil( (float)ihigh ); return (int) Ranf(low,high); }
The particles' randomness needs to be set once somewhere. This is a good use for the InitGraphics( ) function. The wrapper code has a placeholder for it at the end of that function.
To see your program work, here is the file: Particles2019Wrapper.zip , a graphics wrapper program and all the Visual Studio stuff that goes with it. Just unzip all of this into a separate folder and double click on the .sln file.
Your electronic turnin will be done at
http://engr.oregonstate.edu/teach
and will consist of:
This is due at 23:59:59 on the listed due date.
Item | Points |
Position randomized at the start | 15 |
One other item randomized at the start | 15 |
A second other item randomized at the start | 15 |
Position changing during the animation | 15 |
Some sort of deliberate motion | 40 |
Potential Total | 100 |