/* * Copyright 2011-2014 hasufell * * This file is part of a hasufell project. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "types.h" #include #include #include #include #include #include #include #define filename __FILE__ #define XY_WIRE_COUNT 10.0f #define ROT_FACTOR_PLANET_SUN (360.0 / yearabs) #define ROT_FACTOR_PLANET (360.0 / 1.0) #define ROT_FACTOR_MOON (360.0 / dayabs) #define SYSTEM_POS_Z -15.0f #define SYSTEM_POS_Z_BACK 15.0f int year; int yearabs = 365; int day; int dayabs = 30; HE_obj *obj; /* * static function declaration */ static void draw_Sun(void); static void draw_Planet_1(void); static void draw_Planet_2(void); /** * Draws a sun which changes its color randomly. */ static void draw_Sun(void) { glPushMatrix(); /* pull into middle of universe */ glTranslatef(-obj->faces->edge->vert->x, -obj->faces->edge->vert->y, -obj->faces->edge->vert->z + SYSTEM_POS_Z); glBegin(GL_POLYGON); glColor3f(0.0f, 1.0f, 0.0f); for (uint32_t i = 0; i < obj->fc; i++) { /* for all faces */ HE_edge *tmp_edge = obj->faces[i].edge; do { /* for all edges of the face */ glVertex3f(tmp_edge->vert->x, tmp_edge->vert->y, tmp_edge->vert->z); } while ((tmp_edge = tmp_edge->next) != obj->faces[i].edge); } glEnd(); glPopMatrix(); } /** * Draws a planet with some Saturn like rings, two moons and an axis. * Rotates the planet around the sun, the moons around the planet * and the planet around its axis. */ static void draw_Planet_1(void) { GLUquadric* quadric = NULL; quadric = gluNewQuadric(); const int rot_fac_day = 15; glPushMatrix(); //Rotate around the sun glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(90, 1.0f, 0.0f, 0.0f); glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, 1.0f); glTranslatef(0.0f, 4.0f, 0.0f); glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, -1.0f); glRotatef(315, 0.0f, 1.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); //A rotation (full 360°) once a day is much too fast you woulden'd see a thing glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, 1.0f); glutWireSphere(1.0f, XY_WIRE_COUNT, XY_WIRE_COUNT); glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, -1.0f); //Center axis glPushMatrix(); glLineWidth(3); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_LOOP); glVertex3f(0, 0, -5); glVertex3f(0, 0, 5); glEnd(); glPopMatrix(); //circle1 glPushMatrix(); glColor3f(0.8f, 0.0f, 0.2f); //glRotatef(90, 0.0f, 1.0f, 0.0f); //"senkrecht zur Planetenachse" gluDisk(quadric, 1.2f, 1.3f, 32, 1); glPopMatrix(); //circle2 glPushMatrix(); glColor3f(0.0f, 1.0f, 0.0f); //glRotatef(90, 0.0f, 1.0f, 0.0f); //"senkrecht zur Planetenachse" gluDisk(quadric, 1.4f, 1.7f, 32, 1); glPopMatrix(); //Moon1 glPushMatrix(); glColor3f(0.0f, 0.0f, 1.0f); //glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); //"senkrecht zur Planetenachse" glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f); glTranslatef(0.0f, 2.0f, 0.0f); glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT); glPopMatrix(); //Moon2 glPushMatrix(); glColor3f(0.0f, 1.0f, 1.0f); //glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); //"senkrecht zur Planetenachse" glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f); glTranslatef(0.0f, -2.0f, 0.0f); glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT); glPopMatrix(); glPopMatrix(); } /** * Draws a Planet with three moons. * The planet rotates around the sun and the moons around the planet * and the planet around its axis. */ static void draw_Planet_2(void) { glPushMatrix(); const float moon_pos_fac = 2.5; //Rotate around the sun glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(90, 1.0f, 0.0f, 0.0f); glRotatef((ROT_FACTOR_PLANET_SUN * day), 0.0f, 0.0f, 1.0f); glTranslatef(-2.0f, -8.0f, 0.0f); glColor3f(0.0f, 0.0f, 1.0f); //A rotation (full 360°) once a day is much too fast you woulden'd see a thing const int rot_fac_day = 15; glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, 1.0f); glutWireSphere(1.3f, XY_WIRE_COUNT, XY_WIRE_COUNT); glRotatef((ROT_FACTOR_PLANET * day) / rot_fac_day, 0.0f, 0.0f, -1.0f); //Moon3 glPushMatrix(); glColor3f(1.0f, 1.0f, 1.0f); glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f); glTranslatef(cos(0 * (M_PI / 180)) * moon_pos_fac, sin(0 * (M_PI / 180)) * moon_pos_fac, 0.0f); glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT); glPopMatrix(); //Moon4 glPushMatrix(); glColor3f(1.0f, 0.0f, 1.0f); glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f); glTranslatef(cos(120 * (M_PI / 180)) * moon_pos_fac, sin(120 * (M_PI / 180)) * moon_pos_fac, 0.0f); glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT); glPopMatrix(); //Moon5 glPushMatrix(); glColor3f(1.0f, 0.0f, 0.0f); glRotatef((ROT_FACTOR_MOON * day), 0.0f, 0.0f, 1.0f); glTranslatef(cos(240 * (M_PI / 180)) * moon_pos_fac, sin(240 * (M_PI / 180)) * moon_pos_fac, 0.0f); glutWireSphere(0.1f, XY_WIRE_COUNT, XY_WIRE_COUNT); glPopMatrix(); glPopMatrix(); } /** * Displays the whole setup with the sun, planet one, planet two and the frame rate */ void display(void) { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); draw_Sun(); draw_Planet_1(); draw_Planet_2(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(0.0, 500, 0.0, 500); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0f, 1.0f, 1.0f); glRasterPos2i(5, 10); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glEnable(GL_TEXTURE_2D); glutSwapBuffers(); } /** * Sets the initial values to start the program. */ void init(HE_obj *myobj) { obj = myobj; day = 0; year = 0; glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } /** * Is called when the window size changes. * Fits the viewport to the new dimension. * * @param w the new width of the window * @param h the new height of the window */ void reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w / (GLfloat) h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -5.0); } /** * Is called over and over again. * Counts the years and days. */ void animate() { day++; if (day >= yearabs) { day = 0; year++; } if (year >= (INT_MAX - 1000) || year < 0) { year = 0; } if (day < 0) { day = 0; } /* cout << day << endl; */ usleep(30000); // some very basic VScny to see the movement better glutPostRedisplay(); } /** * Keyboard callback function, * * press t to increase the day * press T to decrease the day * press j to increase the year * press J to decrease the year * press x to rotate the whole scene in x direction * press X to rotate the whole scene in -x direction * press y to rotate the whole scene in y direction * press Y to rotate the whole scene in -y direction * press c to rotate the whole scene in z direction * press C to rotate the whole scene in -z direction * press w to translate the whole scene in y direction * press s to translate the whole scene in -y direction * press a to translate the whole scene in -x direction * press d to translate the whole scene in x direction * press q to translate the whole scene in z direction * press e to translate the whole scene in -z direction * * @param key which was pressed * @param x coordinate * @param y coordinate */ void keyboard(unsigned char key, int x, int y) { switch (key) { case 't': dayabs += 15; glutPostRedisplay(); break; case 'j': yearabs += 50; glutPostRedisplay(); break; case 'T': dayabs -= 15; glutPostRedisplay(); break; case 'J': yearabs -= 50; glutPostRedisplay(); break; case 'x': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, 1.0f, 0.0f, 0.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'y': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, 0.0f, 1.0f, 0.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'c': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, 0.0f, 0.0f, 1.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'X': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, -1.0f, 0.0f, 0.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'Y': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, 0.0f, -1.0f, 0.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'C': glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z); glRotatef(1, 0.0f, 0.0f, -1.0f); glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK); glutPostRedisplay(); break; case 'w': glTranslatef(0.0f, 1.0f, 0.0f); break; case 'a': glTranslatef(-1.0f, 0.0f, 0.0f); break; case 's': glTranslatef(0.0f, -1.0f, 0.0f); break; case 'd': glTranslatef(1.0f, 0.0f, 0.0f); break; case 'q': glTranslatef(0.0f, 0.0f, 1.0f); break; case 'e': glTranslatef(0.0f, 0.0f, -1.0f); break; } }