Parallel Programming - Finished OpenMP
[matches/honours.git] / course / semester2 / pprog / assignment1 / openmp / graphics.c~
diff --git a/course/semester2/pprog/assignment1/openmp/graphics.c~ b/course/semester2/pprog/assignment1/openmp/graphics.c~
new file mode 100644 (file)
index 0000000..627cea1
--- /dev/null
@@ -0,0 +1,388 @@
+/**
+ * @file graphics.c
+ * @author Sam Moore (20503628) 2012 
+ *     - Adapted from template program provided by UWA
+ * @purpose Definition of graphics related functions
+ * NOTE: This file is identical for both the single-threaded and multi-threaded versions of the program
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h> // Needed for clock
+#include <math.h> // Maths functions (sin, cos)
+
+#include "graphics.h" //Function declarations
+#include "nbody.h" //The simulation
+
+
+// --- Variable definitions --- //
+double previousTime, eyeTheta, eyePhi, eyeRho;
+float look[3];
+int windowWidth, windowHeight, upY;
+double scale = 1.0;
+
+#ifdef FLYING_CAMERA
+Camera eye;
+#endif //FLYING_CAMERA
+
+/**
+ * @function Graphics_Run
+ * @purpose Setup and start the graphics engine
+ * @param argc - Number of arguments to main function, passed to glutInit
+ * @param argv - Argument strings for main function, passed to glutInit
+ */
+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
+               fprintf(stderr, "Graphics_Run should not be called if graphics are disabled!\n");
+               exit(EXIT_FAILURE);
+       }       
+
+       glutInit(&argc, argv);  
+       glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
+       glutInitWindowSize(WIDTH, HEIGHT);
+       glutInitWindowPosition(POSITION_X, POSITION_Y);
+
+       //Set window title based on version of program
+       #ifdef SINGLE_THREADED
+               glutCreateWindow("N-Body : Single-Threaded");
+       #elif defined PTHREADED
+               glutCreateWindow("N-Body : Multi-Threaded (pthread)");
+       #elif defined OMP_THREADED
+               glutCreateWindow("N-Body : Multi-Threaded (OpenMP)");   
+       #else
+               glutCreateWindow("N-Body");
+       #endif 
+       glutDisplayFunc(Graphics_Display);
+       glutIdleFunc(Graphics_Display);
+       glutKeyboardFunc(Graphics_Keyboard);
+       glutReshapeFunc(Graphics_Reshape);
+        
+
+       glClearColor(1.0,1.0,1.0,0.0);
+       glColor3f(0.0f, 0.0f, 0.0f);
+       glPointSize(POINT_SIZE);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+
+       /*init lighting */
+
+       GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
+       GLfloat mat_shininess[] = { 50.0 };
+       GLfloat light_position[] = { 1.0, 1.0, 0.0, 0.0 };
+       glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
+       glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
+       glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+
+       glColorMaterial(GL_FRONT,GL_DIFFUSE);                // Set Color Capability
+    
+       glEnable(GL_LIGHTING);
+       glEnable(GL_LIGHT0);
+       glEnable(GL_DEPTH_TEST);
+    
+       glEnable(GL_COLOR_MATERIAL);                   // Enable color
+
+       
+       windowWidth = WIDTH;
+       windowHeight = HEIGHT;
+       previousTime = clock();
+       eyeTheta = 0;
+       eyePhi = 0.5 * M_PI;
+       eyeRho = RHO;
+       upY = 1;
+       look[0] = 0;
+       look[1] = 0;
+       look[2] = 0;
+       gluPerspective(VIEW_ANGLE, (double)WIDTH/(double)HEIGHT, WORLD_NEAR, WORLD_FAR);  
+
+       #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
+               glutMainLoop(); 
+       #endif //OMP_THREADED
+}
+
+/**
+ * @function Graphics_Display
+ * @purpose This function redraws the screen after the positions of particles 
+ *             have been updated.
+ *     It also calls System_Compute, and checks for exit conditions, in the single-threaded version only
+ */
+void Graphics_Display() 
+{
+
+       if (options.draw_graphics == false)
+       {
+               // This message is left here for when I inevitably accidentally call the function
+               fprintf(stderr, "Graphics_Display should not be called if graphics are disabled!\n");
+               exit(EXIT_FAILURE);
+       }
+
+       //Check whether the graphics thread should exit for any reason
+       if (ExitCondition())
+       {
+               glutLeaveMainLoop();    // original glut does not have this, which makes "nicely" exiting a bit annoying
+               return;
+       }
+
+       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
+                       // Multiple threads - ensure that all body positions are updated (ie: not halfway through step).
+                       //      (We don't care about the force and velocity variables though)
+
+       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
+
+}
+
+/**
+ * @function Graphics_Keyboard
+ * @purpose This function is to manipulate with the image
+ * @param theKey key pressed
+ * @param mouseX, mouseY position of the mouse in the window
+ */
+void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY) 
+{
+       if (theKey == 'x' || theKey == 'X') 
+       {
+               
+               QuitProgram(false);
+               
+               return;
+       }
+
+       #ifdef FLYING_CAMERA
+       switch (theKey)
+       {
+               // Translate in direction of camera
+               case 'W':
+               case 'w':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += eye.x[i];
+                       break;
+               // Translate backwards from camera direction
+               case 'S':
+               case 's':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -= eye.x[i];
+                       break;
+               // Translate left from camera direction
+               case 'A':
+               case 'a':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -= eye.y[i];
+                       break;
+               // Translate right from camera direction
+               case 'D':
+               case 'd':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += eye.y[i];
+                       break;
+               // Translate up from camera direction
+               case 'Q':
+               case 'q':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] += eye.z[i];
+                       break;
+               // Translate down from camera direction
+               case 'E':
+               case 'e':
+                       for (unsigned i = 0; i < DIMENSIONS; ++i)
+                               eye.p[i] -= 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)
+                               eyePhi = 2 * M_PI;
+               } else if (theKey == 'm' || theKey == 'I') {
+                       eyePhi += M_PI / 20;
+               } else if (theKey == 'j' || theKey == 'J') {
+                       eyeTheta -= M_PI / 20;
+               } else if (theKey == 'k' || theKey == 'K') {
+                       eyeTheta += M_PI / 20;
+               } else if (theKey == ',') {
+                       eyeRho += 0.5;
+               } else if (theKey == '.' || theKey == 'I') {
+                       eyeRho -= 0.5;
+               } else if (theKey == 'w' || theKey == 'W') {
+                       look[1] += 0.5;
+               } else if (theKey == 'z' || theKey == 'Z') {
+                       look[1] -= 0.5;
+               } else if (theKey == 'a' || theKey == 'A') {
+                       look[0] -= 0.5;
+               } else if (theKey == 's' || theKey == 'S') {
+                       look[0] += 0.5;
+               } else if (theKey == '+') {
+                       scale *= 1.1;
+               } else if (theKey == '-') {
+                       scale *= 0.9;
+               }
+               if (sin(eyePhi) > 0) upY = 1;
+               else upY = 1;
+       #endif //FLYING_CAMERA
+}
+
+/**
+ * @function Graphics_Reshape
+ * @purpose Resize the view window
+ * @param width, height - New size of the window
+ */
+void Graphics_Reshape(int width, int height) 
+{
+       double displayRatio = 1.0 * width / height;
+       windowWidth = width;
+       windowHeight = height;
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
+       glViewport(0, 0, windowWidth, windowHeight);
+}
+
+
+

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