#!/usr/bin/python
# -*- coding: utf-8 -*-
# Librerías del programa
import sys
import math
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
# Iluminación personalizada de la animación
class Luz(object):
encendida = True
colores = [(1., 1., 1., 1.), (1., 0.5, 0.5, 1.),
(0.5,1.,0.5,1.), (0.5,0.5,1.,1.)]
def __init__(self, luz_id, posicion):
# Identificador del objeto de iluminación
self.luz_id = luz_id
# Posición de la iluminación
self.posicion = posicion
# Variable para seleccionar colores
self.color_actual = 0
# Tipo de iluminación
def dibujar(self):
light_id = self.luz_id
color = Luz.colores[self.color_actual]
glLightfv(light_id, GL_POSITION, self.posicion)
glLightfv(light_id, GL_DIFFUSE, color)
glLightfv(light_id, GL_CONSTANT_ATTENUATION, 0.1)
glLightfv(light_id, GL_LINEAR_ATTENUATION, 0.05)
def cambiar_color(self):
self.color_actual += 1
# Reinicia el color actual
self.color_actual %= len(Luz.colores)
def enable(self):
if not Luz.encendida:
glEnable(GL_LIGHTING)
Luz.encendida = True
glEnable(self.luz_id)
# Construcción de la Esfera
class Esfera(object):
# Divisiones de norte a sur
meridianos = 40
# Divisiones este a oeste
paralelos = 40
# Constructor de la clase
def __init__(self, radio, posicion, color):
self.radio = radio
self.posicion = posicion
self.color = color
# Función que dibuja una esfera
def dibujar(self):
# Ubicacion de la figura 3d
glTranslatef(*self.posicion)
# Especifica los parametros del material para la iluminación
# GL_AMBIENT , GL_EMISSION
glMaterialfv(GL_FRONT, GL_DIFFUSE, self.color)
# Función especial para dibujar esferas
glutSolidSphere(self.radio, Esfera.meridianos, Esfera.paralelos)
# Aplicación principal
class App(object):
# Constructor de la clase
def __init__(self, largo=800, ancho=600):
# Titulo de la ventana
self.titulo = 'Esferas con OpenGL'
# Medidas de la ventana
self.largo = largo
self.ancho = ancho
# Angulo de vision de la camara
self.angulo = 0
# Distancia de la camara
self.distancia = 20
# Instancia de la clase Luz
self.iluminacion = Luz(GL_LIGHT0, (15, 5, 15, 1))
# Instancia de la clase Esfera
self.esfera1 = Esfera(2, (0, 0, 0), (1, 1, 1, 1))
# Instancia de la clase Esfera
self.esfera2 = Esfera(1, (4, 2, 0), (1, 0.4, 0.4, 1))
# Función que crea la ventana y los graficos 3d
def iniciar(self):
# Inicializa la librería GLUT
glutInit()
# Funciones para inicializar la ventana
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowPosition(50, 50)
glutInitWindowSize(self.largo, self.ancho)
glutCreateWindow(self.titulo)
# Activar las funciones graficas
glEnable(GL_DEPTH_TEST)
# Activar iluminación
glEnable(GL_LIGHTING)
# Seleccionar la constante de iluminación
glEnable(GL_LIGHT0)
# Activar la iluminación con las características de nuestra función
self.iluminacion.enable()
# Color de fondo
glClearColor(.1, .1, .1, 1)
glMatrixMode(GL_PROJECTION)
aspect = self.largo / self.ancho
gluPerspective(40., aspect, 1., 40.)
glMatrixMode(GL_MODELVIEW)
# Llamada para dibujar las figuras
glutDisplayFunc(self.dibujar)
# Llamada para activar las funciones del teclado
glutSpecialFunc(self.keyboard)
#Inicia el ciclo de la libreria
glutMainLoop()
# ...
# Función que dibuja las figuras 3D
def dibujar(self):
# Coordenadas de la cámara
x = math.sin(self.angulo) * self.distancia
z = math.cos(self.angulo) * self.distancia
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
# Coordenadas de la cámara
# Posición
# Dirección en la que mira
# Orientación
gluLookAt(x, 0, z,
0, 0, 0,
0, 1, 0)
# Se crea la iluminación
self.iluminacion.dibujar()
# Se crea la primer esfera
self.esfera1.dibujar()
# Se crea la segunda esfera
self.esfera2.dibujar()
glutSwapBuffers()
# Funciones del teclado
def keyboard(self, tecla, x, y):
if tecla == GLUT_KEY_INSERT:
# Cerrar ventana
sys.exit()
if tecla == GLUT_KEY_UP:
# Acercar la cámara
self.distancia -= 0.1
if tecla == GLUT_KEY_DOWN:
# Alejar cámara
self.distancia += 0.1
if tecla == GLUT_KEY_LEFT:
# Girar cámara a la izquierda
self.angulo -= 0.05
if tecla == GLUT_KEY_RIGHT:
# Girar cámara a la derecha
self.angulo += 0.05
if tecla == GLUT_KEY_F1:
# Cambiar color de las esferas
self.iluminacion.cambiar_color()
# Máxima y mínima distancia de la cámara
self.distancia = max(10, min(self.distancia, 20))
# Reiniciar el ángulo de giro
self.angulo %= math.pi * 2
# Actualiza el plano 3d y las figuras de acuerdo al movimiento de la camara
glutPostRedisplay()
if __name__ == '__main__':
app = App()
app.iniciar()
https://drive.google.com/file/d/1g01y1-6-TQJOzCVfgJfw6wGtfKfa4KoH/view?usp=sharing