From fa8061541550b331249ad2eb1c7cf52b8694e76a Mon Sep 17 00:00:00 2001 From: hasufell Date: Thu, 8 May 2014 22:45:16 +0200 Subject: [PATCH] Include opengl, draw the imported object --- Makefile | 4 +- draw.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ draw.h | 37 ++++++ main.c | 34 ++++- 4 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 draw.c create mode 100644 draw.h diff --git a/Makefile b/Makefile index 31d53db..4d9d3f8 100644 --- a/Makefile +++ b/Makefile @@ -15,8 +15,8 @@ CFLAGS += -O0 -g3 endif TARGET = drow-engine -HEADERS = err.h parser.h types.h print.h filereader.h -OBJECTS = main.o parser.o print.o filereader.o +HEADERS = err.h parser.h types.h print.h filereader.h draw.h +OBJECTS = main.o parser.o print.o filereader.o draw.c INCS = -I. CFLAGS += $(shell $(PKG_CONFIG) --cflags gl glu glib-2.0) diff --git a/draw.c b/draw.c new file mode 100644 index 0000000..499e2f4 --- /dev/null +++ b/draw.c @@ -0,0 +1,379 @@ +#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; + } +} diff --git a/draw.h b/draw.h new file mode 100644 index 0000000..bf7ec7f --- /dev/null +++ b/draw.h @@ -0,0 +1,37 @@ +/* + * 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 . + */ + +#ifndef _DROW_ENGINE_DRAW_H +#define _DROW_ENGINE_DRAW_H + + +#include "types.h" + +#include +#include +#include + + +void init(HE_obj *myobj); +void display(void); +void reshape(GLsizei w, GLsizei h); +void animate(); +void keyboard(unsigned char key, int x, int y); + + +#endif /* _DROW_ENGINE_DRAW_H */ diff --git a/main.c b/main.c index 8e14269..c35a425 100644 --- a/main.c +++ b/main.c @@ -16,12 +16,19 @@ * along with this program. If not, see . */ +#include "draw.h" #include "filereader.h" #include "print.h" #include "types.h" +#include +#include +#include #include +#define filename __FILE__ + + /** * Program help text. */ @@ -30,7 +37,13 @@ char const * const helptext = "Usage: drow-engine \n"; int main(int argc, char *argv[]) { - HE_obj *obj; + HE_obj *obj = NULL; + + int windowX; + int windowY; + int screenX; + int screenY; + float factor = 0.80; // percent of screen if (argc > 1) { obj = read_obj_file(argv[1]); @@ -41,5 +54,24 @@ int main(int argc, char *argv[]) printf("%s", helptext); } + glutInit(&argc, argv); + screenX = glutGet(GLUT_SCREEN_WIDTH); + windowX = (screenX * factor); + screenY = glutGet(GLUT_SCREEN_HEIGHT); + windowY = (screenY * factor); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowPosition(((screenX / 2) - (windowX / 2)), + ((screenY / 2) - (windowY / 2))); + glutInitWindowSize(windowX, windowY); + glutCreateWindow(filename); + + init(obj); + + glutKeyboardFunc(keyboard); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutIdleFunc(animate); + glutMainLoop(); + return 0; }