CS 491 -- Fall Quarter 2022

Project #5: Particle System

Due: November 12

100 Points


This page was last undated: September 13, 2022


Requirements

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. :-)

Hints

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.

How to do Various Graphics Things

Yeah, I know. I said that this was not a graphics course, but you do need to know some graphics to do this.

  1. The Animate( ) function is this program's "Idle Function". An Idle Function is what gets called when there is nothing else going on (which is most of the time). Thus, you should use Animate( ) to loop through all of your particles and update their information, something like 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 >>
    		. . .
    	}
    

  2. But, you do need to handle birth time and death times, so you will need to be sure your particle starts moving when Time = the birth 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 >>
    			. . .
    		}
    	}
    

  3. Be sure the lines:
    
    	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.

  4. All drawing takes place in the Display( ) function. The basic drawing of points looks like this:

    
    	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.

  5. Like you see above, a point's color is set by inserting the line:

    
    	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.)

    ColorRGB
    Black0.0.0.
    White1.1.1.
    Red1.0.0.
    Orange1.0.50.
    Yellow1.1.0.
    Green0.1.0.
    Cyan0.1.1.
    Blue0.0.1.
    Magenta1.0.1.

  6. A point's size can be changed by inserting the line:

    
    	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.

Creating Randomness

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.

Running Your Program

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.

Turn-In

Your electronic turnin will be done at http://engr.oregonstate.edu/teach and will consist of:

  1. Your source code (.cpp) file
  2. A one-page PDF with a title, your name, your email address, a nice screen shot from your program, and the link to the Kaltura video demonstrating that your project does what the requirements ask for. If you narrate your video, then you get to tell us what it is doing, and we can grade it more accurately.
    Be sure that your video is flagged as unlisted.
    A good way to test this is to ask a friend to try to open the same video link that you are giving us.
  3. Leave your PDF file out by itself -- do not place it in any zip files.

This is due at 23:59:59 on the listed due date.

Grading

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