3 * @author Sam Moore (20503628) 2012
4 * - Adapted from template program provided by UWA
5 * @purpose Definition of graphics related functions
6 * NOTE: This file is identical for both the single-threaded and multi-threaded versions of the program
12 #include <time.h> // Needed for clock
13 #include <math.h> // Maths functions (sin, cos)
15 #include "graphics.h" //Function declarations
16 #include "nbody.h" //The simulation
17 #include <GL/freeglut.h>
19 // --- Variable definitions --- //
20 double previousTime, eyeTheta, eyePhi, eyeRho;
22 int windowWidth, windowHeight, upY;
27 * @function Graphics_Run
28 * @purpose Setup and start the graphics engine
29 * @param argc - Number of arguments to main function, passed to glutInit
30 * @param argv - Argument strings for main function, passed to glutInit
32 void Graphics_Run(int argc, char ** argv)
34 if (options.draw_graphics == false)
36 // This message is left here for when I inevitably accidentally call the function
37 fprintf(stderr, "Graphics_Run should not be called if graphics are disabled!\n");
41 glutInit(&argc, argv);
42 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
43 glutInitWindowSize(WIDTH, HEIGHT);
44 glutInitWindowPosition(POSITION_X, POSITION_Y);
46 //Set window title based on version of program
47 #ifdef SINGLE_THREADED
48 glutCreateWindow("N-Body : Single-Threaded");
49 #elif defined PTHREADED
50 glutCreateWindow("N-Body : Multi-Threaded (pthread)");
51 #elif defined OMP_THREADED
52 glutCreateWindow("N-Body : Multi-Threaded (OpenMP)");
54 glutCreateWindow("N-Body");
56 glutDisplayFunc(Graphics_Display);
57 glutIdleFunc(Graphics_Display);
58 glutKeyboardFunc(Graphics_Keyboard);
59 glutReshapeFunc(Graphics_Reshape);
62 glClearColor(1.0,1.0,1.0,0.0);
63 glColor3f(0.0f, 0.0f, 0.0f);
64 glPointSize(POINT_SIZE);
65 glMatrixMode(GL_PROJECTION);
70 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
71 GLfloat mat_shininess[] = { 50.0 };
72 GLfloat light_position[] = { 1.0, 1.0, 0.0, 0.0 };
73 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
74 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
75 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
77 glColorMaterial(GL_FRONT,GL_DIFFUSE); // Set Color Capability
79 glEnable(GL_LIGHTING);
81 glEnable(GL_DEPTH_TEST);
83 glEnable(GL_COLOR_MATERIAL); // Enable color
87 windowHeight = HEIGHT;
88 previousTime = clock();
96 gluPerspective(VIEW_ANGLE, (double)WIDTH/(double)HEIGHT, WORLD_NEAR, WORLD_FAR);
102 * @function Graphics_Display
103 * @purpose This function redraws the screen after the positions of particles
105 * It also calls System_Compute, and checks for exit conditions, in the single-threaded version only
107 void Graphics_Display()
110 if (options.draw_graphics == false)
112 // This message is left here for when I inevitably accidentally call the function
113 fprintf(stderr, "Graphics_Display should not be called if graphics are disabled!\n");
117 //Check whether the graphics thread should exit for any reason
120 glutLeaveMainLoop(); // original glut does not have this, which makes "nicely" exiting a bit annoying
124 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
125 glMatrixMode(GL_MODELVIEW);
127 gluLookAt(eyeRho * sin(eyePhi) * sin(eyeTheta), eyeRho * cos(eyePhi),
128 eyeRho * sin(eyePhi) * cos(eyeTheta),look[0], look[1], look[2], 0, upY, 0);
130 BeforeDraw(); // Stuff to do before graphics is allowed to draw
131 // Single-thread - perform a computation step, obviously! It's not done anywhere else
132 // Multiple threads - ensure that all body positions are updated (ie: not halfway through step).
133 // (We don't care about the force and velocity variables though)
135 for (int i = 0; i < universe.N; ++i)
137 Body * b = universe.body+i;
138 glColor3f(0.0f, b->mass/1e11*100, 0.0f);
139 glPushMatrix(); // to save the current matrix
140 glTranslated(scale*b->x[0], scale*b->x[1], scale*b->x[2]);
141 glutSolidSphere (BALL_SIZE, 10, 10);
142 glPopMatrix(); // restore the previous matrix
146 AfterDraw(); // Stuff to do after graphics is done drawing
147 // Single-thread - Nothing at all
148 // Multiple threads - signal threads it is safe to change position variables
153 * @function Graphics_Keyboard
154 * @purpose This function is to manipulate with the image
155 * @param theKey key pressed
156 * @param mouseX, mouseY position of the mouse in the window
158 void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY)
160 if (theKey == 'x' || theKey == 'X')
166 if (theKey == 'i' || theKey == 'I') {
170 } else if (theKey == 'm' || theKey == 'I') {
172 } else if (theKey == 'j' || theKey == 'J') {
173 eyeTheta -= M_PI / 20;
174 } else if (theKey == 'k' || theKey == 'K') {
175 eyeTheta += M_PI / 20;
176 } else if (theKey == ',') {
178 } else if (theKey == '.' || theKey == 'I') {
180 } else if (theKey == 'w' || theKey == 'W') {
182 } else if (theKey == 'z' || theKey == 'Z') {
184 } else if (theKey == 'a' || theKey == 'A') {
186 } else if (theKey == 's' || theKey == 'S') {
188 } else if (theKey == '+') {
190 } else if (theKey == '-') {
193 if (sin(eyePhi) > 0) upY = 1;
198 * @function Graphics_Reshape
199 * @purpose Resize the view window
200 * @param width, height - New size of the window
202 void Graphics_Reshape(int width, int height)
204 double displayRatio = 1.0 * width / height;
206 windowHeight = height;
207 glMatrixMode(GL_PROJECTION);
209 gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
210 glViewport(0, 0, windowWidth, windowHeight);