-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathteapot.py
212 lines (154 loc) · 5.03 KB
/
teapot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# teapots.py
# by Allen Downey
# The following program demonstrates features from the
# first few chapters of the Red Book. I have lifted
# lines from lots of different examples, with the intention
# of getting it all in one place.
# The documentation for PyOpenGL, GLU and GLUT is at:
#http://pyopengl.sourceforge.net/documentation/manual/reference-GL.xml
#http://pyopengl.sourceforge.net/documentation/manual/reference-GLU.xml
#http://pyopengl.sourceforge.net/documentation/manual/reference-GLUT.xml
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
from time import sleep
revolution = 10
rotation = 10
def init():
# clear the background
glClearColor (1, 1, 1, 0)
# other choice is GL_FLAT
glShadeModel (GL_SMOOTH)
# enable hidden surface removal
glEnable(GL_DEPTH_TEST)
# enable lighting
glEnable(GL_LIGHTING)
# put a red light on the camera
position = [0, 0, 10, 0]
color = [1, 0, 0, 0]
set_up_light(GL_LIGHT0, position, color)
# put a blue light on the right
position = [10, 0, 0, 0]
color = [0, 0, 1, 0]
set_up_light(GL_LIGHT1, position, color)
# put a green light at high noon
position = [0, 10, 0, 0]
color = [0, 1, 0, 0]
set_up_light(GL_LIGHT2, position, color)
def display():
# display runs whenever we have to redraw the screen
# clear out the colors and the buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# for reasons I don't understand, we have to set up
# the camera every time display runs
set_up_camera()
# tell GL which matrix we want to work with, and
# set it to the identity
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# draw a sphere at the current location, size 2
# use 32 lines of latitude and longitude
glutSolidSphere(2, 32, 32)
# save the current matrix before we mangle it
glPushMatrix()
# rotate to the right position in the orbit
axis = (0, 1, 0)
glRotatef(revolution, *axis)
# move out to the orbit
glTranslatef(4.2, 0, 0)
# rotate the teapot
axis = (0, 1, 0)
glRotatef(rotation, *axis)
# draw the teapot, size 1
glutSolidTeapot(0.5)
# restore the saved matrix
glPopMatrix()
# reveal the finished picture
glutSwapBuffers()
def set_up_camera():
# where is the camera
camera = (0, 0, 10)
# what is it looking at
target = (0, 0, 0)
# which way is up
up = (0, 1, 0)
# point and shoot!
gluLookAt(*camera+target+up)
def set_up_light(name, position=[0, 0, 1, 0], color=[1, 1, 1, 1]):
# tell GL which matrix we want, and save the current state
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
# color is in RGBA format
light_ambient = color
light_diffuse = color
light_specular = color
# position is in x, y, z, w format
# if w is 0 then the light is "directional"
# otherwise it is "positional"
# directional is like the sun, very far away
# positional behaves like a lamp in the scene
light_position = position
# turn on the lights
# read the documentation for an explanation of the
# different kinds of light
glLightfv(name, GL_AMBIENT, light_ambient)
glLightfv(name, GL_DIFFUSE, light_diffuse)
glLightfv(name, GL_SPECULAR, light_specular)
glLightfv(name, GL_POSITION, light_position)
glEnable(name)
# restore the matrix before we go
glPopMatrix()
def reshape (w, h):
# reshape gets invoked when the window is resized
# change the size of the viewport
glViewport (0, 0, w, h)
# change the way the scene is projected into
# the viewport
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
(fovy, aspect, near, far) = (60, 1, 2, 20)
gluPerspective(fovy, aspect, near, far)
def keyboard(key, x, y):
# keyboard in invoked when the user presses a key
# quit if the user presses Control-C
if key == chr(3):
sys.exit(0)
def mouse(button, state, x, y):
# mouse is invoked when the user clicks the mouse
if button == GLUT_LEFT_BUTTON:
if state == GLUT_DOWN:
sys.exit()
def idle():
# idle is invoked when GL isn't doing anything else
global revolution, rotation
# update revolution and rotation
revolution = (revolution + 1) % 360
rotation = (rotation + 2) % 360
# mark the scene for redisplay during the next iteration
# of mainLoop
glutPostRedisplay()
sleep(0.05)
def main(*args):
# process command-line arguments
glutInit(args)
# turn on double-buffering
# and rgb color with alpha channel
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA)
# create the window
glutInitWindowSize (500, 500)
glutInitWindowPosition (100, 100)
glutCreateWindow (args[0])
# run my init function
init ()
# set up the callbacks
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutKeyboardFunc(keyboard)
glutMouseFunc(mouse)
glutIdleFunc(idle)
# loop!
glutMainLoop()
if __name__ == "__main__":
main(*sys.argv)