1:/********************************************************************/
   7:/*                                                                  */
   8:/* DESCRIPCION DE EVENTOS:                                          */
   9:/*   Movimiento: tecla w -> cambia a modo walk                      */
  10:/*               tecla e -> cambia a modo examine                   */
  11:/*               tecla f -> cambia a modo fly                       */
  12:/*               teclas de cursor -> para desplazamientos           */
  13:/*   Luces:      tecla 0 -> ninguna luz                             */
  14:/*               tecla 1 -> una luz                                 */
  15:/*               tecla 2 -> dos luces                               */
  16:/*               tecla 3 -> tres luces                              */
  17:/*   Niebla:     tecla n -> habilita la niebla                      */
  18:/*               tecla m -> deshabilita la niebla                   */
  19:/*                                                                  */
  20:/* DESCRIPCION DE LAS CARACTERISTICAS MAS IMPORTANTES DEL PROYECTO  */
  21:/*  El proyecto actual es un proyecto de inform·tica gr·fica        */
  22:/*  desarrollado en OpenGL. Se trata de la representaciÛn de un     */
  23:/*  parque con ·rboles, farolas, bancos, flores (opcionales) y un   */
  24:/*  templete. Todo esto modelado en 3D utilizando las tÈcnicas      */
  25:/*  descritas en la asignatura: modelado geomÈtrico,                */
  26:/*  transformaciones geomÈtricas, proyecciones, visibilidad,        */
  27:/*  iluminaciÛn y texturas. Con todo esto se da una visiÛn inicial  */
  28:/*  a los conceptos b·sicos de inform·tica gr·fica.                 */
  29:/*                                                                  */
  30:/********************************************************************/
  31:
  32:#include <stdlib.h>
  33:#include <GL/glut.h>
  34:#include <stdio.h>
  35:#include <math.h>
  36:
  37:#include "revolucion.h"
  38:
  39://-----------------------------------------------------------------------------
  40:// función para inicializar botones del ratón----------------------------------
  41:void botonRatonPulsado(int boton, int estado, int x, int y) {
  42:  if(boton == GLUT_LEFT_BUTTON) {
  43:    if(estado == GLUT_DOWN) {
  44:      botonIzquierdoPulsado = BOTON_PULSADO;
  45:      pInicio = pFin = actualizaPunto3D(x-(w/2), (h/2)-y, 0.0f);
  46:    }
  47:    else if(estado == GLUT_UP) {
  48:      botonIzquierdoPulsado = BOTON_NO_PULSADO;
  49:      asigna(matrizActual, producto);
  50:    }
  51:  }
  52:  else if(boton == GLUT_RIGHT_BUTTON) {
  53:    if(estado == GLUT_DOWN) {
  54:      botonDerechoPulsado = BOTON_PULSADO;
  55:      pInicio = actualizaPunto3D(x, y, 0.0f);
  56:    }
  57:    else if(estado == GLUT_UP) {
  58:      botonDerechoPulsado = BOTON_NO_PULSADO;
  59:      asigna(matrizActual, producto);
  60:    }
  61:  }
  62:  else if(boton == GLUT_MIDDLE_BUTTON) {
  63:    if(estado == GLUT_DOWN) {
  64:      botonMedioPulsado = BOTON_PULSADO;
  65:      pInicio = actualizaPunto3D(x, y, 0.0f);
  66:    }
  67:    else if(estado == GLUT_UP) {
  68:      botonMedioPulsado = BOTON_NO_PULSADO;
  69:      asigna(matrizActual, producto);
  70:    }
  71:  }
  72:}
  73:
  74:// función para controlar dentro o fuera de la ventana
  75:int dentroVentana(int x, int y) {
  76:  int dentro = DENTRO;
  77:
  78:  if(x < 0 || y < 0 || x > w || y > h) dentro = FUERA;
  79:
  80:  return (dentro);
  81:}
  82:
  83://-----------------------------------------------------------------------------
  84:// función para inicializar movimientos del ratón------------------------------
  85:void ratonMovido(int x, int y) {
  86:  if(botonIzquierdoPulsado == BOTON_PULSADO && dentroVentana(x,y)) {
  87:    pFin = actualizaPunto3D(x-(w/2), (h/2)-y, 0.0f);
  88:    if(distintos(pInicio, pFin) == DISTINTOS) {
  89:      calculaMatrizModeloVista(pFin, pInicio, matriz, R2);
  90:      multiplicaMatrices(matriz, matrizActual, producto);
  91:      glutPostRedisplay();
  92:    }
  93:  }
  94:  else if(botonDerechoPulsado == BOTON_PULSADO && dentroVentana(x, y)) {
  95:    pFin = actualizaPunto3D(x, y, 0.0f);
  96:    dx += (float)(pFin.x - pInicio.x)/200.0f;
  97:    dy += (float)(pInicio.y - pFin.y)/200.0f;
  98:    pInicio = pFin;
  99:    glutPostRedisplay();
 100:  }
 101:  else if(botonMedioPulsado == BOTON_PULSADO && dentroVentana(x,y)) {
 102:    pFin = actualizaPunto3D(x, y, 0.0f);
 103:    dz -= (float)(pInicio.y - pFin.y)/200.0f;
 104:    pInicio = pFin;
 105:    glutPostRedisplay();
 106:  }
 107:}
 108:
 109://-----------------------------------------------------------------------------
 110:// función para controlar el uso de teclas-------------------------------------
 111:void Key (unsigned char tecla, int x, int y)
 112:{
 113:        switch (tecla)
 114:        {
 115:                // ninguna luz
 116:                case '0':
 117:                        glDisable(GL_LIGHT0);
 118:                        glDisable(GL_LIGHT1);
 119:                        glDisable(GL_LIGHT2);
 120:                        glDisable(GL_LIGHT3);
 121:                        glutPostRedisplay ();
 122:                        break;
 123:                // una luz
 124:                case '1':
 125:                        luz0();
 126:                        luz1();
 127:                        glDisable(GL_LIGHT2);
 128:                        glDisable(GL_LIGHT3);
 129:                        glutPostRedisplay ();
 130:                        break;
 131:                //dos luces
 132:                case '2':
 133:                        luz0();
 134:                        luz1();
 135:                        luz2();
 136:                        glDisable(GL_LIGHT3);
 137:                        glutPostRedisplay ();
 138:                        break;
 139:                // tres luces
 140:                case '3':
 141:                        luz0();
 142:                        luz1();
 143:                        luz2();
 144:                        luz3();
 145:                        glutPostRedisplay ();
 146:                        break;
 147:                // habilita la niebla
 148:                case 'n':
 149:                        niebla();
 150:                        glutPostRedisplay ();
 151:                        break;
 152:                // deshabilita la niebla
 153:                case 'm':
 154:                        glDisable (GL_FOG);
 155:                        glutPostRedisplay ();
 156:                        break;
 157:                case 27 :
 158:                        exit (0);
 159:                        break;
 160:
 161:                // modo walk
 162:                case 'w' :
 163:                        modo = WALK;
 164:                        printf ("Modo = WALK      \r");
 165:                        break;
 166:
 167:                // modo examinar
 168:                case 'e' :
 169:                        modo = EXAMINAR;
 170:                        printf ("Modo = EXAMINAR    \r");
 171:                        break;
 172:
 173:                // modo fly
 174:                case 'f' :
 175:                        modo = FLY;
 176:                        printf ("Modo = FLY      \r");
 177:                        break;
 178:
 179:        }
 180:}
 181:
 182:// función para controlar el teclado ampliado
 183:void TecladoAmpliado (int tecla, int x, int y)
 184:{
 185:        switch (tecla)
 186:        {
 187:                case GLUT_KEY_PAGE_UP :
 188:                        if (modo == FLY)
 189:                        {
 190:                                beta = beta + 1.50;
 191:                                if (beta > 360.0) beta = beta - 360.0;
 192:                                iy = oy + PASO * sin (grad2rad (beta));
 193:                        }
 194:                        break;
 195:                case GLUT_KEY_UP : /* Pulsacion cursor arriba del teclado ampliado */
 196:                        if (modo == WALK || modo == FLY)
 197:                        {
 198:                                ox = ix;
 199:                                oz = iz;
 200:                                ix = ox + PASO * sin(grad2rad(alfa));
 201:                                iz = oz - PASO * cos(grad2rad(alfa));
 202:                                if (modo == FLY)
 203:                                {
 204:                                        oy = iy;
 205:                                        iy = iy + PASO * sin (grad2rad (beta));
 206:                                }
 207:                        }
 208:                        else if (modo == EXAMINAR)
 209:                        {
 210:                                beta = beta + 1.50;
 211:                                if (beta > 360.0) beta = beta - 360.0;
 212:                                iy = oy + PASO * sin (grad2rad (beta));
 213:                        }
 214:                        break;
 215:
 216:                case GLUT_KEY_PAGE_DOWN :
 217:                        if (modo == FLY)
 218:                        {
 219:                                beta = beta - 1.50;
 220:                                if (beta > 360.0) beta = beta - 360.0;
 221:                                iy = oy + PASO * sin (grad2rad (beta));
 222:                        }
 223:                        break;
 224:                case GLUT_KEY_DOWN : /* Pulsacion cursor abajo del teclado ampliado */
 225:                        if (modo == WALK || modo == FLY)
 226:                        {
 227:                                ox = ox - (ix-ox);
 228:                                oz = oz - (iz-oz);
 229:                                ix = ox + PASO * sin(grad2rad(alfa));
 230:                                iz = oz - PASO * cos(grad2rad(alfa));
 231:                                if (modo == FLY)
 232:                                {
 233:                                        iy = oy;
 234:                                        oy = oy - PASO * sin (grad2rad (beta));
 235:                                }
 236:                        }
 237:                        else if (modo == EXAMINAR)
 238:                        {
 239:                                beta = beta - 1.50;
 240:                                if (beta < 0.0) beta = beta + 360.0;
 241:                                iy = oy + PASO * sin (grad2rad (beta));
 242:                        }
 243:                        break;
 244:
 245:                case GLUT_KEY_RIGHT : /* Pulsacion cursor derecha del teclado ampliado */
 246:                        alfa = alfa + 15.0;
 247:                        if (alfa > 360.0) alfa = alfa - 360.0;
 248:                        ix = ox + PASO * sin(grad2rad(alfa));
 249:                        iz = oz - PASO * cos(grad2rad(alfa));
 250:                        break;
 251:
 252:                case GLUT_KEY_LEFT : /* Pulsacion cursor izquierda del teclado ampliado */
 253:                        alfa = alfa - 15.0;
 254:                        if (alfa < 0.0) alfa = alfa + 360.0;
 255:                        ix = ox + PASO * sin(grad2rad(alfa));
 256:                        iz = oz - PASO * cos(grad2rad(alfa));
 257:                        break;
 258:
 259:        }
 260:        glutPostRedisplay ();
 261:}
 262:
 263:/*--------------------------------------------------------------------------
 264:   Borra la ventana y establece el color de dibujo y el ancho de las lineas
 265:  --------------------------------------------------------------------------*/
 266:void display(void)
 267:{
 268:        glClearColor (1.0,1.0,1.0, 1.0);
 269:        
 270:        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 271:
 272:        glLoadIdentity ();
 273: 
 274:        //posición inicial
 275:        gluLookAt (ox, oy, oz, ix, iy, iz, 0, 1, 0);
 276:
 277:        // luz inicial
 278:        luz0();
 279:
 280:        glPushMatrix();
 281:        glTranslatef(dx, dy, dz);
 282:        glMultMatrixf(producto);
 283:
 284:        blanco();
 285:        
 286:        glCallList(escenario);
 287:        
 288:        glPopMatrix();
 289:        glutSwapBuffers ();
 290:}
 291:
 292:
 293:/*--------------------------------------------------------------------------
 294:   Asocia las funciones a los eventos del teclado
 295:  --------------------------------------------------------------------------*/
 296:void  inicializaTeclado (void) {
 297:  glutKeyboardFunc (Key);
 298:  glutSpecialFunc (TecladoAmpliado);
 299:}
 300:
 301:
 302:/*--------------------------------------------------------------------------
 303:   Especifica las caracteristicas de la vista...
 304:  --------------------------------------------------------------------------*/
 305:void  inicializaVista (void)
 306:{
 307:    /* Definicion del viewport */
 308:        glViewport(0, 0, w, h);  
 309:
 310:        glMatrixMode(GL_PROJECTION);
 311:        glLoadIdentity();
 312:        
 313:        gluPerspective (60.0, (GLdouble)w/(GLdouble)h, 1.0, 400.0);
 314:
 315:        glMatrixMode(GL_MODELVIEW);
 316:        glLoadIdentity();
 317:        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
 318:        
 319:        // eliminación de caras traseras
 320:        glFrontFace (GL_CCW);   // dirección contraria a las agujas del reloj
 321:        glCullFace(GL_BACK);    // elimina la cara back
 322:        
 323:        glEnable (GL_NORMALIZE);
 324:        glShadeModel (GL_SMOOTH);
 325:        
 326:        glDepthFunc (GL_LEQUAL);
 327:
 328:        //Activar el test de profundidad:
 329:        glEnable(GL_DEPTH_TEST);
 330:}
 331:
 332:
 333:/*--------------------------------------------------------------------------
 334:   Posible cambio del tamaño de la ventana
 335:  --------------------------------------------------------------------------*/
 336:void reshape (int width, int height) {
 337:
 338:        //define el tamaño de la ventana a través de la que vemos
 339:        glViewport (0, 0, width, height);
 340:        w = width;
 341:        h = height;
 342:        if(w > h) Z = w;
 343:        else Z = h;
 344:        R2 = (w*w+h*h+Z*Z)/4;
 345:        inicializaVista ();
 346:}
 347:
 348:
 349:/*--------------------------------------------------------------------------
 350:   Crea la ventana
 351:  --------------------------------------------------------------------------*/
 352:void  inicializaVentana (int argc, char **argv)
 353:{
 354:  glutInit(&argc, argv);
 355:
 356:  //Indicar que tu aplicación OpenGL va a utilizar el z-buffer
 357:  glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
 358:
 359:  glutInitWindowSize (700, 700);
 360:  glutInitWindowPosition (200, 30);
 361:  glutCreateWindow ("Parque, by David Barreda");
 362:  glutDisplayFunc (display);
 363:  glutReshapeFunc (reshape);
 364:}
 365:
 366:// función de inicialización del ratón
 367:void iniciaRaton(void) {
 368:  glutMouseFunc(botonRatonPulsado); // Eventos de pulsacion de botones de raton
 369:  glutMotionFunc(ratonMovido);
 370:}
 371:
 372:
 373:
 374:/*--------------------------------------------------------------------------
 375:   Distribuye el juego
 376:  --------------------------------------------------------------------------*/
 377:void pintaModelo (int argc, char **argv)
 378:{
 379:  inicializaVentana (argc, argv);
 380:  inicializaTeclado ();
 381:  iniciaRaton ();
 382:  inicializaVista ();
 383:
 384:  iniciaIluminacion();
 385:
 386:  iniciaTexturas();
 387:
 388:  iniciaDisplayLists();
 389: 
 390:  printf("Parque, by David Barreda\n");
 391:  printf("\n");
 392:  printf("Modos: WALK (w), EXAMINE (e), FLY  (f)\n");
 393:  printf("Desplazamientos: cursor\n");
 394:  printf("Luces: 0, 1, 2, 3\n");
 395:  printf("Niebla: activa(n), desactiva(m)\n");
 396:  printf("\n");
 397:  printf("Modo actual= WALK\r");
 398:
 399:  glutMainLoop();
 400:}
 401:
 402:
 403:int main (int argc, char** argv)
 404:{
 405:        pintaModelo(argc, argv);
 406:        return (1);
 407:}