Your SlideShare is downloading. ×
  • Like
Programación con Pygame IX
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Programación con Pygame IX

  • 1,848 views
Published

Los archivos pueden encontrarse en …

Los archivos pueden encontrarse en
http://sites.google.com/site/laislalibre/informatica/python/pygame

Published in Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,848
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
219
Comments
0
Likes
3

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO Cubo3D: Pyggel y OpenGL (Basado en los tutoriales NeHe, http://nehe.gamedev.net ) Introducción Cubo3D no es un juego, es un pequeño programa escrito para mostrar cómo se puede trabajar en Python con las 3 dimensiones. El guión está basado en uno de los famosos tutoriales NeHe, algunos de los cuales fueron convertidos a Python y PyGame por Paul Furber http://www.pygame.org/gamelets/games/nehe1-10.zip Pero ésta no va a ser nuestra aproximación (aunque incluimos al final el código correspondiente por completitud). Estos tutoriales utilizan una librería 3D genérica muy potente llamada OpenGL http://www.opengl.org sin lugar a dudas, la más extendida y con la que se programan multitud de videojuegos profesionales. Su implementación en Python se conoce como PyOpenGL PÁGINA 1 DE 13 CC: FERNANDO SALAMERO
  • 2. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO http://pyopengl.sourceforge.net En cualquier caso, al ser una librería avanzada, su manejo es muy complejo (sólo tienes que mirar el código al que nos hemos referido antes). Existe una librería conocida como Pyggel http://code.google.com/p/pyggel/ que hace de intermediario de PyOpenGL; incorpora clases, constantes y funciones que facilitan mucho el aprendizaje y uso de las tres dimensiones en nuestros programas, encargándose ella de gestionar de forma transparente las rutinas correspondientes de OpenGL. Además, la librería Pyggel se encarga de inicializar a su vez a PyGame. ¡Dos en uno! Si esto fuera poco, no necesitamos instalar nada más (bueno, en realidad sí que hay que tener instalado en el sistema a PyOpenGL y OpenGL); basta con que a nuestro proyecto le incorporemos la carpeta de la librería y a funcionar. En resumen, con este documento incluimos dos programas distintos: 1. Cubo3D_Pyggel.py es nuestro tutorial y el que se va a describir en las próximas líneas. Utiliza el módulo Pyggel. 2. Cubo3D_PyOpenGL.py es el tutorial original de Paul Furber, conversión a Python del tutorial NeHe correspondiente. Trabaja directamente con PyOpenGL. Vamos allá. Importación e Inicialización Después de la típica línea de declaración de codificación y del nombre del programa, nos encontramos con la importación del módulo pyggel. Observa la curiosa forma. Por una parte se importa tal cual import pyggel, sys y, por otra parte, se importa de nuevo en la forma from pyggel import * El resultado es que podemos llamar a cualquier objeto refiriéndonos a él directamente o con el prefijo pyggel. Es una cuestión de comodidad, aunque en general no es muy recomendable. En pyggel es importante que lo hagamos así pues, como ya hemos comentado previamente, esté módulo carga e inicializa automáticamente a su vez a PyGame y, de esta manera, podemos también acceder a sus objetos directamente. Lo siguiente es inicializar el entorno (recuerda que al inicializar Pyggel se inicializa también PyGame). Fíjate que no escribimos simplemente init(). Pyggel admite en dicha función varios parámetros que nos permiten ajustar las características de la ventana de visualización. De paso se usa una característica de Python muy útil; no hace falta recordar el orden en el que hay que escribir los parámetros, podemos referirnos a ellos por su nombre. Así pyggel.init(screen_size=(800,600)) tiene el efecto de invocar a la función init() del módulo pyggel dando el valor (800,600) al argumento llamado screen_size en su definición. Como adivinarás, eso hace que la ventana en la que veremos nuestra animación 3D tenga un tamaño de 800x600 pixeles. PÁGINA 2 DE 13 CC: FERNANDO SALAMERO
  • 3. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO Composición de la ESCENA Hay una diferencia fundamental entre trabajar con dos dimensiones (como hasta ahora, con el estándar de PyGame) y trabajar con tres. Cuando dibujamos en 2D dibujamos exactamente lo que queremos, ya que la superficie sobre la que se dibuja (la pantalla del ordenador) también es bidimensional. Sin embargo, cuando queremos dibujar en 3D, debemos hacer proyección de los objetos, realizar una perspectiva. Y en tal caso, influyen muchos más factores; para empezar el lugar desde donde se mira (no es lo mismo mirar un cubo desde delante que desde un lado, o desde muy lejos). Dibujar en 3D en hacer un salto a una animación más realista en la que puedes tener en cuenta detalles como iluminación, atmósfera... Debes ponerte en el papel de un director de cine o de un fotógrafo: 1. Para empezar, todo lo que quieres incluir forma lo que se denomina una escena. 2. Tienes que determinar desde dónde vas a mirar, es decir, la posición de la cámara. 3. Y necesitas luces que iluminen los objetos, por supuesto. Todo ello vas a tener que implementarlo. Veámoslo paso a paso. La primera línea de código que encontramos es escena = pyggel.scene.Scene() es precisamente la creación de la escena. Observa que es un objeto de tipo Scene (definido en el módulo scene, es decir, en el archivo scene.py de la carpeta pyggel). De la misma manera que un Grupo de Pygame contenía una serie de Sprites, un objeto de tipo Scene contiene todos los objetos que forman la escena y, por lo tanto, a medida que los vayamos creando deberemos añadírselos. En nuestro mundo tridimensional sólo vamos a tener un cubo, pero para que no sea aburrido vamos a añadirle una textura. Las texturas son imágenes que se colocan en las superficies de los objetos y simulan el tipo de material o la decoración. Si te has fijado en la captura de pantalla al inicio de este documento, la que vamos a emplear es una imagen de tipo vidriera (glass.bmp); pero si quisiéramos que nuestro cubo fuera de madera, por ejemplo, podríamos tomar una imagen con listones o similar. Las texturas son objetos de tipo Texture y se crean de la siguiente forma textura = pyggel.data.Texture("glass.bmp") Una vez cargada en memoria, usarla para crear un cubo es también sencillo: cubo = pyggel.geometry.Cube(1, pos=(0, 0, 0), texture=textura) En la línea anterior hemos creado un objeto de tipo Cube (como puedes adivinar, los diferentes tipos de objetos tridimensionales nativos están definidos en el archivo geometry.py de pyggel; analiza su código si tienes curiosidad). El parámetro pos indica claramente en qué posición pondremos al cubo; se necesitan tres coordenadas pues estamos en un mundo tridimensional (ya se encargará Pyggel, o más correctamente OpenGL, de proyectar la escena en la pantalla). En nuestro mundo tridimensional, el cubo está situado en el origen de coordenadas. Y el valor 1 del primer argumento indica su tamaño; nuestro cubo tiene una arista de 1 unidad. PÁGINA 3 DE 13 CC: FERNANDO SALAMERO
  • 4. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO Con los objetos tridimensionales, no sólo podemos situarlos en algún lugar, también podemos orientarlos. ¿Qué tal se te da la geometría...? Para orientar un objeto podemos girarlo adecuadamente, pero este giro podemos hacerlo con respecto a cualquiera de los tres ejes X, Y y Z. Así que, en general, un giro puede ser la composición de tres giros, uno en torno a cada eje coordenado. El que encontramos en el código, cubo.rotation = (0,45,10) el cubo se rota 45 grados con respecto al eje Y y 10 grados con respecto al eje Z. Finalmente, hemos de incluir el cubo creado en la escena para que luego se visualice. Ello se consigue con la línea escena.add_3d(cubo) Nuestra escena ya tiene un objeto tridimensional. Añadiendo LUCES Como hemos indicado, para poder la escena correctamente necesitamos iluminarla. Como en la realidad, hay muchos tipos de luces; direccionales (como un foco), de ambiente (repartida por todas partes de forma homogénea), puntuales (como una bombilla)... La forma de crear luces desde una librería de programación, por lo tanto, ha de ser muy flexible. Veamos cómo lo hemos implementado: luz = pyggel.light.Light((0,0,2), (0.5,0.5,0.5,1), (1,1,1,1), (50,50,50,10), (0,0,0), True) Bien. Como viene siendo habitual, el sistema se basa en la creación de un objeto, en este caso de tipo Light (definido en el módulo de pyggel light). Los diferentes parámetros indican las propiedades que va a tener la iluminación: 1. (0,0,2) Se corresponde con la posición, en el espacio, de la fuente que emite la luz. 2. (0.5,0.5,0.5,1) Es el color de la luz ambiente; una luz que llena todo el espacio por igual (y que por lo tanto no produciría sombras). Está en formato RGBA, es decir, valores entre 0 y 1 que indicam la cantidad de rojo, verde, azul y canal alfa (la opacidad; 1 indica que es sólida; 0 completamente transparente). 3. (1,1,1,1) Color de la luz difusa; tipo de luz suave que viene desde una dirección dada y que produciría sombras (algo así como un Sol velado). También en formato RGBA 4. (50,50,50,10) Luz especular; similar a la anterior pero más brillante, como un Sol intenso (que puede producir brillos sobre las superficies que ilumina directamente). PÁGINA 4 DE 13 CC: FERNANDO SALAMERO
  • 5. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO 5. (0,0,0) Dirección de la luz en el caso de que ésta sea direccional; con ello controlamos en qué dirección aparecerán las combras. 6. True Indica si la luz es direccional en cuyo caso se indica True, o la emite un punto de luz concreto en todas direcciones, indicado con False. Juega con las diferentes opciones y prueba todo lo que quieras; sólo así podrás comprenderlo mejor. Una vez creada la luz, hemos de añadirla a la escena para que el motor 3D de pyggel pueda luego generarla correctamente: escena.add_light(luz) ¡Conseguido! Posicionando la CÁMARA Ahora hay que decidir desde dónde hay que mirarlo, es decir, hay que situar la cámara. Con Pyggel es muy sencillo... camara = pyggel.camera.LookAtCamera((0,0,0), distance=3) Fíjate en el código. Para crear una cámara se crea un objeto de la clase LookAtCamera, definida en el módulo camera (si miras su código verás que hay otras formas de crear cámaras). Los parámetros que hemos incluido son muy intuitivos; el primero es una tupla que indica en qué dirección miramos (en este caso, miramos hacia el punto (0,0,0), el lugar en el que hemos puesto el cubo) y el parámetro distance indica desde qué distancia se hace (valores negativos indicarían algo así como ‘desde el otro lado’; experimenta, como siempre, para ver la diferencia). Bucle Principal Justo antes de entrar en el bucle de la animación nos encontramos con el habitual reloj = pygame.time.Clock() que controlará posteriormente la velocidad de los fotogramas con reloj.tick(60). La gestión de eventos puede hacerse de la forma habitual en PyGame, pero ya que estamos usando en primer plano la librería Pyggel, podemos hacerlo con ella: eventos = pyggel.event.Handler() Con la línea anterior hemos creado un objeto de tipo Handler y lo hemos almacenado en la variable eventos. Un objeto de este tipo centraliza la detección y uso de los eventos que se producen en el programa. En seguida veremos cómo. Una vez dentro del bucle, la línea pyggel.view.set_title("FPS: %s"%int(reloj.get_fps())) PÁGINA 5 DE 13 CC: FERNANDO SALAMERO
  • 6. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO tiene una misión muy interesante; mostrar en la barra de título de la ventana la velocidad real conseguida en fotogramas por segundo; es un buen método para, en tiempo de desarrollo, comprobar si conseguimos la velocidad que queremos (si el ordenador no es lo suficientemente rápido, o le pedimos demasiadas tareas a la vez, es posible que no alcance la que hemos indicado, en nuestro caso los 60 fps). ¿Cómo lo hace? La función pyggel.view.set_title() toma como argumento una cadena de texto y la coloca como título de la ventana. Recuerda, además, que en “FPS: %s” el %s indica que vamos a pasarle un entero a la cadena de texto en cuestión. Y ese entero lo conseguimos usando el método get_fps() del objeto reloj, método que nos devuelve el valor real de la velocidad de la animación (con decimales, de ahí el int para convertirlo). Lo siguiente es actualiza la lista de eventos que se puedan haber producido con eventos.update() y, por consiguiente, hemos de mirar cuáles tenemos y actuar en consecuencia. La forma de hacerlo es muy similar a la de PyGame, pero con sus características propias. Para empezar, los eventos que se producen con el teclado se corresponden con el objeto keyboard y los del ratón con el mouse. En este programa sólo vamos a responder a las pulsaciones de ciertas teclas, así que estamos en el primer caso. Para saber si se acaba de pulsar una tecla, hay que mirar si está en keyboard.hit mientras que la lista de teclas que están todavía pulsadas se encuentra en keyboard.active. De esta forma, para salir del programa si se cierra la ventana o si se pulsa la tecla escape escribimos if eventos.quit or K_ESCAPE in eventos.keyboard.hit: pyggel.quit() sys.exit() Si se pulsan ciertas teclas, lo que haremos es desplazar la cámara (y por lo tanto veremos la escena desde otras posiciones o perspectivas). Así, por ejemplo, if K_LEFT in eventos.keyboard.active: camara.roty -= .5 mira si se ha pulsado la tecla de desplazamiento izquierda del cursor y, en tal caso, resta 0.5 grados al ángulo de rotación sobre el eje Y de la cámara. Ejecuta el programa para ver el efecto que esto tiene. Observa que no es lo mismo girar la cámara que girar un objeto (según sea lo que quieres conseguir o cómo quieres que el programa responda a las acciones del usuario elegirás una u otra cosa); girar la cámara hace moverse al observador que contempla la escena; girar los objetos hace que la propia escena cambie. Los demás giros sobre los diferentes ejes se implementan de forma similar. Como sólo tenemos las teclas de desplazamiento izquierda, derecha, arriba y abajo, para hacer el giro sobre el eje Z hemos usado, como puedes ver, las teclas 1 y 2. Por otra parte, para acercarnos o alejarnos de la escena, usando las teclas z y x, simplemente hemos de modificar el valor de camara.distance. Cuando giramos la cámara, lo que hacemos es orbitar en torno al punto que estamos mirando, como hace la Luna con la Tierra. Desplazarla es algo distinto, pues es simplemente cambiar su posición (lo que hace que entonces no mire necesariamente en la dirección de antes). En el código, por poner un ejemplo, usamos las teclas a, d, s y w para desplazarla en los ejes X y Z. De nuevo, ejecuta el script y verás lo que sucede. PÁGINA 6 DE 13 CC: FERNANDO SALAMERO
  • 7. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO Una vez que hemos atendido a todos los eventos que queríamos usar en nuestro programa, lo único que nos queda es realizar el dibujado en pantalla para que se muestre en toda su gloria la imagen tridimensional. Análogamente a lo que ocurría en PyGame, en cada fotograma tienes que vigilar que sean borradas las imágenes que han cambiado y redibujar las que ahora han de visualizarse. Por lo tanto, lo primero es borrar toda la pantalla pyggel.view.clear_screen() y lo siguiente es generar la imagen tridimensional (lo que se conoce como renderizar) escena.render(camara) La línea anterior nos renderiza la escena tal como se vería por la camara. Para finalizar, como es habitual, debemos volcar la escena generada. Ello nos lleva a la última línea del programa: pyggel.view.refresh_screen() ¡Perfecto! Nuestro cubo ha quedado realmente aparente. Y esto es sólo el comienzo. Con tiempo e imaginación, puedes crear cualquier Mundo que te propongas... # -*- coding: utf-8 -*- # Ejemplo de escena en 3D import pyggel, sys from pyggel import * pyggel.init(screen_size=(800,600)) escena = pyggel.scene.Scene() textura = pyggel.data.Texture("glass.bmp") cubo = pyggel.geometry.Cube(1, pos=(0, 0, 0), texture=textura) cubo.rotation = (0,45,10) escena.add_3d(cubo) luz = pyggel.light.Light((0,0,2), (0.5,0.5,0.5,1), (1,1,1,1), (50,50,50,10), (0,0,0), True) escena.add_light(luz) PÁGINA 7 DE 13 CC: FERNANDO SALAMERO
  • 8. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO camara = pyggel.camera.LookAtCamera((0,0,0), distance=3) reloj = pygame.time.Clock() eventos = pyggel.event.Handler() while 1: reloj.tick(60) pyggel.view.set_title("FPS: %s"%int(reloj.get_fps())) eventos.update() if eventos.quit or K_ESCAPE in eventos.keyboard.hit: pyggel.quit() sys.exit() if K_LEFT in eventos.keyboard.active: camara.roty -= .5 if K_RIGHT in eventos.keyboard.active: camara.roty += .5 if K_UP in eventos.keyboard.active: camara.rotx -= .5 if K_DOWN in eventos.keyboard.active: camara.rotx += .5 if K_1 in eventos.keyboard.active: camara.rotz -= .5 if K_2 in eventos.keyboard.active: camara.rotz += .5 if K_z in eventos.keyboard.active: camara.distance -= .05 if K_x in eventos.keyboard.active: camara.distance += .05 if K_a in eventos.keyboard.active: camara.posx -= .1 if K_d in eventos.keyboard.active: camara.posx += .1 if K_s in eventos.keyboard.active: camara.posz -= .1 if K_w in eventos.keyboard.active: camara.posz += .1 pyggel.view.clear_screen() escena.render(camara) pyggel.view.refresh_screen() PÁGINA 8 DE 13 CC: FERNANDO SALAMERO
  • 9. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO Como hemos comentado, incluimos también el código de Paul Furber que usa directamente las librerías OpenGL a través de PyOpenGL. Como verás, el programa es mucho más complejo aunque más potente. Si lo ejecutas verás que, por ejemplo, con la tecla l se activa o desactiva la iluminación, mientras que con la tecla b se activan o desactivan efectos de transparencia... #!/usr/bin/env python # pygame + PyOpenGL version of Nehe's OpenGL lesson08 # Paul Furber 2001 - m@verick.co.za import os from OpenGL.GL import * from OpenGL.GLU import * import pygame, pygame.image from pygame.locals import * xrot = yrot = 0.0 xspeed = yspeed = 0.0 z = -5.0 textures = [] filter = 0 light = 0 blend = 0 LightAmbient = ( (0.5, 0.5, 0.5, 1.0) ); LightDiffuse = ( (1.0, 1.0, 1.0, 1.0) ); LightPosition = ( (0.0, 0.0, 2.0, 1.0) ); def resize((width, height)): if height==0: height=1.0 glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, 1.0*width/height, 0.1, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() def init(): glEnable(GL_TEXTURE_2D) load_textures() glShadeModel(GL_SMOOTH) glClearColor(0.0, 0.0, 0.0, 0.0) glClearDepth(1.0) glEnable(GL_DEPTH_TEST) PÁGINA 9 DE 13 CC: FERNANDO SALAMERO
  • 10. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glLightfv( GL_LIGHT1, GL_AMBIENT, LightAmbient ) glLightfv( GL_LIGHT1, GL_DIFFUSE, LightDiffuse ) glLightfv( GL_LIGHT1, GL_POSITION, LightPosition ) glEnable( GL_LIGHT1 ) glColor4f( 1.0, 1.0, 1.0, 0.5) glBlendFunc( GL_SRC_ALPHA, GL_ONE ) def load_textures(): global LightAmbient, LightDiffuse, LightPosition, textures #texturefile = os.path.join('data','glass.bmp') textureSurface = pygame.image.load('glass.bmp') textureData = pygame.image.tostring(textureSurface, "RGBX", 1) textures = glGenTextures(3) glBindTexture(GL_TEXTURE_2D, textures[0]) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData ) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glBindTexture(GL_TEXTURE_2D, textures[1]) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData ) glBindTexture( GL_TEXTURE_2D, textures[2]) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, textureSurface.get_width(), textureSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textureData); def draw(): global xrot, yrot, xspeed, yspeed, z, filter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0.0, 0.0, z) PÁGINA 10 DE 13 CC: FERNANDO SALAMERO
  • 11. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO glRotatef(xrot, 1.0, 0.0, 0.0) glRotatef(yrot, 0.0, 1.0, 0.0) glBindTexture(GL_TEXTURE_2D, textures[filter]) glBegin(GL_QUADS) glNormal3f(0.0, 0.0, 1.0) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) glNormal3f(0.0, 0.0, -1.0) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) glNormal3f(0.0, 1.0, 0.0) glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, 1.0, 1.0) glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, 1.0, 1.0) glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) glNormal3f(0.0, -1.0, 0.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, -1.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) glNormal3f(1.0, 0.0, 0.0) glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) glNormal3f(-1.0, 0.0, 0.0) glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) glEnd(); xrot += xspeed yrot += yspeed PÁGINA 11 DE 13 CC: FERNANDO SALAMERO
  • 12. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO def handle_keys(key): global filter, light, z, xspeed, yspeed, blend if key == K_ESCAPE: return 0 if key == K_f: filter = filter + 1 if filter == 3: filter = 0 elif key == K_l: light = not light if not light: glDisable(GL_LIGHTING) else: glEnable(GL_LIGHTING) elif key == K_b: blend = not blend if blend: glEnable(GL_BLEND) glDisable(GL_DEPTH_TEST) else: glEnable(GL_DEPTH_TEST) glDisable(GL_BLEND) elif key == K_PAGEUP: z -= 0.05 elif key == K_PAGEDOWN: z += 0.05 elif key == K_UP: xspeed -= 0.01 elif key == K_DOWN: xspeed += 0.01 elif key == K_LEFT: yspeed -= 0.01 elif key == K_RIGHT: yspeed += 0.01 return 1 def main(): video_flags = OPENGL|DOUBLEBUF pygame.init() surface = pygame.display.set_mode((640,480), video_flags) resize((640,480)) init() frames = 0 PÁGINA 12 DE 13 CC: FERNANDO SALAMERO
  • 13. PROGRAMA: DRIVE CURSO: 1º BACHILLERATO ticks = pygame.time.get_ticks() while 1: event = pygame.event.poll() if event.type == QUIT: break if event.type == KEYDOWN: if handle_keys(event.key) == 0: break draw() pygame.display.flip() frames = frames+1 print "fps: %d" % ((frames*1000)/(pygame.time.get_ticks()-ticks)) if __name__ == '__main__': main() PÁGINA 13 DE 13 CC: FERNANDO SALAMERO