2014-05-08 20:46:11 +00:00
|
|
|
/*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2014-05-10 17:33:54 +00:00
|
|
|
/**
|
|
|
|
* @file gl_draw.c
|
|
|
|
* This file does the actual OpenGL and GLUT logic,
|
|
|
|
* drawing the objects, handling keyboard input and
|
|
|
|
* various GLUT-related callback functions.
|
|
|
|
* @brief OpenGL drawing
|
|
|
|
*/
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
#include "err.h"
|
|
|
|
#include "filereader.h"
|
2014-05-10 17:16:13 +00:00
|
|
|
#include "half_edge.h"
|
2014-05-08 20:45:16 +00:00
|
|
|
|
|
|
|
#include <GL/glut.h>
|
|
|
|
#include <GL/gl.h>
|
|
|
|
#include <GL/glu.h>
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2014-05-15 22:32:38 +00:00
|
|
|
#include <string.h>
|
2014-05-08 20:45:16 +00:00
|
|
|
|
|
|
|
#define XY_WIRE_COUNT 10.0f
|
|
|
|
|
2014-05-15 22:32:38 +00:00
|
|
|
#define FPS_OUT_SIZE 17
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
#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
|
2014-05-09 17:47:05 +00:00
|
|
|
#define VISIBILITY_FACTOR 5.0f
|
2014-05-15 16:33:43 +00:00
|
|
|
#define FAR_CLIPPING_PLANE 60.0f
|
|
|
|
#define NEAR_CLIPPING_PLANE 1.0f
|
|
|
|
#define CAMERA_ANGLE 60.0f
|
2014-05-08 20:45:16 +00:00
|
|
|
|
|
|
|
int year;
|
|
|
|
int yearabs = 365;
|
|
|
|
int day;
|
|
|
|
int dayabs = 30;
|
|
|
|
HE_obj *obj;
|
2014-05-12 18:20:03 +00:00
|
|
|
bool show_normals = false;
|
2014-05-15 16:33:43 +00:00
|
|
|
bool shademodel = true;
|
2014-05-08 20:45:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* static function declaration
|
|
|
|
*/
|
2014-05-12 17:49:52 +00:00
|
|
|
static void draw_obj(int32_t const myxrot,
|
|
|
|
int32_t const myyrot,
|
|
|
|
int32_t const myzrot);
|
2014-05-08 20:45:16 +00:00
|
|
|
static void draw_Planet_1(void);
|
|
|
|
static void draw_Planet_2(void);
|
2014-05-09 12:54:47 +00:00
|
|
|
static void gl_destroy(void);
|
2014-05-15 16:33:43 +00:00
|
|
|
static void draw_normals(HE_obj const * const obj,
|
|
|
|
float const scale_inc);
|
|
|
|
static void draw_vertices(HE_obj const * const obj,
|
|
|
|
bool disco);
|
2014-05-15 22:32:38 +00:00
|
|
|
static float calculateFPS();
|
2014-05-09 15:53:02 +00:00
|
|
|
|
|
|
|
|
2014-05-17 01:54:07 +00:00
|
|
|
/**
|
|
|
|
* Draws the vertex normals of the object.
|
|
|
|
*
|
|
|
|
* @param obj the object to draw the vertex normals of
|
|
|
|
* @param scale_inc the incrementor for scaling the normals
|
|
|
|
*/
|
2014-05-15 16:33:43 +00:00
|
|
|
static void draw_normals(HE_obj const * const obj,
|
|
|
|
float const scale_inc)
|
2014-05-12 18:20:03 +00:00
|
|
|
{
|
2014-05-17 01:32:14 +00:00
|
|
|
static float normals_scale_factor = 0.1f;
|
2014-05-15 16:33:43 +00:00
|
|
|
static float line_width = 2;
|
2014-05-12 18:20:03 +00:00
|
|
|
vector vec;
|
|
|
|
|
2014-05-15 16:33:43 +00:00
|
|
|
normals_scale_factor += scale_inc;
|
|
|
|
|
|
|
|
glPushMatrix();
|
2014-05-13 11:47:13 +00:00
|
|
|
|
2014-05-15 16:33:43 +00:00
|
|
|
glLineWidth(line_width);
|
|
|
|
glColor3f(1.0, 0.0, 0.0);
|
2014-05-13 11:47:13 +00:00
|
|
|
|
2014-05-15 16:33:43 +00:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
for (uint32_t i = 0; i < obj->vc; i++) {
|
2014-05-17 12:55:46 +00:00
|
|
|
/* be fault tolerant here, so we don't just
|
|
|
|
* kill the whole thing, because the normals failed to draw */
|
|
|
|
if (!vec_normal(&(obj->vertices[i]), &vec))
|
|
|
|
break;
|
2014-05-13 11:47:13 +00:00
|
|
|
|
|
|
|
glVertex3f(obj->vertices[i].vec->x,
|
|
|
|
obj->vertices[i].vec->y,
|
|
|
|
obj->vertices[i].vec->z);
|
2014-05-15 16:33:43 +00:00
|
|
|
glVertex3f(obj->vertices[i].vec->x + (vec.x * normals_scale_factor),
|
|
|
|
obj->vertices[i].vec->y + (vec.y * normals_scale_factor),
|
|
|
|
obj->vertices[i].vec->z + (vec.z * normals_scale_factor));
|
2014-05-12 18:20:03 +00:00
|
|
|
}
|
2014-05-15 16:33:43 +00:00
|
|
|
glEnd();
|
|
|
|
glPopMatrix();
|
2014-05-12 18:20:03 +00:00
|
|
|
}
|
|
|
|
|
2014-05-09 13:03:46 +00:00
|
|
|
/**
|
2014-05-17 01:54:07 +00:00
|
|
|
* Draws all vertices of the object by
|
|
|
|
* assembling a polygon for each face.
|
2014-05-09 13:03:46 +00:00
|
|
|
*
|
|
|
|
* @param obj the object of which we will draw the vertices
|
2014-05-15 16:33:43 +00:00
|
|
|
* @param disco_set determines whether we are in disco mode
|
2014-05-09 13:03:46 +00:00
|
|
|
*/
|
2014-05-15 16:33:43 +00:00
|
|
|
static void draw_vertices(HE_obj const * const obj,
|
|
|
|
bool disco_set)
|
2014-05-09 12:54:47 +00:00
|
|
|
{
|
2014-05-15 16:33:43 +00:00
|
|
|
/* color */
|
|
|
|
static float red = 90,
|
|
|
|
blue = 90,
|
|
|
|
green = 90;
|
|
|
|
static bool disco = false;
|
|
|
|
|
|
|
|
if (disco_set)
|
|
|
|
disco = !disco;
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
2014-05-09 12:54:47 +00:00
|
|
|
for (uint32_t i = 0; i < obj->fc; i++) { /* for all faces */
|
|
|
|
HE_edge *tmp_edge = obj->faces[i].edge;
|
|
|
|
|
2014-05-15 16:33:43 +00:00
|
|
|
/* add random values */
|
|
|
|
red += rand() / (RAND_MAX / ((rand() % 11) / 10.0f));
|
|
|
|
blue += rand() / (RAND_MAX / ((rand() % 11) / 10.0f));
|
|
|
|
green += rand() / (RAND_MAX / ((rand() % 11) / 10.0f));
|
|
|
|
|
|
|
|
/* values above 180 will cause negative color values */
|
|
|
|
red = fmodf(red, 181.0f);
|
|
|
|
blue = fmodf(blue, 181.0f);
|
|
|
|
green = fmodf(green, 181.0f);
|
|
|
|
|
|
|
|
if (disco) {
|
|
|
|
tmp_edge->vert->col->red =
|
|
|
|
(sin(red * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
tmp_edge->vert->col->green =
|
|
|
|
(sin(green * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
tmp_edge->vert->col->blue =
|
|
|
|
(sin(blue * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
} else {
|
|
|
|
if (tmp_edge->vert->col->red == -1)
|
|
|
|
tmp_edge->vert->col->red =
|
|
|
|
(sin(red * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
|
|
|
|
if (tmp_edge->vert->col->green == -1)
|
|
|
|
tmp_edge->vert->col->green =
|
|
|
|
(sin(green * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
|
|
|
|
if (tmp_edge->vert->col->blue == -1)
|
|
|
|
tmp_edge->vert->col->blue =
|
|
|
|
(sin(blue * i * (M_PI / 180)) / 2) + 0.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
glBegin(GL_POLYGON);
|
2014-05-09 12:54:47 +00:00
|
|
|
do { /* for all edges of the face */
|
2014-05-15 16:33:43 +00:00
|
|
|
glColor3f(tmp_edge->vert->col->red,
|
|
|
|
tmp_edge->vert->col->green,
|
|
|
|
tmp_edge->vert->col->blue);
|
|
|
|
|
2014-05-12 17:48:46 +00:00
|
|
|
glVertex3f(tmp_edge->vert->vec->x,
|
|
|
|
tmp_edge->vert->vec->y,
|
|
|
|
tmp_edge->vert->vec->z);
|
2014-05-15 16:33:43 +00:00
|
|
|
|
2014-05-09 12:54:47 +00:00
|
|
|
} while ((tmp_edge = tmp_edge->next) != obj->faces[i].edge);
|
2014-05-15 16:33:43 +00:00
|
|
|
glEnd();
|
2014-05-09 12:54:47 +00:00
|
|
|
}
|
2014-05-15 16:33:43 +00:00
|
|
|
glPopMatrix();
|
2014-05-09 12:54:47 +00:00
|
|
|
}
|
2014-05-08 20:45:16 +00:00
|
|
|
|
2014-05-15 16:33:43 +00:00
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
/**
|
2014-05-09 12:27:58 +00:00
|
|
|
* Draws an object.
|
|
|
|
*
|
|
|
|
* @param myxrot rotation increment around x-axis
|
|
|
|
* @param myyrot rotation increment around x-axis
|
|
|
|
* @param myzrot rotation increment around x-axis
|
2014-05-08 20:45:16 +00:00
|
|
|
*/
|
2014-05-12 17:49:52 +00:00
|
|
|
static void draw_obj(int32_t const myxrot,
|
|
|
|
int32_t const myyrot,
|
|
|
|
int32_t const myzrot)
|
2014-05-08 20:45:16 +00:00
|
|
|
{
|
2014-05-12 18:55:16 +00:00
|
|
|
/* rotation */
|
2014-05-12 17:49:52 +00:00
|
|
|
static int32_t xrot = 0,
|
2014-05-09 12:27:58 +00:00
|
|
|
yrot = 0,
|
|
|
|
zrot = 0;
|
2014-05-12 18:55:16 +00:00
|
|
|
|
2014-05-11 12:02:34 +00:00
|
|
|
vector center_vert;
|
2014-05-09 12:27:58 +00:00
|
|
|
|
2014-05-13 11:47:13 +00:00
|
|
|
FIND_CENTER(obj, ¢er_vert);
|
2014-05-11 12:02:34 +00:00
|
|
|
|
2014-05-12 18:55:16 +00:00
|
|
|
/* increment rotation, if any */
|
2014-05-09 12:27:58 +00:00
|
|
|
xrot += myxrot;
|
|
|
|
yrot += myyrot;
|
|
|
|
zrot += myzrot;
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* rotate according to static members */
|
|
|
|
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z);
|
2014-05-12 18:20:03 +00:00
|
|
|
glScalef(VISIBILITY_FACTOR,
|
|
|
|
VISIBILITY_FACTOR,
|
|
|
|
VISIBILITY_FACTOR);
|
2014-05-09 12:27:58 +00:00
|
|
|
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
|
|
|
|
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
|
|
|
|
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
|
|
|
|
glTranslatef(0.0f, 0.0f, SYSTEM_POS_Z_BACK);
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
/* pull into middle of universe */
|
2014-05-11 12:02:34 +00:00
|
|
|
glTranslatef(-center_vert.x,
|
|
|
|
-center_vert.y,
|
|
|
|
-center_vert.z + SYSTEM_POS_Z);
|
2014-05-08 20:45:16 +00:00
|
|
|
|
2014-05-12 18:20:03 +00:00
|
|
|
if (show_normals)
|
2014-05-15 16:33:43 +00:00
|
|
|
draw_normals(obj, 0);
|
|
|
|
|
|
|
|
draw_vertices(obj, false);
|
2014-05-08 20:45:16 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Rotate around the sun */
|
2014-05-08 20:45:16 +00:00
|
|
|
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);
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* A rotation (full 360°) once a day is much
|
|
|
|
* too fast you woulden'd see a thing */
|
2014-05-08 20:45:16 +00:00
|
|
|
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);
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Center axis */
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glLineWidth(3);
|
|
|
|
glColor3f(1.0, 1.0, 1.0);
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3f(0, 0, -5);
|
|
|
|
glVertex3f(0, 0, 5);
|
|
|
|
glEnd();
|
|
|
|
glPopMatrix();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* circle1 */
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glColor3f(0.8f, 0.0f, 0.2f);
|
2014-05-09 12:27:58 +00:00
|
|
|
/* glRotatef(90, 0.0f, 1.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
|
2014-05-08 20:45:16 +00:00
|
|
|
gluDisk(quadric, 1.2f, 1.3f, 32, 1);
|
|
|
|
glPopMatrix();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* circle2 */
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glColor3f(0.0f, 1.0f, 0.0f);
|
2014-05-09 12:27:58 +00:00
|
|
|
/* glRotatef(90, 0.0f, 1.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
|
2014-05-08 20:45:16 +00:00
|
|
|
gluDisk(quadric, 1.4f, 1.7f, 32, 1);
|
|
|
|
glPopMatrix();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Moon1 */
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glColor3f(0.0f, 0.0f, 1.0f);
|
2014-05-09 12:27:58 +00:00
|
|
|
/* glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
|
2014-05-08 20:45:16 +00:00
|
|
|
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();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Moon2 */
|
2014-05-08 20:45:16 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glColor3f(0.0f, 1.0f, 1.0f);
|
2014-05-09 12:27:58 +00:00
|
|
|
/* glRotatef((ROT_FACTOR_MOON * day), 1.0f, 0.0f, 0.0f); [> "senkrecht zur Planetenachse" <] */
|
2014-05-08 20:45:16 +00:00
|
|
|
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;
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Rotate around the sun */
|
2014-05-08 20:45:16 +00:00
|
|
|
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);
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* A rotation (full 360°) once a day is much
|
|
|
|
* too fast you woulden'd see a thing */
|
2014-05-08 20:45:16 +00:00
|
|
|
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);
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Moon3 */
|
2014-05-08 20:45:16 +00:00
|
|
|
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();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Moon4 */
|
2014-05-08 20:45:16 +00:00
|
|
|
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();
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
/* Moon5 */
|
2014-05-08 20:45:16 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2014-05-15 22:32:38 +00:00
|
|
|
/**
|
|
|
|
* Calculates the frames per second rate.
|
|
|
|
*
|
|
|
|
* @return the actual frames per second rate
|
|
|
|
*/
|
|
|
|
static float calculateFPS(void)
|
|
|
|
{
|
|
|
|
static int frameCount = 0;
|
|
|
|
static int currentTime = 0;
|
|
|
|
static int previousTime = 0;
|
|
|
|
static float fps = 0;
|
|
|
|
|
|
|
|
frameCount++;
|
|
|
|
currentTime = glutGet(GLUT_ELAPSED_TIME);
|
|
|
|
int timeInterval = currentTime - previousTime;
|
|
|
|
if (timeInterval > 1000) {
|
|
|
|
fps = frameCount / (timeInterval / 1000.0f);
|
|
|
|
previousTime = currentTime;
|
|
|
|
frameCount = 0;
|
|
|
|
}
|
|
|
|
return fps;
|
|
|
|
}
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
/**
|
2014-05-09 15:53:16 +00:00
|
|
|
* Displays the whole setup with the sun, planet one,
|
|
|
|
* planet two and the frame rate
|
2014-05-08 20:45:16 +00:00
|
|
|
*/
|
|
|
|
void display(void)
|
|
|
|
{
|
2014-05-15 22:32:38 +00:00
|
|
|
char fps_out[FPS_OUT_SIZE];
|
|
|
|
char *tmp_ptr = fps_out;
|
|
|
|
float fps = calculateFPS();
|
|
|
|
int i;
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
2014-05-09 12:27:58 +00:00
|
|
|
draw_obj(0, 0, 0);
|
2014-05-08 20:45:16 +00:00
|
|
|
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);
|
|
|
|
|
2014-05-15 22:32:38 +00:00
|
|
|
sprintf(fps_out, "FPS: %f", fps);
|
|
|
|
|
|
|
|
for (i = 0; i < FPS_OUT_SIZE; ++i)
|
|
|
|
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *tmp_ptr++);
|
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glPopMatrix();
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glPopMatrix();
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glutSwapBuffers();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the initial values to start the program.
|
|
|
|
*/
|
2014-05-09 12:27:58 +00:00
|
|
|
void init(char const * const filename)
|
2014-05-08 20:45:16 +00:00
|
|
|
{
|
2014-05-09 12:27:58 +00:00
|
|
|
obj = read_obj_file(filename);
|
|
|
|
if (!obj)
|
|
|
|
ABORT("Failed to read object file \"%s\"!", filename);
|
2014-05-12 18:20:17 +00:00
|
|
|
|
2014-05-13 12:05:02 +00:00
|
|
|
NORMALIZE_OBJECT(obj);
|
2014-05-12 18:20:17 +00:00
|
|
|
|
2014-05-08 20:45:16 +00:00
|
|
|
day = 0;
|
|
|
|
year = 0;
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2014-05-15 16:33:43 +00:00
|
|
|
glShadeModel(GL_SMOOTH);
|
2014-05-08 20:45:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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();
|
2014-05-15 16:33:43 +00:00
|
|
|
gluPerspective(CAMERA_ANGLE,
|
|
|
|
(GLfloat) w / (GLfloat) h,
|
|
|
|
NEAR_CLIPPING_PLANE,
|
|
|
|
FAR_CLIPPING_PLANE);
|
2014-05-08 20:45:16 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-05-12 18:20:17 +00:00
|
|
|
usleep(30000); /* some very basic VScny to see the movement better */
|
2014-05-08 20:45:16 +00:00
|
|
|
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
|
2014-05-17 01:40:13 +00:00
|
|
|
* press b to toggle GL_CULL_FACE
|
|
|
|
* press D to toggle disco mode
|
|
|
|
* press S to toggle shade model between GL_SMOOTH and GL_FLAT
|
|
|
|
* press n to toggle normals
|
|
|
|
* press k to increase length of normals
|
|
|
|
* press l to decrease length of normals
|
2014-05-09 12:27:58 +00:00
|
|
|
* press x to rotate the middle object in x direction
|
2014-05-17 01:40:13 +00:00
|
|
|
* press X to rotate the middle object in -x direction
|
2014-05-09 12:27:58 +00:00
|
|
|
* press y to rotate the middle object in y direction
|
2014-05-17 01:40:13 +00:00
|
|
|
* press Y to rotate the middle object in -y direction
|
2014-05-09 12:27:58 +00:00
|
|
|
* press c to rotate the middle object in z direction
|
2014-05-17 01:40:13 +00:00
|
|
|
* press C to rotate the middle object in -z direction
|
2014-05-08 20:45:16 +00:00
|
|
|
* 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
|
2014-05-17 01:40:13 +00:00
|
|
|
* press q to quit
|
2014-05-08 20:45:16 +00:00
|
|
|
*
|
|
|
|
* @param key which was pressed
|
|
|
|
* @param x coordinate
|
|
|
|
* @param y coordinate
|
|
|
|
*/
|
|
|
|
void keyboard(unsigned char key, int x, int y)
|
|
|
|
{
|
|
|
|
switch (key) {
|
2014-05-15 16:33:43 +00:00
|
|
|
case 'b':
|
|
|
|
if (glIsEnabled(GL_CULL_FACE))
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
else
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
2014-05-08 20:45:16 +00:00
|
|
|
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':
|
2014-05-12 17:49:52 +00:00
|
|
|
draw_obj(2, 0, 0);
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
draw_obj(-2, 0, 0);
|
2014-05-08 20:45:16 +00:00
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'y':
|
2014-05-12 17:49:52 +00:00
|
|
|
draw_obj(0, 2, 0);
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'Y':
|
|
|
|
draw_obj(0, -2, 0);
|
2014-05-08 20:45:16 +00:00
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'c':
|
2014-05-12 17:49:52 +00:00
|
|
|
draw_obj(0, 0, 2);
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
draw_obj(0, 0, -2);
|
2014-05-08 20:45:16 +00:00
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
2014-05-15 16:33:43 +00:00
|
|
|
case 'D':
|
|
|
|
draw_vertices(obj, true);
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
if (shademodel) {
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
shademodel = false;
|
|
|
|
} else {
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
shademodel = true;
|
|
|
|
}
|
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'k':
|
2014-05-17 01:32:14 +00:00
|
|
|
draw_normals(obj, 0.01f);
|
2014-05-15 16:33:43 +00:00
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
|
|
|
case 'l':
|
2014-05-17 01:32:14 +00:00
|
|
|
draw_normals(obj, -0.01f);
|
2014-05-15 16:33:43 +00:00
|
|
|
glutPostRedisplay();
|
|
|
|
break;
|
2014-05-08 20:45:16 +00:00
|
|
|
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;
|
2014-05-12 18:20:03 +00:00
|
|
|
case 'n':
|
2014-05-12 21:38:27 +00:00
|
|
|
show_normals = !show_normals;
|
2014-05-12 18:20:03 +00:00
|
|
|
break;
|
2014-05-09 12:55:03 +00:00
|
|
|
case '+':
|
2014-05-08 20:45:16 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, 1.0f);
|
|
|
|
break;
|
2014-05-09 12:55:03 +00:00
|
|
|
case '-':
|
2014-05-08 20:45:16 +00:00
|
|
|
glTranslatef(0.0f, 0.0f, -1.0f);
|
|
|
|
break;
|
2014-05-09 12:55:03 +00:00
|
|
|
case 'q':
|
2014-05-09 12:55:16 +00:00
|
|
|
gl_destroy();
|
|
|
|
break;
|
2014-05-08 20:45:16 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-09 12:55:16 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy the gl session/window.
|
|
|
|
*/
|
|
|
|
static void gl_destroy(void)
|
|
|
|
{
|
2014-05-12 21:02:10 +00:00
|
|
|
delete_object(obj);
|
2014-05-09 12:55:16 +00:00
|
|
|
free(obj);
|
|
|
|
glutDestroyWindow(glutGetWindow());
|
|
|
|
}
|