Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

main.cpp

Go to the documentation of this file.
00001 
00006 #include <iostream>
00007 #include <vector>
00008 
00009 #ifdef __APPLE__
00010 #include <GraphicsLib/GraphicsLib.h>
00011         #include <GraphicsLib/ThreadTimer.h>
00012 #else
00013 #include "GraphicsLib.h"
00014 #include "ThreadTimer.h"
00015 #endif
00016 
00017 #include <math.h>
00018 #include "ParticleSystems.h"
00019 #include "Debugger.h"
00020 
00021 using namespace std;
00022 using namespace GraphicsLib;
00023 using namespace ParticleSystems;
00024 
00028 Emitter *emit;
00029 DataStructure *dataParticle;
00030 ParticleSystem *particleSys;
00031 
00036 ParticleSystemManager *manager;
00037 
00039 int WIDTH = 1024;
00041 int HEIGHT = 800;
00042 
00044 int FRAMESPERSEC = 25;
00045 
00046 // The global camera
00047 Camera Cam;
00048 // the values to spin the main window by in x y and z
00049 int spinxface = 0 ;
00050 int spinyface = 0 ;
00051 int spinzface = 0 ;
00052 int  origx,origy,origz,RotateXY,RotateXZ=0;
00053 int Rotate;
00054 
00058 void MakeFloor()
00059 {
00060 const static GLfloat FSIZE=10.0;
00061 glPushMatrix();
00062         glDisable(GL_LIGHTING);
00063         glColor3f(0.2,0.2,0.2); 
00064         glBegin(GL_QUADS);
00065                 glVertex3d(-FSIZE,0,-FSIZE); 
00066                 glVertex3d(FSIZE,0,-FSIZE);
00067                 glVertex3d(FSIZE,0,FSIZE); 
00068                 glVertex3d(-FSIZE,0,FSIZE);
00069         glEnd();
00070         glColor3f(0.6,0.6,0.6);
00071 
00072         for(int x=-10; x<10; x++)
00073         {
00074         glBegin(GL_LINES);
00075                 glVertex3d(x,0,FSIZE); 
00076                 glVertex3d(x,0,-FSIZE);
00077         glEnd();
00078         glBegin(GL_LINES);
00079                 glVertex3d(FSIZE,0,x); 
00080                 glVertex3d(-FSIZE,0,x);
00081         glEnd();
00082         }
00083 glPopMatrix();
00084 glEnable(GL_LIGHTING);
00085 }
00086 
00088 void display()
00089 {
00090         //start the timer
00091         int start = GetThreadTimeMS();
00092         #ifdef __TIMER__
00093         std::cout << "VectorDS: time start " << start  << std::endl;
00094         #endif
00095         // clear the current buffer
00096         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00097         // save the current transformation matrix
00098         // turn on the lights
00099         glPushMatrix();
00100                 //rotate the global scene based on the mouse rotations
00101                 glRotated       ( (GLdouble) spinxface, 1.0, 0.0, 0.0 ) ;
00102                 glRotated       ( (GLdouble) spinyface, 0.0, 1.0, 0.0 ) ;
00103                 glRotated       ( (GLdouble) spinzface, 0.0, 0.0, 1.0 ) ;
00104                 
00105                 //draw the x, y, z axis
00106                 DrawAxis(5);
00107                 //MakeFloor();
00108                 #ifdef __PERFORMANCE__
00109                         cout << "main: render" << endl;
00110                 #endif
00111                 //draw all the ParticleSystems
00112                 manager->render();
00113                 #ifdef __PERFORMANCE__
00114                         cout << "main: update" << endl;
00115                 #endif
00116                 
00117                 //update all the ParticleSystems
00118                 manager->update();
00119                 #ifdef __PERFORMANCE__
00120                         cout << "main: update finished" << endl;
00121                 #endif
00122         //glRecti(-10,-10,10,10);
00123 
00124         glPopMatrix();
00125         // render the scene
00126         glutSwapBuffers();
00127         //take the time how long it took
00128         int end_time = GetThreadTimeMS();
00129         
00130         //check if we need to wait
00131         while(end_time < start+FRAMESPERSEC) {
00132                 end_time = GetThreadTimeMS();
00133         }
00134         #ifdef __TIMER__
00135         std::cout << "VectorDS: time end " << end_time << std::endl;
00136         #endif
00137 }
00138 
00139 
00140 
00141 
00143 void update()
00144 {
00145     glutPostRedisplay();
00146 }
00147 
00149 void initPSManager()
00150 {
00151     manager = new ParticleSystemManager();
00152 }
00153 
00154 
00155 
00161 void multiCollision() {
00162         //constrain for the RandomForce
00163         Vector *constrain = new Vector(0.0,0.0,0.0);
00164 
00165         //First ParticleSystem inital Velocity
00166         Vector *initVelocity2 = new Vector(0,0.05,0.1);
00167         
00168         //Second ParticleSystem inital Velocity
00169         Vector *initVelocity3 = new Vector(0.1,0.05,0.0);
00170         
00171         //The inital Colour
00172         Colour *colour = new Colour(0.0,0.0,1.0,1.0);
00173         colour->set(0.0,0.0,1.0,1.0);
00174         
00175         //No flare colour
00176         Colour *flare = new Colour(0.0,0.0,0.0,0.00);
00177         flare->set(0.0,0.0,0.0,0.00);
00178         
00179         //The Vector for the Gravity
00180     Vector *gravCon = new Vector(0,-0.005,0);
00181         
00182         //The Emitter position for the first ParticleSystem
00183         Point3 emitPoint = new Point3(0,1,0);
00184         
00185         //The Emitter position for the second ParticleSystem
00186         Point3 emitPoint2 = new Point3(-5,1,7);
00187 
00188         //A random force
00189         RandomForce *rf = new RandomForce(constrain, 0.01);
00190         
00191         //The Gravity force
00192         GravityForce *f = new GravityForce(gravCon, 1, 0.9);
00193         
00194         //The Solver with both forces added
00195         StraightSolver *solver = new StraightSolver();
00196         solver->addForce(rf);
00197     solver->addForce(f);
00198 
00199         //The first emitter
00200     Emitter *emit2 = new PointEmitter(manager->getNextID(), solver, Emitter::STRIKE, (*initVelocity2),(*colour),0.1,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga", emitPoint,0.05);
00201         emit2->flareColor = (*flare);
00202         emit2->particleLife = 100;
00203         
00204         //The second emitter
00205         Emitter *emit3 = new PointEmitter(manager->getNextID(), solver, Emitter::STRIKE, (*initVelocity3),(*colour),0.1,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga", emitPoint2,0.05);
00206         emit3->flareColor = (*flare);
00207         emit3->particleLife = 100;
00208 
00209     //The dataStructures for both ParticleSystems
00210     DataStructure *data2 = new VectorDS();
00211         DataStructure *data3 = new VectorDS();
00212         
00213         //The position of the CollisionSphere
00214         Point3 *sPoint = new Point3(0,-4,8);
00215         //The radius
00216         Real radius = 2.0;
00217         CollisionSphere *sphere = new CollisionSphere(sPoint, radius);
00218         
00219         //add it to both
00220     data2->addCollisionObject(sphere);
00221         data3->addCollisionObject(sphere);
00222     //data2->addCollisionObject(collide);
00223         //turn on collision
00224     data2->collision = true;
00225         data3->collision = true;
00226 
00227     ParticleSystem *particleSys2 = new ParticleSystem(manager->getNextID(), emit2, data2, solver, 1000,1000);
00228         
00229     manager->addSystem(particleSys2);
00230         
00231         ParticleSystem *particleSys3 = new ParticleSystem(manager->getNextID(), emit3, data3, solver, 1000,1000);
00232         
00233         manager->addSystem(particleSys3);
00234 
00235 }
00236 
00242 void fire() {
00243         
00244     Vector *constrain = new Vector(0.1,0.1,0.1);
00245 
00246         Vector *initVelocity = new Vector(0,0.5,0);
00247 
00248         Colour *colour = new Colour(0.5,0.5,0.5,1.0);
00249         colour->set(0.75,0.5,0.25,1.0);
00250 
00251         Colour *flare = new Colour(0.05,0.05,0.05,0.00);
00252         flare->set(0.05,0.05,0.05,0.00);
00253 
00254     Vector *gravCon = new Vector(0,-0.1,0);
00255         Vector *x = new Vector(20,0,0);
00256         Vector *z = new Vector(0,0,20);
00257 
00258         Point3 midPoint = new Point3(0,0,0);
00259         RandomForce *rf = new RandomForce(constrain, 1);
00260         GravityForce *f = new GravityForce(gravCon, 1, 0.5);
00261 
00262         StraightSolver *solver = new StraightSolver();
00263         solver->addForce(rf);
00264     //solver->addForce(f);
00265 
00266         /******** SYSID ******/
00267     emit = new PlanarEmitter(1, solver, Emitter::IMAGE,(*initVelocity),(*colour),0.5,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/Particle.tga",(*x), (*z));
00268     emit->flareColor = (*flare);
00269         emit->particleSizeFlare = 0.03;
00270         emit->particleLife = 30;
00271 
00272     dataParticle = new VectorDS();
00273 
00274     particleSys = new ParticleSystem(manager->getNextID(), emit, dataParticle, solver, 1000,5000);
00275 
00276     manager->addSystem(particleSys);
00277 }
00278 
00279 void smoke() {
00280     Vector *constrain = new Vector(0.1,0.1,0.1);
00281 
00282         Vector *initVelocity = new Vector(0,0.5,0);
00283 
00284         Colour *colour = new Colour(0.5,0.5,0.5,1.0);
00285         colour->set(0.5,0.5,0.5,0.3);
00286 
00287         Colour *flare = new Colour(0.05,0.05,0.05,0.00);
00288         flare->set(0.0,0.0,0.0,0.00);
00289 
00290     Vector *gravCon = new Vector(0,-0.1,0);
00291         Vector *x = new Vector(20,0,0);
00292         Vector *z = new Vector(0,0,20);
00293 
00294         Point3 midPoint = new Point3(0,0,0);
00295         //UniformForce *f = new UniformForce(constrain, 1);
00296         RandomForce *rf = new RandomForce(constrain, 1);
00297         GravityForce *f = new GravityForce(gravCon, 1, 0.5);
00298 
00299         StraightSolver *solver = new StraightSolver();
00300         solver->addForce(rf);
00301     //solver->addForce(f);
00302 
00303         /******** SYSID ******/
00304     emit = new PlanarEmitter(1, solver, Emitter::IMAGE,(*initVelocity),(*colour),0.5,"/Users/hannes/Documents/Uni/Bournemouth/Term2/ProgrammingGFX/ParticleSystem/smoke2.tga",(*x), (*z));
00305     emit->flareColor = (*flare);
00306         emit->particleSizeFlare = 0.01;
00307         emit->particleLife = 20;
00308 
00309     dataParticle = new VectorDS();
00310 
00311     //manager = new ParticleSystemManager(dataParticle);
00312 
00313     particleSys = new ParticleSystem(manager->getNextID(), emit, dataParticle, solver, 1000,2000);
00314 
00315 
00316     manager->addSystem(particleSys);
00317 }
00318 
00322 void init() {
00323         initPSManager();
00324 }
00325 
00327 void InitGL()
00328 {
00329 glClearColor(0.5f, 0.5f, 0.5f, 1.0f);                   
00330 // render things smoothly
00331 glShadeModel(GL_SMOOTH);
00332 // enable the default light
00333 glEnable(GL_LIGHT0);
00334 // set the ambient colour to dark grey
00335 
00336 GLfloat AmbColour[]={0.2,0.2,0.2};
00337 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,AmbColour);
00338 // setup the Camera
00339 Point3 Eye(15.0f,15.0f,15.0f);
00340 Point3 Look(0.0f,0.0f,0.0f);
00341 Vector Up(0.0f,1.0f,0.0f); //Y == UP
00342 
00343 Cam.set(Eye,Look,Up);
00344 Cam.setShape(45,640.0/480.0,0.5,150);
00345 glEnable(GL_LIGHTING);
00346 glEnable(GL_COLOR_MATERIAL);
00347 glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
00348 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
00349 glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
00350 glEnable(GL_NORMALIZE);
00351 
00352 }
00353 
00354 
00358 void resetPMManager()
00359 {
00360         manager->reset();
00361         manager->restart();
00362 }
00363 
00364 
00365 void KeyPressed(unsigned char ch, int x, int y)
00366 {
00367   switch (ch)
00368   {
00369   // ESC key to exit program
00370                   case 27 : exit(0); break;
00371                   case 'p' : manager->pause(); break;
00372                   case 'r' : resetPMManager(); break;
00373                   case 's' : initPSManager(); smoke(); break;
00374                   case 'f' : initPSManager(); fire(); break;
00375                   case 'm' : initPSManager(); multiCollision(); break; 
00376                   case 't' : initPSManager(); smoke(); fire(); break;
00377                   //case 'c' : ChangeParticleType(); break;
00378   }
00379   // tell the system we need to redisplay
00380  glutPostRedisplay();
00381 }
00382 
00383 
00384 
00388 void SpecialKeyPressed(int key, int x, int y)
00389 {
00390     switch (key)
00391     {
00392     // slide the camera left right up and down
00393     case GLUT_KEY_LEFT  :
00394                 Cam.slide(0.5,0.0,0.0);
00395         break;
00396     case GLUT_KEY_UP    :
00397         Cam.slide(0.0,-0.5,0.0);
00398         break;
00399         case GLUT_KEY_RIGHT     :
00400                 Cam.slide(-0.5,0.0,0.0);
00401     break;
00402         case GLUT_KEY_DOWN      :
00403         Cam.slide(0.0,0.5,0.0);
00404         break;
00405     //slide the camera along the z axis
00406         case GLUT_KEY_PAGE_UP   :
00407         Cam.slide(0.0,0.0,0.5);
00408                 break;
00409         case GLUT_KEY_PAGE_DOWN :
00410         Cam.slide(0.0,0.0,-0.5);
00411                 break;
00412 
00413         //turn the mouse rotate on and off
00414 
00415     }
00416  //redisplay the scene
00417 glutPostRedisplay();
00418 }
00419 
00420 
00424 void motion ( int x, int y )
00425 {
00426  if (Rotate) {
00427          spinyface = ( spinyface + (x - origx) ) % 360 ;
00428          spinxface = ( spinxface + (y - origy) ) % 360 ;
00429          origx = x;
00430          origy = y;
00431          glutPostRedisplay();
00432   }
00433 }
00434 
00439 static void Button(int button, int down, int x, int y)
00440 {
00441 Rotate = 0;
00442   switch(button)
00443   {
00444   case GLUT_LEFT_BUTTON:
00445          if (down == GLUT_DOWN)
00446         {
00447                 origx = x;
00448                 origy = y;
00449                 Rotate = 1;
00450         }
00451      else Rotate = 0;
00452    break;
00453    }
00454 }
00455 
00459 void intro() {
00460         std::cout << "Welcome to Hannes Ricklefs ParticleSystem" << std::endl;
00461         std::cout << "There are 4 different demo scenes" << std::endl;
00462         std::cout << "1) Smoke can be viewed by pressing s" << std::endl;
00463         std::cout << "2) Fire can be viewed by pressing f" << std::endl;
00464         std::cout << "3) Fire and smoke together can be viewed by pressing t" << std::endl;
00465         std::cout << "4) Two ParticleSystems colliding with a CollisionSphere can be viewed by pressing m" << std::endl;
00466         std::cout << "To restart any of the demos press r" << std::endl;
00467         std::cout << "To pause any of the demos press p" << std::endl;
00468         std::cout << "To quit press esc" << std::endl;
00469         std::cout << "You can fly arround the scene by using your mouse or " << std::endl;
00470         std::cout << "by using the arrow keys";
00471         std::cout << "To zoom in and out use the page up and down keys" << std::endl;
00472 }
00473 
00474 
00478 int main(int argc, char **argv)
00479 {
00480     init();
00481         // set the rng seed
00482         srand(time(NULL));
00483         // get how many particles to create
00484         //initPSManager(200);
00485         glutInit(&argc, argv);
00486     glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE |GLUT_ALPHA |GLUT_ACCUM);
00487         glutInitWindowSize(WIDTH, HEIGHT);
00488     glutCreateWindow("ParticleSystem :: Hannes Ricklefs");
00489         //set the time to the current time
00490     //load the glut callbacks
00491     glutDisplayFunc(display);
00492     //glutIdleFunc(idle);
00493 
00494         glutMouseFunc(Button);
00495     glutMotionFunc(motion);
00496     glutKeyboardFunc(KeyPressed);
00497     glutSpecialFunc(SpecialKeyPressed);
00498         glutIdleFunc(update);
00499         intro();
00500         //initialise opengl
00501     InitGL();
00502         glutMainLoop();
00503         //this never gets called due to glutmainloop not exiting properly
00504     return 1;
00505 }
00506 
00507 
00508 //end of file
00509 
00510 

Generated on Thu Mar 24 11:05:02 2005 for ParticleSystem by  doxygen 1.4.1