From 695965a636bddfbafa0e8b8c66bfd3e7efa5d440 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@0f7e0d06-a6f9-0310-a55f-d5f984f55e4c> Date: Thu, 10 Feb 2005 23:10:52 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'START'. git-svn-id: file:///usr/local/opt/svn/repos/glagen@6 0f7e0d06-a6f9-0310-a55f-d5f984f55e4c --- tags/START/glagen/3d/display.cc | 411 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 tags/START/glagen/3d/display.cc (limited to 'tags/START/glagen/3d/display.cc') diff --git a/tags/START/glagen/3d/display.cc b/tags/START/glagen/3d/display.cc new file mode 100644 index 0000000..a956274 --- /dev/null +++ b/tags/START/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 +#include +#include + +#ifndef DARWIN +# include +# include +# include +#else +# include +# include +# include +#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; +} -- cgit v1.2.3