SlideShare ist ein Scribd-Unternehmen logo
1 von 13
Downloaden Sie, um offline zu lesen
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
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
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
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
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
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
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
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
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
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
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
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
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

Weitere ähnliche Inhalte

Was ist angesagt?

Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Fernando Salamero
 
Introducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGLIntroducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGLkdeespana
 
Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (II)
Programación de Videojuegos con Python y Pilas (II)Programación de Videojuegos con Python y Pilas (II)
Programación de Videojuegos con Python y Pilas (II)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (I)
Programación de Videojuegos con Python y Pilas (I)Programación de Videojuegos con Python y Pilas (I)
Programación de Videojuegos con Python y Pilas (I)Fernando Salamero
 
Taller de introduccion a python con turtle
Taller de  introduccion a python  con  turtleTaller de  introduccion a python  con  turtle
Taller de introduccion a python con turtleAlbert Page
 
Instructivo tortugart
Instructivo tortugartInstructivo tortugart
Instructivo tortugartGladys León
 
Xna game studio presentación 02
Xna game studio   presentación 02Xna game studio   presentación 02
Xna game studio presentación 02Juan Cardona
 
Xna game studio presentación 01
Xna game studio   presentación 01Xna game studio   presentación 01
Xna game studio presentación 01Juan Cardona
 

Was ist angesagt? (20)

Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)Programación de Videojuegos con Python y Pilas (X)
Programación de Videojuegos con Python y Pilas (X)
 
Aventura
AventuraAventura
Aventura
 
Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)Programación de Videojuegos con Python y Pilas (VII)
Programación de Videojuegos con Python y Pilas (VII)
 
Introducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGLIntroducción a las librerías PyGame y PyOpenGL
Introducción a las librerías PyGame y PyOpenGL
 
Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)Programación de Videojuegos con Python y Pilas (VI)
Programación de Videojuegos con Python y Pilas (VI)
 
Intro pygamev2
Intro pygamev2Intro pygamev2
Intro pygamev2
 
Intro PyGame Capitulo 5
Intro PyGame Capitulo 5Intro PyGame Capitulo 5
Intro PyGame Capitulo 5
 
Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)Programación de Videojuegos con Python y Pilas (VIII)
Programación de Videojuegos con Python y Pilas (VIII)
 
Programación de Videojuegos con Python y Pilas (II)
Programación de Videojuegos con Python y Pilas (II)Programación de Videojuegos con Python y Pilas (II)
Programación de Videojuegos con Python y Pilas (II)
 
Intro Pygame Capitulo 2
Intro Pygame Capitulo 2Intro Pygame Capitulo 2
Intro Pygame Capitulo 2
 
Intro PygameCapitulo 3
Intro PygameCapitulo 3Intro PygameCapitulo 3
Intro PygameCapitulo 3
 
Intro PyGame Capitulo 1
Intro PyGame Capitulo 1Intro PyGame Capitulo 1
Intro PyGame Capitulo 1
 
Intro PyGame Capitulo 0
Intro PyGame Capitulo 0Intro PyGame Capitulo 0
Intro PyGame Capitulo 0
 
Capitulo 4
Capitulo 4Capitulo 4
Capitulo 4
 
Programación de Videojuegos con Python y Pilas (I)
Programación de Videojuegos con Python y Pilas (I)Programación de Videojuegos con Python y Pilas (I)
Programación de Videojuegos con Python y Pilas (I)
 
Taller de introduccion a python con turtle
Taller de  introduccion a python  con  turtleTaller de  introduccion a python  con  turtle
Taller de introduccion a python con turtle
 
Instructivo tortugart
Instructivo tortugartInstructivo tortugart
Instructivo tortugart
 
Xna game studio presentación 02
Xna game studio   presentación 02Xna game studio   presentación 02
Xna game studio presentación 02
 
Presentación del 21 de abril de 2012
Presentación del 21 de abril de 2012Presentación del 21 de abril de 2012
Presentación del 21 de abril de 2012
 
Xna game studio presentación 01
Xna game studio   presentación 01Xna game studio   presentación 01
Xna game studio presentación 01
 

Ähnlich wie Programación con Pygame IX

Ähnlich wie Programación con Pygame IX (20)

Manual de practicas segundo parcial
Manual de practicas segundo parcialManual de practicas segundo parcial
Manual de practicas segundo parcial
 
112542874 links-cape
112542874 links-cape112542874 links-cape
112542874 links-cape
 
Tutorial de INKSCAPE: Logo a logo
Tutorial de INKSCAPE: Logo a logoTutorial de INKSCAPE: Logo a logo
Tutorial de INKSCAPE: Logo a logo
 
Manual inkscape
Manual inkscapeManual inkscape
Manual inkscape
 
Tutorial modelado casa
Tutorial  modelado casaTutorial  modelado casa
Tutorial modelado casa
 
Tutorial modelado casa
Tutorial  modelado casaTutorial  modelado casa
Tutorial modelado casa
 
Logo a logo
Logo a logoLogo a logo
Logo a logo
 
Inkscape logo a logo (1) (1)
Inkscape logo a logo (1) (1)Inkscape logo a logo (1) (1)
Inkscape logo a logo (1) (1)
 
Manual Inkscape
Manual InkscapeManual Inkscape
Manual Inkscape
 
logo a logo
logo a logologo a logo
logo a logo
 
Ogre Game Engine
Ogre Game EngineOgre Game Engine
Ogre Game Engine
 
1. tutorial unity3d introducción
1.  tutorial unity3d introducción1.  tutorial unity3d introducción
1. tutorial unity3d introducción
 
1. tutorial unity3d introducción
1.  tutorial unity3d introducción1.  tutorial unity3d introducción
1. tutorial unity3d introducción
 
Vray14520
Vray14520Vray14520
Vray14520
 
Manual de photoshop leidy vivani olvera leon
Manual de photoshop leidy vivani olvera leonManual de photoshop leidy vivani olvera leon
Manual de photoshop leidy vivani olvera leon
 
Trabajo de programacion grafica de torres bautista ines
Trabajo de programacion grafica de torres bautista inesTrabajo de programacion grafica de torres bautista ines
Trabajo de programacion grafica de torres bautista ines
 
Renderizador de cinema 4 d
Renderizador de cinema 4 dRenderizador de cinema 4 d
Renderizador de cinema 4 d
 
Trabajo de programacion grafica
Trabajo de programacion graficaTrabajo de programacion grafica
Trabajo de programacion grafica
 
Libro sketch up-7-capitulo-1
Libro sketch up-7-capitulo-1Libro sketch up-7-capitulo-1
Libro sketch up-7-capitulo-1
 
Proyecto 3 dsm
Proyecto 3 dsmProyecto 3 dsm
Proyecto 3 dsm
 

Mehr von Fernando Salamero

(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no proponeFernando Salamero
 
Ciencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeCiencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeFernando Salamero
 
(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la FísicaFernando Salamero
 
(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la FísicaFernando Salamero
 
Timeline - En busca de la Física
Timeline - En busca de la FísicaTimeline - En busca de la Física
Timeline - En busca de la FísicaFernando Salamero
 
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Fernando Salamero
 
Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Fernando Salamero
 
Programación con Pygame VII
Programación con Pygame VIIProgramación con Pygame VII
Programación con Pygame VIIFernando Salamero
 

Mehr von Fernando Salamero (18)

(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
(Anotaciones) Ciencia (Cuestiones) que la tiza no propone
 
Ciencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no proponeCiencia (Cuestiones) que la tiza no propone
Ciencia (Cuestiones) que la tiza no propone
 
(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física(Sin anotaciones) - En busca de la Física
(Sin anotaciones) - En busca de la Física
 
(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física(Con anotaciones) En busca de la Física
(Con anotaciones) En busca de la Física
 
Timeline - En busca de la Física
Timeline - En busca de la FísicaTimeline - En busca de la Física
Timeline - En busca de la Física
 
Jovenes físicos
Jovenes físicosJovenes físicos
Jovenes físicos
 
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
Taller de Pilas Engine, un motor de juegos en Python - PyConES 2014
 
Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)Programación de Videojuegos con Python y Pilas (V)
Programación de Videojuegos con Python y Pilas (V)
 
Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)Programación de Videojuegos con Python y Pilas (III)
Programación de Videojuegos con Python y Pilas (III)
 
Python básico II
Python básico IIPython básico II
Python básico II
 
Python básico I
Python básico IPython básico I
Python básico I
 
Python (ejercicios)
Python (ejercicios)Python (ejercicios)
Python (ejercicios)
 
Python (práctica 4)
Python (práctica 4)Python (práctica 4)
Python (práctica 4)
 
Python (práctica 3)
Python (práctica 3)Python (práctica 3)
Python (práctica 3)
 
Python (práctica 2)
Python (práctica 2)Python (práctica 2)
Python (práctica 2)
 
Python (práctica 1)
Python (práctica 1)Python (práctica 1)
Python (práctica 1)
 
Iniciación a python
Iniciación a pythonIniciación a python
Iniciación a python
 
Programación con Pygame VII
Programación con Pygame VIIProgramación con Pygame VII
Programación con Pygame VII
 

Kürzlich hochgeladen

Neurociencias para Educadores NE24 Ccesa007.pdf
Neurociencias para Educadores  NE24  Ccesa007.pdfNeurociencias para Educadores  NE24  Ccesa007.pdf
Neurociencias para Educadores NE24 Ccesa007.pdfDemetrio Ccesa Rayme
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoFundación YOD YOD
 
Dinámica florecillas a María en el mes d
Dinámica florecillas a María en el mes dDinámica florecillas a María en el mes d
Dinámica florecillas a María en el mes dstEphaniiie
 
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.Alejandrino Halire Ccahuana
 
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLA
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLAACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLA
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLAJAVIER SOLIS NOYOLA
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Carlos Muñoz
 
MAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMarjorie Burga
 
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURAFORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURAEl Fortí
 
Sesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxSesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxMaritzaRetamozoVera
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADauxsoporte
 
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdfGUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdfPaolaRopero2
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.amayarogel
 
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdfDemetrio Ccesa Rayme
 
Éteres. Química Orgánica. Propiedades y reacciones
Éteres. Química Orgánica. Propiedades y reaccionesÉteres. Química Orgánica. Propiedades y reacciones
Éteres. Química Orgánica. Propiedades y reaccionesLauraColom3
 
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptx
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptxACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptx
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptxzulyvero07
 
INSTRUCCION PREPARATORIA DE TIRO .pptx
INSTRUCCION PREPARATORIA DE TIRO   .pptxINSTRUCCION PREPARATORIA DE TIRO   .pptx
INSTRUCCION PREPARATORIA DE TIRO .pptxdeimerhdz21
 
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSTEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSjlorentemartos
 
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdf
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdfCurso = Metodos Tecnicas y Modelos de Enseñanza.pdf
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdfFrancisco158360
 

Kürzlich hochgeladen (20)

Neurociencias para Educadores NE24 Ccesa007.pdf
Neurociencias para Educadores  NE24  Ccesa007.pdfNeurociencias para Educadores  NE24  Ccesa007.pdf
Neurociencias para Educadores NE24 Ccesa007.pdf
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativo
 
Dinámica florecillas a María en el mes d
Dinámica florecillas a María en el mes dDinámica florecillas a María en el mes d
Dinámica florecillas a María en el mes d
 
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
Lecciones 05 Esc. Sabática. Fe contra todo pronóstico.
 
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLA
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLAACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLA
ACERTIJO DE POSICIÓN DE CORREDORES EN LA OLIMPIADA. Por JAVIER SOLIS NOYOLA
 
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
Plan Refuerzo Escolar 2024 para estudiantes con necesidades de Aprendizaje en...
 
MAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grandeMAYO 1 PROYECTO día de la madre el amor más grande
MAYO 1 PROYECTO día de la madre el amor más grande
 
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURAFORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
FORTI-MAYO 2024.pdf.CIENCIA,EDUCACION,CULTURA
 
Sesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docxSesión de aprendizaje Planifica Textos argumentativo.docx
Sesión de aprendizaje Planifica Textos argumentativo.docx
 
CALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDADCALENDARIZACION DE MAYO / RESPONSABILIDAD
CALENDARIZACION DE MAYO / RESPONSABILIDAD
 
Medición del Movimiento Online 2024.pptx
Medición del Movimiento Online 2024.pptxMedición del Movimiento Online 2024.pptx
Medición del Movimiento Online 2024.pptx
 
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdfGUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
GUIA DE CIRCUNFERENCIA Y ELIPSE UNDÉCIMO 2024.pdf
 
La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.La triple Naturaleza del Hombre estudio.
La triple Naturaleza del Hombre estudio.
 
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdfPlanificacion Anual 2do Grado Educacion Primaria   2024   Ccesa007.pdf
Planificacion Anual 2do Grado Educacion Primaria 2024 Ccesa007.pdf
 
Éteres. Química Orgánica. Propiedades y reacciones
Éteres. Química Orgánica. Propiedades y reaccionesÉteres. Química Orgánica. Propiedades y reacciones
Éteres. Química Orgánica. Propiedades y reacciones
 
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptx
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptxACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptx
ACUERDO MINISTERIAL 078-ORGANISMOS ESCOLARES..pptx
 
INSTRUCCION PREPARATORIA DE TIRO .pptx
INSTRUCCION PREPARATORIA DE TIRO   .pptxINSTRUCCION PREPARATORIA DE TIRO   .pptx
INSTRUCCION PREPARATORIA DE TIRO .pptx
 
Power Point: Fe contra todo pronóstico.pptx
Power Point: Fe contra todo pronóstico.pptxPower Point: Fe contra todo pronóstico.pptx
Power Point: Fe contra todo pronóstico.pptx
 
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOSTEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
TEMA 13 ESPAÑA EN DEMOCRACIA:DISTINTOS GOBIERNOS
 
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdf
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdfCurso = Metodos Tecnicas y Modelos de Enseñanza.pdf
Curso = Metodos Tecnicas y Modelos de Enseñanza.pdf
 

Programación con Pygame IX

  • 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