
/* Copyright (c) Mark J. Kilgard, 1997. */

/* This program is freely distributable without licensing fees 
   and is provided without guarantee or warrantee expressed or 
   implied. This program is -not- in the public domain. */

/* This program was requested by Patrick Earl; hopefully someone else
   will write the equivalent Direct3D immediate mode program. */

#include <GL/glut.h>

GLfloat light_diffuse1[] = {1.0, 0.2, 0.2, 1.0};  /* Red diffuse light. */
GLfloat light_position1[] = {1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */
GLfloat light_diffuse2[] = {0.2, 1.0, 1.0};  /* Red diffuse light. */
GLfloat light_position2[] = {-1.0, 1.0, 1.0, 0.0};  /* Infinite light location. */

GLfloat EyeX = 4;
GLfloat EyeY = 2;
GLfloat EyeZ = 5;

GLfloat Xdelta = -1;
GLfloat Ydelta = 0;
GLfloat Zdelta = -1;


void drawFloor(void) {

glColor3f(0.0, 0.5, 0.5);
glPushMatrix();
glScalef(5,5,5);
glBegin(GL_QUADS);
  glNormal3f(0,1,0);
  glVertex3f(2,0,2);
  glVertex3f(-2,0,2);
  glVertex3f(-2,0,-2);
  glVertex3f(2,0,-2);
glEnd();
glPopMatrix();

}


void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(EyeX, EyeY, EyeZ,  
    EyeX + Xdelta, 2.0, EyeZ + Zdelta,      /* center is at (0,0,0) */
    0.0, 1.0, 0.);      /* up is in positive Y direction */

  glPushMatrix();
  glTranslatef(0,1.0,0);
  glutSolidCube(2.0);
  glPopMatrix();
  drawFloor();
  glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
         
      case 'e': EyeX += Xdelta; EyeZ += Zdelta;  break;
      
      case 'd': EyeX -= Xdelta; EyeZ -= Zdelta;  break;
      
      case 's': EyeX -= Xdelta;  break;
      
      case 'f': EyeX += Xdelta;  break;
      
      
   }
   glutPostRedisplay();
}


void
init(void)
{

  /* Enable a single OpenGL light. */
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse1);
  glLightfv(GL_LIGHT0, GL_POSITION, light_position1);
  glEnable(GL_LIGHT0);
   /* Enable a second OpenGL light. */
  glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse2);
  glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
  glEnable(GL_LIGHT1);
  glEnable(GL_LIGHTING);

  /* Use depth buffering for hidden surface elimination. */
  glEnable(GL_DEPTH_TEST);

  /* Setup the _view of the cube. */
  glMatrixMode(GL_PROJECTION);
  gluPerspective( /* field of view in degree */ 40.0,
    /* aspect ratio */ 1.0,
    /* Z near */ 1.0, /* Z far */ 10.0);
  glMatrixMode(GL_MODELVIEW);
  gluLookAt(EyeX, EyeY, EyeZ,  /* eye is at (4,2,5) */
    0.0, 0.0, 0.0,      /* center is at (0,0,0) */
    0.0, 1.0, 0.);      /* up is in positive Y direction */


}

int
main(int argc, char **argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutCreateWindow("navigate");
  glutDisplayFunc(display);
  glutKeyboardFunc(keyboard);
  init();
  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}
