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:}