206 lines
5.5 KiB
C++
Executable File
206 lines
5.5 KiB
C++
Executable File
/*
|
|
* A particle system using triangles and textured particles
|
|
* you can also switch between textured triangles and colored points
|
|
* and you can change the emitter's position/direction.
|
|
*
|
|
* The actual action goes on in particle.h, but I figured main.cpp is where
|
|
* most folks would start reading. This isn't a complete system; I had intended
|
|
* to implement textured particles, but I didn't get that implemented by my 6 am deadline.
|
|
* I'm going to go ahead and leave in the code for textured polys/quads (which
|
|
* does nothing right now) because I intend to implement that in the future.
|
|
*
|
|
* I also haven't profiled this code, so I have no idea how efficient it is. However,
|
|
* since this is my *first ever* attempt at a particle system, I don't think it's
|
|
* too bad considering I churned it out in 6 hours without anyone else's code to guide me.
|
|
* So take this as you will. :)
|
|
*
|
|
* Written with openGL and SDL (http://www.libsdl.org).
|
|
*
|
|
* Andrew Kesterson, Feb. 2005.
|
|
*
|
|
* NOTE: Textured polys are currently not implemented, but now that I have the particles
|
|
* distributing around the emitter properly and fading correctly, it is *definitely* next
|
|
* on the list.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "common.h"
|
|
|
|
int main( int argc, char **argv )
|
|
{
|
|
/* Flags and stuff for the state machine and SDL */
|
|
int videoFlags;
|
|
int done = FALSE;
|
|
SDL_Event event;
|
|
const SDL_VideoInfo *videoInfo;
|
|
int isActive = TRUE;
|
|
GLfloat emitterColors[2][3] = {
|
|
//{1.0, 1.0, 1.0},
|
|
{0.0, 0.0, 0.0},
|
|
{0.0, 0.5, 1.0}};
|
|
Vector emitterSpeeds[2] = {
|
|
{0.00f, 0.0001f, 0.0f},
|
|
{0.00f, 0.005f, 0.0f}};
|
|
Vector emitterGravities[2] = {
|
|
{0.002f, -0.0f, 0.0f},
|
|
{0.00f, -0.00001f, 0.00f}};
|
|
Vector emitterPositions[2] = {
|
|
{0.0f, 0.0f, -50.0f},
|
|
{0.0f, -2.0f, -50.0f}};
|
|
Vector randPositions[2] = {
|
|
{5.7f, 5.7f, 0.0f},
|
|
{.5f, 3.5f, .5f}
|
|
};
|
|
Vector randSpeeds[2] = {
|
|
{0.001f, 0.001f, 0.0f},
|
|
{0.000f, 0.00f, 0.000f}
|
|
};
|
|
Vector randGravities[2] = {
|
|
{0.0f, 0.0f, 0.0f},
|
|
{0.000005f, 0.0f, 0.000005f},
|
|
};
|
|
|
|
srand((long)time(NULL));
|
|
|
|
PopulateEmitter(&theEmitter[0],
|
|
GL_TRUE,
|
|
emitterColors[0],
|
|
0.0001F,
|
|
1000,
|
|
&emitterGravities[0],
|
|
&emitterPositions[0],
|
|
&emitterSpeeds[0],
|
|
&randGravities[0],
|
|
&randPositions[0],
|
|
&randSpeeds[0],
|
|
500,
|
|
GL_POINTS,
|
|
0);
|
|
PopulateEmitter(&theEmitter[1],
|
|
GL_TRUE,
|
|
emitterColors[1],
|
|
0.0002F,
|
|
5000,
|
|
&emitterGravities[1],
|
|
&emitterPositions[1],
|
|
&emitterSpeeds[1],
|
|
&randGravities[1],
|
|
&randPositions[1],
|
|
&randSpeeds[1],
|
|
1400,
|
|
GL_POINTS,
|
|
0);
|
|
|
|
|
|
/* initialize SDL */
|
|
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
|
|
{
|
|
fprintf( stderr, "Video initialization failed: %s\n",
|
|
SDL_GetError( ) );
|
|
Quit( 1 );
|
|
}
|
|
|
|
/* Fetch the video info */
|
|
videoInfo = SDL_GetVideoInfo( );
|
|
|
|
if ( !videoInfo )
|
|
{
|
|
fprintf( stderr, "Video query failed: %s\n",
|
|
SDL_GetError( ) );
|
|
Quit( 1 );
|
|
}
|
|
|
|
/* Ask SDL for a OpenGL double buffered context with various flags. */
|
|
videoFlags = SDL_OPENGL;
|
|
videoFlags |= SDL_GL_DOUBLEBUFFER;
|
|
videoFlags |= SDL_HWPALETTE;
|
|
videoFlags |= SDL_RESIZABLE;
|
|
|
|
/* Can we have hardware surfaces? */
|
|
if ( videoInfo->hw_available )
|
|
videoFlags |= SDL_HWSURFACE;
|
|
else
|
|
videoFlags |= SDL_SWSURFACE;
|
|
|
|
/* Hardware blits? */
|
|
if ( videoInfo->blit_hw )
|
|
videoFlags |= SDL_HWACCEL;
|
|
|
|
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
|
|
|
/* get the main SDL surface */
|
|
surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
|
|
videoFlags );
|
|
|
|
if ( !surface )
|
|
{
|
|
fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
|
|
Quit( 1 );
|
|
}
|
|
|
|
if ( initGL( ) == FALSE )
|
|
{
|
|
fprintf( stderr, "Could not initialize OpenGL.\n" );
|
|
Quit( 1 );
|
|
}
|
|
|
|
resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
|
|
|
|
/* wait for events */
|
|
while ( !done )
|
|
{
|
|
/* handle the events in the queue, pumped by the SDL event machine */
|
|
|
|
while ( SDL_PollEvent( &event ) )
|
|
{
|
|
switch( event.type )
|
|
{
|
|
case SDL_ACTIVEEVENT:
|
|
/* Gained or lost window focus. */
|
|
if ( event.active.gain == 0 )
|
|
isActive = FALSE;
|
|
else
|
|
isActive = TRUE;
|
|
break;
|
|
case SDL_VIDEORESIZE:
|
|
/* handle resize event */
|
|
surface = SDL_SetVideoMode( event.resize.w,
|
|
event.resize.h,
|
|
16, videoFlags );
|
|
if ( !surface )
|
|
{
|
|
fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) );
|
|
Quit( 1 );
|
|
}
|
|
resizeWindow( event.resize.w, event.resize.h );
|
|
break;
|
|
case SDL_KEYDOWN:
|
|
/* handle key presses */
|
|
handleKeyPress( &event.key.keysym );
|
|
break;
|
|
case SDL_QUIT:
|
|
/* handle quit requests */
|
|
done = TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* draw the scene */
|
|
if ( isActive ) {
|
|
drawGLScene( );
|
|
}
|
|
}
|
|
|
|
/* clean ourselves up and exit */
|
|
Quit( 0 );
|
|
|
|
/* Should never even get here */
|
|
return( 0 );
|
|
}
|
|
|