Parallel Programming - Final version
[matches/honours.git] / course / semester2 / pprog / assignment1 / single-thread / graphics.c
index 864ff91..e275eb5 100644 (file)
@@ -14,7 +14,7 @@
 
 #include "graphics.h" //Function declarations
 #include "nbody.h" //The simulation
-#include <GL/freeglut.h>
+
 
 // --- Variable definitions --- //
 double previousTime, eyeTheta, eyePhi, eyeRho;
@@ -22,6 +22,9 @@ float look[3];
 int windowWidth, windowHeight, upY;
 double scale = 1.0;
 
+#ifdef FLYING_CAMERA
+Camera eye;
+#endif //FLYING_CAMERA
 
 /**
  * @function Graphics_Run
@@ -31,6 +34,7 @@ double scale = 1.0;
  */
 void Graphics_Run(int argc, char ** argv) 
 {
+       
        if (options.draw_graphics == false)
        {
                // This message is left here for when I inevitably accidentally call the function
@@ -50,6 +54,8 @@ void Graphics_Run(int argc, char ** argv)
                glutCreateWindow("N-Body : Multi-Threaded (pthread)");
        #elif defined OMP_THREADED
                glutCreateWindow("N-Body : Multi-Threaded (OpenMP)");   
+       #elif defined BARNES_HUT
+               glutCreateWindow("N-Body : Barnes Hut Algorithm");
        #else
                glutCreateWindow("N-Body");
        #endif 
@@ -95,7 +101,24 @@ void Graphics_Run(int argc, char ** argv)
        look[2] = 0;
        gluPerspective(VIEW_ANGLE, (double)WIDTH/(double)HEIGHT, WORLD_NEAR, WORLD_FAR);  
 
-       glutMainLoop();   
+       #ifdef FLYING_CAMERA
+       eye.x[0] = 0; eye.x[1] = 0; eye.x[2] = 1;
+       eye.y[0] = 0; eye.y[1] = 1; eye.y[2] = 0;
+       eye.z[0] = 1; eye.z[1] = 0; eye.z[2] = 0;
+       eye.p[0] = 0; eye.p[1] = 0; eye.p[2] = -50;
+       #endif //FLYING_CAMERA
+
+
+       //This option must be set, or when glut leaves the main loop. the exit(3) function is called... annoying
+       glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
+
+
+       #ifndef OMP_THREADED
+       #ifndef BARNES_HUT
+               glutMainLoop(); // the mthread and single-thread versions can just start the loop here
+               // In OpenMP, because barriers have to be within the #pragma, need glutMainLoopEvent in the #pragma
+       #endif //BARNS_HUT
+       #endif //OMP_THREADED
 }
 
 /**
@@ -117,6 +140,7 @@ void Graphics_Display()
        //Check whether the graphics thread should exit for any reason
        if (ExitCondition())
        {
+               QuitProgram(false);
                glutLeaveMainLoop();    // original glut does not have this, which makes "nicely" exiting a bit annoying
                return;
        }
@@ -124,8 +148,16 @@ void Graphics_Display()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
+
+       #ifdef FLYING_CAMERA
+
+       gluLookAt(eye.p[0], eye.p[1], eye.p[2], 
+               eye.p[0] + eye.x[0], eye.p[1] + eye.x[1], eye.p[2] + eye.x[2],
+               eye.z[0], eye.z[1], eye.z[2]);
+       #else
        gluLookAt(eyeRho * sin(eyePhi) * sin(eyeTheta), eyeRho * cos(eyePhi),
                eyeRho * sin(eyePhi) * cos(eyeTheta),look[0], look[1], look[2], 0, upY, 0);
+       #endif //FLYING_CAMERA
 
        BeforeDraw(); // Stuff to do before graphics is allowed to draw
                        // Single-thread - perform a computation step, obviously! It's not done anywhere else
@@ -134,19 +166,21 @@ void Graphics_Display()
 
        for (int i = 0; i < universe.N; ++i) 
        {
+       
                Body * b = universe.body+i;
                glColor3f(0.0f, b->mass/1e11*100, 0.0f);
+               //glColor3f(1.0f, 0.0f, 0.0f);
                glPushMatrix(); // to save the current matrix
                glTranslated(scale*b->x[0], scale*b->x[1], scale*b->x[2]);
                glutSolidSphere (BALL_SIZE, 10, 10);
                glPopMatrix(); // restore the previous matrix
        }
-       glFlush();
+       
 
        AfterDraw(); // Stuff to do after graphics is done drawing
                        // Single-thread - Nothing at all
                        // Multiple threads - signal threads it is safe to change position variables
-
+       glFlush();
 }
 
 /**
@@ -159,10 +193,157 @@ void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY)
 {
        if (theKey == 'x' || theKey == 'X') 
        {
+               
                QuitProgram(false);
+               glutLeaveMainLoop();
                return;
        }
 
+       #ifdef FLYING_CAMERA
+       float s = 10;
+       switch (theKey)
+       {
+               // Translate in direction of camera
+               case 'W':
+               case 'w':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += s * eye.x[i];
+                       break;
+               // Translate backwards from camera direction
+               case 'S':
+               case 's':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -=  s * eye.x[i];
+                       break;
+               // Translate left from camera direction
+               case 'A':
+               case 'a':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -= s * eye.y[i];
+                       break;
+               // Translate right from camera direction
+               case 'D':
+               case 'd':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += s * eye.y[i];
+                       break;
+               // Translate up from camera direction
+               case 'Q':
+               case 'q':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += s * eye.z[i];
+                       break;
+               // Translate down from camera direction
+               case 'E':
+               case 'e':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -= s * eye.z[i];
+                       break;
+
+               // Rotate camera direction "down"
+               // (pitch control)
+               case 'I':
+               case 'i':
+               {
+                       float theta = M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.z[i] = old.z[i] * cos(theta) + old.x[i] * sin(theta);
+                               eye.x[i] = old.x[i] * cos(theta) - old.z[i] * sin(theta);
+                       }
+                       break;
+               }
+               // Rotate camera direction "up"
+               // (pitch control)
+               case 'K':
+               case 'k':
+               {
+                       float theta = -M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.z[i] = old.z[i] * cos(theta) + old.x[i] * sin(theta);
+                               eye.x[i] = old.x[i] * cos(theta) - old.z[i] * sin(theta);
+                       }
+                       break;
+               }
+               // Rotate camera direction "left"
+               // (yaw control)
+               case 'J':
+               case 'j':
+               {
+                       float theta = +M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.y[i] = old.y[i] * cos(theta) + old.x[i] * sin(theta);
+                               eye.x[i] = old.x[i] * cos(theta) - old.y[i] * sin(theta);
+                       }
+                       break;
+               }
+               // Rotate camera direction "right"
+               // (yaw control)
+               case 'L':
+               case 'l':
+               {
+                       float theta = -M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.y[i] = old.y[i] * cos(theta) + old.x[i] * sin(theta);
+                               eye.x[i] = old.x[i] * cos(theta) - old.y[i] * sin(theta);
+                       }
+                       break;
+               }
+               // Rotate camera direction CCW about its axis
+               // (roll control)
+               case 'U':
+               case 'u':
+               {
+                       float theta = -M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.z[i] = old.z[i] * cos(theta) + old.y[i] * sin(theta);
+                               eye.y[i] = old.y[i] * cos(theta) - old.z[i] * sin(theta);
+                       }
+                       break;
+               }
+               // Rotate camera direction CW about its axis
+               // (roll control)
+               case 'O':
+               case 'o':
+               {
+                       float theta = +M_PI/80.0;
+                       Camera old = eye;
+
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                       {
+                               eye.z[i] = old.z[i] * cos(theta) + old.y[i] * sin(theta);
+                               eye.y[i] = old.y[i] * cos(theta) - old.z[i] * sin(theta);
+                       }
+                       break;
+               }       
+       }
+
+       /*  Code used for debugging the camera
+       system("clear");
+       printf("Camera status:\n");
+       printf("Position: %f %f %f\n", eye.p[0], eye.p[1], eye.p[2]);
+       printf("x: %f %f %f (%f)\n", eye.x[0], eye.x[1], eye.x[2], sqrt(eye.x[0]*eye.x[0] + eye.x[1]*eye.x[1] + eye.x[2]*eye.x[2]));
+       printf("y: %f %f %f (%f)\n", eye.y[0], eye.y[1], eye.y[2], sqrt(eye.y[0]*eye.y[0] + eye.y[1]*eye.y[1] + eye.y[2]*eye.y[2]));
+       printf("z: %f %f %f (%f)\n", eye.z[0], eye.z[1], eye.z[2], sqrt(eye.z[0]*eye.z[0] + eye.z[1]*eye.z[1] + eye.z[2]*eye.z[2]));
+       */
+       #else // The original view code
+       
+               // I like how 'I' is used three times.
+
                if (theKey == 'i' || theKey == 'I') {
                        eyePhi -= M_PI / 20;
                if (eyePhi == 0)
@@ -192,6 +373,7 @@ void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY)
                }
                if (sin(eyePhi) > 0) upY = 1;
                else upY = 1;
+       #endif //FLYING_CAMERA
 }
 
 /**

UCC git Repository :: git.ucc.asn.au