Lightningbeam/PyGUI-2.5.3/Tests/91-glview-task.py

249 lines
8.5 KiB
Python

# A translation of the gears demo that comes with mesa.
# Conversion from gtk.gl module to PyGtkGLExt by Naofumi Yasufuku
# Conversion to PyGUI by Greg Ewing
import math
from GUI import Window, Task, application
from GUI.GL import GLView
from OpenGL import GL
frame_interval = 0.01
rotation_step = 5.0
rotations = {
'up_arrow': (-rotation_step, 0.0, 0.0),
'down_arrow': ( rotation_step, 0.0, 0.0),
'left_arrow': (0.0, -rotation_step, 0.0),
'right_arrow': (0.0, rotation_step, 0.0),
}
#----------------------------------------------------------------------------
# Draw a gear wheel. You'll probably want to call this function when
# building a display list since we do a lot of trig here.
#
# Input:
# inner_radius - radius of hole at center
# outer_radius - radius at center of teeth
# width - width of gear
# teeth - number of teeth
# tooth_depth - depth of tooth
def gear(inner_radius, outer_radius, width, teeth, tooth_depth):
cos = math.cos
sin = math.sin
r0 = inner_radius
r1 = outer_radius - tooth_depth/2.0
r2 = outer_radius + tooth_depth/2.0
da = 2.0*math.pi / teeth / 4.0
GL.glShadeModel(GL.GL_FLAT)
GL.glNormal3f(0.0, 0.0, 1.0)
# draw front face
GL.glBegin(GL.GL_QUAD_STRIP)
for i in range(teeth + 1):
angle = i * 2.0*math.pi / teeth
GL.glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5)
GL.glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5)
GL.glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5)
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5)
GL.glEnd()
# draw front sides of teeth
GL.glBegin(GL.GL_QUADS)
da = 2.0*math.pi / teeth / 4.0
for i in range(teeth):
angle = i * 2.0*math.pi / teeth
GL.glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5)
GL.glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5)
GL.glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5)
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5)
GL.glEnd()
GL.glNormal3f(0.0, 0.0, -1.0)
# draw back face
GL.glBegin(GL.GL_QUAD_STRIP)
for i in range(teeth + 1):
angle = i * 2.0 * math.pi / teeth
GL.glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5)
GL.glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5)
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da),-width*0.5)
GL.glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5)
GL.glEnd()
# draw back sides of teeth
GL.glBegin(GL.GL_QUADS)
da = 2.0*math.pi / teeth / 4.0
for i in range(teeth):
angle = i * 2.0*math.pi / teeth
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da),-width*0.5)
GL.glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da),-width*0.5)
GL.glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5)
GL.glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5)
GL.glEnd()
# draw outward faces of teeth
GL.glBegin(GL.GL_QUAD_STRIP)
for i in range(teeth):
angle = i * 2.0*math.pi / teeth
GL.glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5)
GL.glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5)
u = r2*cos(angle+da) - r1*cos(angle)
v = r2*sin(angle+da) - r1*sin(angle)
len = math.sqrt(u*u + v*v)
u = u / len
v = v / len
GL.glNormal3f(v, -u, 0.0)
GL.glVertex3f(r2*cos(angle+da), r2*sin(angle+da), width*0.5)
GL.glVertex3f(r2*cos(angle+da), r2*sin(angle+da), -width*0.5)
GL.glNormal3f(cos(angle), sin(angle), 0.0)
GL.glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5)
GL.glVertex3f(r2*cos(angle+2*da), r2*sin(angle+2*da),-width*0.5)
u = r1*cos(angle+3*da) - r2*cos(angle+2*da)
v = r1*sin(angle+3*da) - r2*sin(angle+2*da)
GL.glNormal3f(v, -u, 0.0)
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5)
GL.glVertex3f(r1*cos(angle+3*da), r1*sin(angle+3*da),-width*0.5)
GL.glNormal3f(cos(angle), sin(angle), 0.0)
GL.glVertex3f(r1*cos(0), r1*sin(0), width*0.5)
GL.glVertex3f(r1*cos(0), r1*sin(0), -width*0.5)
GL.glEnd()
GL.glShadeModel(GL.GL_SMOOTH)
# draw inside radius cylinder
GL.glBegin(GL.GL_QUAD_STRIP)
for i in range(teeth + 1):
angle = i * 2.0*math.pi / teeth;
GL.glNormal3f(-cos(angle), -sin(angle), 0.0)
GL.glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5)
GL.glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5)
GL.glEnd()
#----------------------------------------------------------------------------
class GearsView(GLView):
view_rotx=20.0
view_roty=30.0
view_rotz=0.0
angle = 0.0
def init_context(self):
#print "Init Context" ###
pos = (5.0, 5.0, 10.0, 0.0)
red = (0.8, 0.1, 0.0, 1.0)
green = (0.0, 0.8, 0.2, 1.0)
blue = (0.2, 0.2, 1.0, 1.0)
#
GL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos)
GL.glEnable(GL.GL_CULL_FACE)
GL.glEnable(GL.GL_LIGHTING)
GL.glEnable(GL.GL_LIGHT0)
GL.glEnable(GL.GL_DEPTH_TEST)
#
self.gear1 = GL.glGenLists(1)
GL.glNewList(self.gear1, GL.GL_COMPILE)
GL.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red)
gear(1.0, 4.0, 1.0, 20, 0.7)
GL.glEndList()
#
self.gear2 = GL.glGenLists(1)
GL.glNewList(self.gear2, GL.GL_COMPILE)
GL.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green)
gear(0.5, 2.0, 2.0, 10, 0.7)
GL.glEndList()
#
self.gear3 = GL.glGenLists(1)
GL.glNewList(self.gear3, GL.GL_COMPILE)
GL.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue)
gear(1.3, 2.0, 0.5, 10, 0.7)
GL.glEndList()
#
GL.glEnable(GL.GL_NORMALIZE)
#
self.frame_task = Task(self.next_frame, frame_interval, repeat = 1)
def init_projection(self):
#print "init_projection" ###
width, height = self.size
if width > height:
w = float(width) / float(height)
GL.glFrustum(-w, w, -1.0, 1.0, 5.0, 60.0)
else:
h = float(height) / float(width)
GL.glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0)
def render(self):
#print "Render" ###
#GL.glMatrixMode(GL.GL_MODELVIEW)
#GL.glLoadIdentity()
GL.glTranslatef(0.0, 0.0, -40.0)
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
#
GL.glPushMatrix()
#
GL.glRotatef(self.view_rotx, 1.0, 0.0, 0.0)
GL.glRotatef(self.view_roty, 0.0, 1.0, 0.0)
GL.glRotatef(self.view_rotz, 0.0, 0.0, 1.0)
#
GL.glPushMatrix()
GL.glTranslatef(-3.0, -2.0, 0.0)
GL.glRotatef(self.angle, 0.0, 0.0, 1.0)
GL.glCallList(self.gear1)
GL.glPopMatrix()
#
GL.glPushMatrix()
GL.glTranslatef(3.1, -2.0, 0.0)
GL.glRotatef(-2.0 * self.angle - 9.0, 0.0, 0.0, 1.0)
GL.glCallList(self.gear2)
GL.glPopMatrix()
#
GL.glPushMatrix()
GL.glTranslatef(-3.1, 4.2, 0.0)
GL.glRotatef(-2.0 * self.angle - 25.0, 0.0, 0.0, 1.0)
GL.glCallList(self.gear3)
GL.glPopMatrix()
#
GL.glPopMatrix()
def next_frame(self):
#print "Next Frame" ###
self.angle += 2.0
self.invalidate()
self.update()
def key_down(self, event):
#print "Key:", event ###
try:
xa, ya, za = rotations[event.key]
self.view_rotx += xa
self.view_roty += ya
self.view_rotz += za
except KeyError:
pass
#----------------------------------------------------------------------------
def test():
view = GearsView(size = (300, 300))
win = Window(title = "Gears")
win.place(view, sticky = "nsew")
view.become_target()
win.shrink_wrap()
win.show()
application().run()
instructions = """
Gears should be spinning. The arrow keys should rotate the view.
"""
print instructions
test()