summaryrefslogtreecommitdiff
path: root/branches/hugues/glagen/3d/display.cc
diff options
context:
space:
mode:
Diffstat (limited to 'branches/hugues/glagen/3d/display.cc')
-rw-r--r--branches/hugues/glagen/3d/display.cc411
1 files changed, 411 insertions, 0 deletions
diff --git a/branches/hugues/glagen/3d/display.cc b/branches/hugues/glagen/3d/display.cc
new file mode 100644
index 0000000..a956274
--- /dev/null
+++ b/branches/hugues/glagen/3d/display.cc
@@ -0,0 +1,411 @@
+//=============================================================================
+//
+// Glagen : a planet sized landscape generator
+// Copyright (C) 2002 Julien Guertault, Hugues Hiegel, Meng-Tih Lam
+//
+// 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; either version 2
+// of the License, or (at your option) any later version.
+//
+// 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+//
+// Glagen : GPL LAndscape GENerator
+//
+// display.cc for Glagen : made by Zavie (Julien Guertault)
+//
+// www.glagen.org
+//
+//=============================================================================
+
+#include <cstdlib>
+#include <cstdio>
+#include <cmath>
+
+#ifndef DARWIN
+# include <GL/gl.h>
+# include <GL/glu.h>
+# include <GL/glut.h>
+#else
+# include <gl.h>
+# include <glu.h>
+# include <glut.h>
+#endif
+
+#include "data_glagen.hh"
+#include "end.hh"
+#include "library.hh"
+#include "time.hh"
+#include "triangle.hh"
+
+bool pressed;
+int x;
+int y;
+int xold;
+int yold;
+
+static const GLfloat L0position[] = { 0.0, 1.0, -2.0, 0.0 };
+static const GLfloat L0ambient[] = { 0.0, 0.0, 0.0, 1.0 };
+static const GLfloat L0diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
+static const GLfloat L0specular[] = { 1.0, 1.0, 1.0, 1.0 };
+static const GLfloat Mshiny = 50;
+
+void display_frame ()
+{
+ Frame *o = &glagen.observer.frame;
+
+ update_time ();
+
+ glagen.step = glagen.step + 1;
+ if (glagen.display_planet == true)
+ library_caller (glagen.ref);
+ glagen.step = glagen.step + 1;
+ glagen.ref->Update_normal_visitor ();
+ glagen.step = glagen.step + 1;
+
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity ();
+
+ // Third person view : the observer is represented by a frame
+ if (glagen.third_view == true)
+ {
+ // View initialization in third person view mode
+ gluPerspective(45,
+ float(glagen.x) / float(glagen.y),
+ 0.5,
+ 8.0);
+ gluLookAt (-4, 4, -4,
+ 1, -1, 1,
+ 0, 1, 0);
+
+ // The frame representing the user's position
+ if (glagen.light == true)
+ glDisable(GL_LIGHTING);
+ glBegin (GL_LINES);
+ glColor3f(1.0, 1.0, 0.0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), o->Origin_Z ());
+ glVertex3f(o->Origin_X () + o->Basis_X ().X () / 2,
+ o->Origin_Y () + o->Basis_X ().Y () / 2,
+ o->Origin_Z () + o->Basis_X ().Z () / 2);
+ glColor3f(0.0, 1.0, 1.0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), o->Origin_Z ());
+ glVertex3f(o->Origin_X () + o->Basis_Y ().X () / 2,
+ o->Origin_Y () + o->Basis_Y ().Y () / 2,
+ o->Origin_Z () + o->Basis_Y ().Z () / 2);
+ glColor3f(1.0, 0.0, 1.0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), o->Origin_Z ());
+ glVertex3f(o->Origin_X () + o->Basis_Z ().X () / 2,
+ o->Origin_Y () + o->Basis_Z ().Y () / 2,
+ o->Origin_Z () + o->Basis_Z ().Z () / 2);
+
+ // Then the projection of the user's position on the planet's frame
+ glColor3f(1.0, 1.0, 1.0);
+ glVertex3f(0, 0, 0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), o->Origin_Z ());
+
+ glColor3f(1.0, 0.0, 0.0);
+ glVertex3f(0, 0, 0);
+ glVertex3f(o->Origin_X (), 0, 0);
+
+ glColor3f(0.0, 1.0, 0.0);
+ glVertex3f(o->Origin_X (), 0, 0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), 0);
+
+ glColor3f(0.0, 0.0, 1.0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), 0);
+ glVertex3f(o->Origin_X (), o->Origin_Y (), o->Origin_Z ());
+
+ glEnd ();
+ if (glagen.light == true)
+ glEnable(GL_LIGHTING);
+ }
+ else
+ {
+ // View initialization in normal view
+ if (glagen.x > glagen.y)
+ gluPerspective(45 * float(glagen.y) / float(glagen.x),
+ float(glagen.x) / float(glagen.y),
+ glagen.observer.altitude / 2,
+ glagen.observer.altitude + 1);
+ else
+ gluPerspective(45,
+ float(glagen.x) / float(glagen.y),
+ glagen.observer.altitude / 2,
+ glagen.observer.altitude + 1);
+ gluLookAt (o->Origin_X (), o->Origin_Y (), o->Origin_Z (),
+ o->Origin_X () + o->Basis_Z ().X (),
+ o->Origin_Y () + o->Basis_Z ().Y (),
+ o->Origin_Z () + o->Basis_Z ().Z (),
+ o->Basis_Y ().X (), o->Basis_Y ().Y (), o->Basis_Y (). Z ());
+ }
+
+
+ // The light
+ if (glagen.light == true)
+ {
+ glLightfv(GL_LIGHT0, GL_POSITION, L0position);
+ glEnable(GL_LIGHTING);
+ }
+
+ // The line calling the planet's display is just here
+ glagen.ref->Display (0);
+ glagen.step = glagen.step + 1;
+
+ if (glagen.light == true)
+ glDisable (GL_LIGHTING);
+
+// // Uncomment those lines for an atmosphere ===
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+// for (int current = 1; current < 100; current ++)
+// {
+// glagen.ref->Display (current);
+// glagen.step = glagen.step + 1;
+// }
+// glDisable (GL_BLEND);
+// //
+
+ glFlush ();
+
+ // On echange les buffers
+ glutSwapBuffers ();
+ glutPostRedisplay();
+}
+
+//
+// Simple keyboard events catching
+//
+void Keyboard (unsigned char key_stroke, int, int)
+{
+ switch (key_stroke)
+ {
+ // Quit
+ case 'q':
+ case 'Q':
+ case 27:
+ end_all();
+ }
+}
+
+//
+// Other keyboard events catching
+//
+void Keyboard_Special (int key_stroke, int, int)
+{
+ Frame *o = &glagen.observer.frame;
+ float ox = o->Origin_X ();
+ float oy = o->Origin_Y ();
+ float oz = o->Origin_Z ();
+
+ switch (key_stroke)
+ {
+ case GLUT_KEY_UP:
+ o->Translate (o->Basis_Z () * glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_DOWN:
+ o->Translate (o->Basis_Z () * -glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_LEFT:
+ o->Translate (o->Basis_X () * glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_RIGHT:
+ o->Translate (o->Basis_X () * -glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_PAGE_UP:
+ o->Translate (o->Basis_Y () * glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_PAGE_DOWN:
+ o->Translate (o->Basis_Y () * -glagen.observer.speed);
+ glagen.observer.speed = glagen.observer.altitude / 50;
+ glagen.observer.altitude = sqrtf (ox * ox + oy * oy + oz * oz) - 1;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ break;
+ case GLUT_KEY_F1:
+ if (glagen.mode == 1)
+ glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
+ else
+ {
+ if (glagen.mode == 2)
+ glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
+ else
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+ }
+ glagen.mode++;
+ if (glagen.mode > 3)
+ glagen.mode = 1;
+ glutPostRedisplay ();
+ break;
+ case GLUT_KEY_F2:
+ glagen.depth_test = !glagen.depth_test;
+ if (glagen.depth_test == true)
+ glEnable (GL_DEPTH_TEST);
+ else
+ glDisable (GL_DEPTH_TEST);
+ glutPostRedisplay ();
+ break;
+ case GLUT_KEY_F3:
+ glagen.display_normal = !glagen.display_normal;
+ break;
+ case GLUT_KEY_F4:
+ glagen.display_planet = !glagen.display_planet;
+ break;
+ case GLUT_KEY_F5:
+ glagen.display_all = !glagen.display_all;
+ break;
+ case GLUT_KEY_F6:
+ glagen.third_view = !glagen.third_view;
+ break;
+ case GLUT_KEY_F7:
+ glagen.light = !glagen.light;
+ break;
+ }
+// {
+// float alt = glagen.observer.altitude * 12000000;
+// if (alt > 1000)
+// printf ("%.3f km\n", alt / 1000);
+// else
+// printf ("%.3f m\n", alt);
+// }
+}
+
+void reshape (int x, int y)
+{
+ glagen.x = x;
+ glagen.y = y;
+ glViewport (0, 0, x, y);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+}
+
+void mouse(int button, int state, int x, int y)
+{
+ // sleft button pressed
+ if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
+ pressed = true;
+ // left button released
+ if (button == GLUT_LEFT_BUTTON && state == GLUT_UP)
+ {
+ pressed = false;
+ if (glagen.zoom)
+ glagen.ref->Split_visitor ();
+ glagen.step = glagen.step + 1;
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ }
+ xold = x; // saving position
+ yold = y;
+}
+
+void mousemotion(int x, int y)
+{
+ float angle[3];
+
+ if (pressed) // left button
+ {
+ angle[0] = (y - yold) / 100.0;
+ angle[1] = (xold - x) / 100.0;
+ angle[2] = 0;
+ }
+ else
+ {
+ angle[0] = 0;
+ angle[1] = 0;
+ angle[2] = (xold - x) / 50.0;
+ }
+
+ glagen.observer.frame.Rotate (angle[0], glagen.observer.frame.Basis_X ());
+ glagen.observer.frame.Rotate (angle[1], glagen.observer.frame.Basis_Y ());
+ glagen.observer.frame.Rotate (angle[2], glagen.observer.frame.Basis_Z ());
+ glagen.ref->Hide_visitor ();
+ glagen.step = glagen.step + 1;
+ glutPostRedisplay ();
+ xold = x;
+ yold = y;
+}
+
+void display(int *narg, char ***args)
+{
+ // Glut
+ glutInit (narg, *args);
+ glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ glutInitWindowSize (600, 600);
+ glutCreateWindow ("Test Glagen");
+
+ // OpenGL
+ glClearColor (0.0, 0.0, 0.0, 0.0);
+ glColor3f (1.0, 1.0, 1.0);
+ glEnable (GL_DEPTH_TEST);
+ glagen.mode = 1;
+ glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
+
+ // Light
+ glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
+ glEnable (GL_LIGHTING);
+ glEnable (GL_LIGHT0);
+ glLightfv (GL_LIGHT0, GL_DIFFUSE, L0diffuse);
+ glLightfv (GL_LIGHT0, GL_SPECULAR, L0specular);
+ glLightfv (GL_LIGHT0, GL_AMBIENT, L0ambient);
+ glEnable (GL_COLOR_MATERIAL);
+ glDisable (GL_LIGHTING);
+
+ // Events functions
+ glutDisplayFunc (display_frame);
+ glutKeyboardFunc (Keyboard);
+ glutSpecialFunc (Keyboard_Special);
+ glutReshapeFunc (reshape);
+ glutMouseFunc (mouse);
+ glutMotionFunc (mousemotion);
+
+ // Glut main loop ;-)
+ glutMainLoop ();
+ return;
+}