/* * 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 #include #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 ); }