Parallel Programming - Commit before I break everything
[matches/honours.git] / course / semester2 / pprog / assignment1 / single-thread / graphics.c
1 /**
2  * @file graphics.c
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
7  */
8
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <time.h> // Needed for clock
13 #include <math.h> // Maths functions (sin, cos)
14
15 #include "graphics.h" //Function declarations
16 #include "nbody.h" //The simulation
17 #include <GL/freeglut.h>
18
19 // --- Variable definitions --- //
20 double previousTime, eyeTheta, eyePhi, eyeRho;
21 float look[3];
22 int windowWidth, windowHeight, upY;
23 double scale = 1.0;
24
25
26 /**
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
31  */
32 void Graphics_Run(int argc, char ** argv) 
33 {
34         if (options.draw_graphics == false)
35         {
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");
38                 exit(EXIT_FAILURE);
39         }       
40
41         glutInit(&argc, argv);  
42         glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
43         glutInitWindowSize(WIDTH, HEIGHT);
44         glutInitWindowPosition(POSITION_X, POSITION_Y);
45
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)");   
53         #else
54                 glutCreateWindow("N-Body");
55         #endif 
56         glutDisplayFunc(Graphics_Display);
57         glutIdleFunc(Graphics_Display);
58         glutKeyboardFunc(Graphics_Keyboard);
59         glutReshapeFunc(Graphics_Reshape);
60          
61
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);
66         glLoadIdentity();
67
68         /*init lighting */
69
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);
76
77         glColorMaterial(GL_FRONT,GL_DIFFUSE);                // Set Color Capability
78     
79         glEnable(GL_LIGHTING);
80         glEnable(GL_LIGHT0);
81         glEnable(GL_DEPTH_TEST);
82     
83         glEnable(GL_COLOR_MATERIAL);                   // Enable color
84
85         
86         windowWidth = WIDTH;
87         windowHeight = HEIGHT;
88         previousTime = clock();
89         eyeTheta = 0;
90         eyePhi = 0.5 * M_PI;
91         eyeRho = RHO;
92         upY = 1;
93         look[0] = 0;
94         look[1] = 0;
95         look[2] = 0;
96         gluPerspective(VIEW_ANGLE, (double)WIDTH/(double)HEIGHT, WORLD_NEAR, WORLD_FAR);  
97
98         glutMainLoop();   
99 }
100
101 /**
102  * @function Graphics_Display
103  * @purpose This function redraws the screen after the positions of particles 
104  *              have been updated.
105  *      It also calls System_Compute, and checks for exit conditions, in the single-threaded version only
106  */
107 void Graphics_Display() 
108 {
109
110         if (options.draw_graphics == false)
111         {
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");
114                 exit(EXIT_FAILURE);
115         }
116
117         //Check whether the graphics thread should exit for any reason
118         if (ExitCondition())
119         {
120                 glutLeaveMainLoop();    // original glut does not have this, which makes "nicely" exiting a bit annoying
121                 return;
122         }
123
124         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
125         glMatrixMode(GL_MODELVIEW);
126         glLoadIdentity();
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);
129
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)
134
135         for (int i = 0; i < universe.N; ++i) 
136         {
137                 Body * b = universe.body+i;
138                 glColor3f(0.0f, b->mass/1e11*100, 0.0f);
139                 //glColor3f(1.0f, 0.0f, 0.0f);
140                 glPushMatrix(); // to save the current matrix
141                 glTranslated(scale*b->x[0], scale*b->x[1], scale*b->x[2]);
142                 glutSolidSphere (BALL_SIZE, 10, 10);
143                 glPopMatrix(); // restore the previous matrix
144         }
145         glFlush();
146
147         AfterDraw(); // Stuff to do after graphics is done drawing
148                         // Single-thread - Nothing at all
149                         // Multiple threads - signal threads it is safe to change position variables
150
151 }
152
153 /**
154  * @function Graphics_Keyboard
155  * @purpose This function is to manipulate with the image
156  * @param theKey key pressed
157  * @param mouseX, mouseY position of the mouse in the window
158  */
159 void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY) 
160 {
161         if (theKey == 'x' || theKey == 'X') 
162         {
163                 QuitProgram(false);
164                 return;
165         }
166
167                 if (theKey == 'i' || theKey == 'I') {
168                         eyePhi -= M_PI / 20;
169                 if (eyePhi == 0)
170                                 eyePhi = 2 * M_PI;
171                 } else if (theKey == 'm' || theKey == 'I') {
172                         eyePhi += M_PI / 20;
173                 } else if (theKey == 'j' || theKey == 'J') {
174                         eyeTheta -= M_PI / 20;
175                 } else if (theKey == 'k' || theKey == 'K') {
176                         eyeTheta += M_PI / 20;
177                 } else if (theKey == ',') {
178                         eyeRho += 0.5;
179                 } else if (theKey == '.' || theKey == 'I') {
180                         eyeRho -= 0.5;
181                 } else if (theKey == 'w' || theKey == 'W') {
182                         look[1] += 0.5;
183                 } else if (theKey == 'z' || theKey == 'Z') {
184                         look[1] -= 0.5;
185                 } else if (theKey == 'a' || theKey == 'A') {
186                         look[0] -= 0.5;
187                 } else if (theKey == 's' || theKey == 'S') {
188                         look[0] += 0.5;
189                 } else if (theKey == '+') {
190                         scale *= 1.1;
191                 } else if (theKey == '-') {
192                         scale *= 0.9;
193                 }
194                 if (sin(eyePhi) > 0) upY = 1;
195                 else upY = 1;
196 }
197
198 /**
199  * @function Graphics_Reshape
200  * @purpose Resize the view window
201  * @param width, height - New size of the window
202  */
203 void Graphics_Reshape(int width, int height) 
204 {
205         double displayRatio = 1.0 * width / height;
206         windowWidth = width;
207         windowHeight = height;
208         glMatrixMode(GL_PROJECTION);
209         glLoadIdentity();
210         gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
211         glViewport(0, 0, windowWidth, windowHeight);
212 }
213
214
215

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