Statistics
| Revision:

root / PyOpenGL-Demo / GLUT / glutplane.py @ 1

History | View | Annotate | Download (6.6 kB)

1
import sys
2

    
3
from OpenGL.GLUT import *
4
from OpenGL.GLU import *
5
from OpenGL.GL import *
6
from math import *
7
from random import random, choice, randint, getrandbits
8

    
9
"""                       
10
   Copyright (c) Mark J. Kilgard, 1994.   
11

12
   This program is freely distributable without licensing fees 
13
   and is provided without guarantee or warrantee expressed or 
14
   implied. This program is -not- in the public domain.  
15
"""
16
M_PI   = pi
17
M_PI_2 = pi / 2.0
18

    
19
moving = False
20
MAX_PLANES = 15
21

    
22
# define plane object
23
#
24
class plane(object):
25
    def __init__(self, speed, red, green, blue, theta, x, y, z, angle):
26
        self.speed = speed
27
        self.red   = red
28
        self.green = green
29
        self.blue  = blue
30
        self.theta = theta
31
        self.angle = angle
32
        self.x = x
33
        self.y = y
34
        self.z = z 
35

    
36
# create list of planes
37
#
38
planes = []        
39
for n in range(MAX_PLANES) :
40
    p = plane(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
41
    planes.append(p)
42

    
43

    
44
# define the GLUT display function
45
#
46
def draw():
47
    glClear(GL_DEPTH_BUFFER_BIT)
48
    # paint black to blue smooth shaded polygon for background 
49
    glDisable(GL_DEPTH_TEST)
50
    glShadeModel(GL_SMOOTH)
51
    glBegin(GL_POLYGON);
52
    glColor3f(0.0, 0.0, 0.0);
53
    glVertex3f(-20.0, 20.0, -19.0)
54
    glVertex3f( 20.0, 20.0, -19.0)
55
    glColor3f(0.0, 0.0, 1.0)
56
    glVertex3f( 20.0, -20.0, -19.0)
57
    glVertex3f(-20.0, -20.0, -19.0)
58
    glEnd()
59
    # paint planes 
60
    glEnable(GL_DEPTH_TEST)
61
    glShadeModel(GL_FLAT)
62
    for n in range(MAX_PLANES) :
63
        if (planes[n].speed != 0.0) :
64
            glPushMatrix()
65
            glTranslatef(planes[n].x, planes[n].y, planes[n].z)
66
            glRotatef(290.0, 1.0, 0.0, 0.0)
67
            glRotatef(planes[n].angle, 0.0, 0.0, 1.0)
68
            glScalef(1.0 / 3.0, 1.0 / 4.0, 1.0 / 4.0)
69
            glTranslatef(0.0, -4.0, -1.5)
70
            glBegin(GL_TRIANGLE_STRIP)
71
            # left wing 
72
            glVertex3f(-7.0, 0.0, 2.0)
73
            glVertex3f(-1.0, 0.0, 3.0)
74
            red   = planes[n].red
75
            green = planes[n].green
76
            blue  = planes[n].blue
77
            glColor3f(red, green, blue)
78
            glVertex3f(-1.0, 7.0, 3.0)
79
            # left side 
80
            glColor3f(0.6 * red, 0.6 * green, 0.6 * blue)
81
            glVertex3f(0.0, 0.0, 0.0)
82
            glVertex3f(0.0, 8.0, 0.0)
83
            # right side
84
            glVertex3f(1.0, 0.0, 3.0)
85
            glVertex3f(1.0, 7.0, 3.0)
86
            # final tip of right wing */
87
            glColor3f(red, green, blue)
88
            glVertex3f(7.0, 0.0, 2.0)
89
            glEnd()
90
            glPopMatrix()
91
     
92
    glutSwapBuffers()
93
    return
94

    
95
# define the plane position and speed incrementor
96
#
97
def tick_per_plane(i):
98
    planes[i].theta += planes[i].speed
99
    theta = planes[i].theta
100
    planes[i].z = -10 + 4 * cos(theta)
101
    planes[i].x = 5 * sin(2 * theta)
102
    planes[i].y = sin(theta / 3.4) * 3
103
    planes[i].angle = ((atan(2.0) + M_PI_2) * sin(theta) - M_PI_2) * 180 / M_PI
104
    if (planes[i].speed < 0.0) :
105
        planes[i].angle += 180.0
106
    return
107

    
108
#define the list of rgb tuples for setting plane colours by random choice
109
#
110
rgblist = [(1.0, 0.0, 0.0),  # red 
111
           (1.0, 1.0, 1.0),  # white 
112
           (0.0, 1.0, 0.0),  # green
113
           (1.0, 0.0, 1.0),  # magenta
114
           (1.0, 1.0, 0.0),  # yellow
115
           (0.0, 1.0, 1.0)   # cyan
116
          ]
117

    
118
# define add planes to display of planes
119
# 
120
def add_plane():
121
    for i in range(MAX_PLANES) :
122
        if (planes[i].speed == 0.0) :
123
            planes[i].red, planes[i].green, planes[i].blue = choice(rgblist)
124
            planes[i].speed = (float(randint(0, 19)) * 0.001) + 0.02
125
            if (getrandbits(32) & 0x1) :
126
                planes[i].speed *= -1
127
            planes[i].theta = float(randint(0, 256)) * 0.1111
128
            tick_per_plane(i)
129
            if (not moving) :
130
                glutPostRedisplay()
131
            return
132
    return
133

    
134

    
135
# define remove a plane from display of planes
136
#
137
def remove_plane():
138
    for i in range(MAX_PLANES-1, -1, -1) :
139
      if (planes[i].speed != 0) :
140
          planes[i].speed = 0
141
          if (not moving) :
142
              glutPostRedisplay()
143
          return
144
    return
145

    
146
#define choice of planes to animate
147
#
148
def tick():
149
    for i in range(MAX_PLANES) :
150
        if (planes[i].speed != 0.0) :
151
            tick_per_plane(i)
152
    return
153

    
154
# define animator so that motion can be started
155
def animate():
156
    tick()
157
    glutPostRedisplay()
158
    return
159

    
160

    
161
def visible(state):
162
    if (state == GLUT_VISIBLE) :
163
        if (moving) :
164
            glutIdleFunc(animate)
165
    else :
166
        if (moving) :
167
            glutIdleFunc(None)
168
    return
169

    
170

    
171
# ARGSUSED1 
172

    
173
def keyboard( ch,  x,  y):
174
    if(ch == ' ') :
175
        if (not moving) :
176
            tick()
177
            glutPostRedisplay()
178
    elif (ch == chr(27)) :
179
        sys.exit(0)
180
    return 0
181

    
182
VOID, ADD_PLANE, REMOVE_PLANE, MOTION_ON, MOTION_OFF, QUIT = range(6)
183

    
184
def domotion_on(): 
185
    moving = GL_TRUE
186
    glutChangeToMenuEntry(3, "Motion off", MOTION_OFF)
187
    glutIdleFunc(animate)
188
    return
189

    
190
def domotion_off():
191
    moving = GL_FALSE
192
    glutChangeToMenuEntry(3, "Motion", MOTION_ON)
193
    glutIdleFunc(None)
194
    return
195

    
196
def doquit():
197
    sys.exit(0)
198
    return
199

    
200
menudict ={ADD_PLANE : add_plane, 
201
           REMOVE_PLANE : remove_plane, 
202
           MOTION_ON : domotion_on, 
203
           MOTION_OFF: domotion_off, 
204
           QUIT : doquit}
205

    
206
def dmenu(item):
207
    menudict[item]()
208
    return 0
209

    
210
if __name__ == "__main__":
211
        glutInit(['glutplane'])
212
        glutInitWindowPosition(112, 84)
213
        glutInitWindowSize(800, 600)
214
        # use multisampling if available 
215
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE)
216
        wintitle = "glutplane  Copyright (c) Mark J. Kilgard, 1994. RIGHT-CLICK for menu"
217
        glutCreateWindow(wintitle)
218
        glutDisplayFunc(draw)
219
        glutKeyboardFunc(keyboard)
220
        glutVisibilityFunc(visible)
221
        #
222
        # This program fails if PyOpenGL-3.0.0b1-py2.5.egg\OpenGL\GLUT\special.py
223
        # is not corrected at line 158 to read :
224
        # callbackType = ctypes.CFUNCTYPE( None, ctypes.c_int )
225
        # instead of :
226
        # callbackType = ctypes.CFUNCTYPE( ctypes.c_int, ctypes.c_int )
227
        #
228
        # RIGHT-CLICK to display the menu
229
        #
230
        glutCreateMenu(dmenu)
231
        glutAddMenuEntry("Add plane", ADD_PLANE)
232
        glutAddMenuEntry("Remove plane", REMOVE_PLANE)
233
        glutAddMenuEntry("Motion", MOTION_ON)
234
        glutAddMenuEntry("Quit", QUIT)
235
        glutAttachMenu(GLUT_RIGHT_BUTTON)
236

    
237
        # setup OpenGL state 
238
        glClearDepth(1.0)
239
        glClearColor(0.0, 0.0, 0.0, 0.0)
240
        glMatrixMode(GL_PROJECTION)
241
        glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 30)
242
        glMatrixMode(GL_MODELVIEW)
243
        # add three initial random planes 
244
        add_plane()
245
        add_plane()
246
        add_plane()
247
        # start event processing */
248
        print 'RIGHT-CLICK to display the menu.'
249
        glutMainLoop()
250