X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=course%2Fsemester2%2Fpprog%2Fassignment1%2Fopenmp%2Fgraphics.c~;fp=course%2Fsemester2%2Fpprog%2Fassignment1%2Fopenmp%2Fgraphics.c~;h=627cea12316f499e4351968523d2c38efe5aea69;hb=bb7fa31ea517a1fba064e723b37d5b8d8bd7dd72;hp=0000000000000000000000000000000000000000;hpb=20979b1c07eda73b7f86b2fe8cb66eb58d959e04;p=matches%2Fhonours.git diff --git a/course/semester2/pprog/assignment1/openmp/graphics.c~ b/course/semester2/pprog/assignment1/openmp/graphics.c~ new file mode 100644 index 00000000..627cea12 --- /dev/null +++ b/course/semester2/pprog/assignment1/openmp/graphics.c~ @@ -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 +#include +#include // Needed for clock +#include // 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); +} + + +