/**
* @file graphics.c
* @author Sam Moore (20503628) 2012 - adapted from template program provided by UWA
- * @pur
+ * @purpose Definition of graphics related functions
+ */
+
+#include "graphics.h" //Function declarations
+#include <time.h> // Needed for clock
+#include <math.h> // Maths functions (sin, cos)
+/**
+ * Variables
+ */
+double previousTime, eyeTheta, eyePhi, eyeRho;
+float look[3];
+int windowWidth, windowHeight, upY;
-/*
- * Initialization of graphics
+double scale = 1.0;
+
+
+/**
+ * Initialise the graphics
*/
-void Init(void) {
+void Graphics_Init(void)
+{
glClearColor(1.0,1.0,1.0,0.0);
glColor3f(0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
- glColorMaterial(GL_FRONT,GL_DIFFUSE); // Set Color Capability
+ glColorMaterial(GL_FRONT,GL_DIFFUSE); // Set Color Capability
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
- glEnable(GL_COLOR_MATERIAL); // Enable color
+ glEnable(GL_COLOR_MATERIAL); // Enable color
- double displayRatio = 1.0 * WIDTH / HEIGHT;
+
windowWidth = WIDTH;
windowHeight = HEIGHT;
previousTime = clock();
eyeTheta = 0;
- eyePhi = 0.5 * M_PI;
- eyeRho = RHO;
- upY = 1;
+ eyePhi = 0.5 * M_PI;
+ eyeRho = RHO;
+ upY = 1;
look[0] = 0;
look[1] = 0;
look[2] = 0;
- gluPerspective(VIEW_ANGLE, displayRatio, WORLD_NEAR, WORLD_FAR);
+ gluPerspective(VIEW_ANGLE, (double)WIDTH/(double)HEIGHT, WORLD_NEAR, WORLD_FAR);
}
-/*
+/**
* This function redraws the screen after the positions of particles
* have been updated
*/
-void Display(void) {
+void Graphics_Display(System * s)
+{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(eyeRho * sin(eyePhi) * sin(eyeTheta), eyeRho * cos(eyePhi),
- eyeRho * sin(eyePhi) * cos(eyeTheta),
- look[0], look[1], look[2], 0, upY, 0);
-
- for (int i = 0; i < N; i++) {
- //glClearColor(1.0,1.0,1.0,0.0);
- glColor3f(0.0f, body[i].mass/1e11*100, 0.0f);
- //glColor3f(1.0f, 0.0f, 0.0f);
+ glLoadIdentity();
+ gluLookAt(eyeRho * sin(eyePhi) * sin(eyeTheta), eyeRho * cos(eyePhi),
+ eyeRho * sin(eyePhi) * cos(eyeTheta),look[0], look[1], look[2], 0, upY, 0);
+
+ for (int i = 0; i < s->N; ++i)
+ {
+ Body * b = s->body+i;
+ glColor3f(0.0f, b->mass/1e11*100, 0.0f);
glPushMatrix(); // to save the current matrix
- glTranslated(SCALE*body[i].X, SCALE*body[i].Y, SCALE*body[i].Z);
+ glTranslated(scale*b->x[0], scale*b->x[1], scale*b->x[2]);
glutSolidSphere (BALL_SIZE, 10, 10);
glPopMatrix(); // restore the previous matrix
}
glFlush();
}
+
+/**
+ * This function is to manipulate with the image
+ */
+void Graphics_Keyboard(unsigned char theKey, int mouseX, int mouseY)
+{
+ if (theKey == 'x' || theKey == 'X')
+ {
+ exit(EXIT_SUCCESS);
+ }
+
+ 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;
+}
+
+/**
+ * Resize the view 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);
+}
+
+
+/**
+ * This function is called repeatedly by graphics library. You can consider
+ * it as main loop in the program.
+ */
+void Graphics_Animate(void)
+{
+
+ System_Compute(&universe); //Compute and update new positions for the time step
+ Graphics_Display(&universe); // Display needs to be called to redraw the screen
+}