Statistics
| Revision:

root / PyOpenGL-Demo / NeHe / lesson6-multi.py @ 1

History | View | Annotate | Download (11.6 kB)

1 1 equemene
#!
2 1 equemene
3 1 equemene
# This is statement is required by the build system to query build info
4 1 equemene
if __name__ == '__build__':
5 1 equemene
        raise Exception
6 1 equemene
7 1 equemene
import string
8 1 equemene
__version__ = string.split('$Revision: 1.1.1.1 $')[1]
9 1 equemene
__date__ = string.join(string.split('$Date: 2007/02/15 19:25:21 $')[1:3], ' ')
10 1 equemene
__author__ = 'Tarn Weisner Burton <twburton@users.sourceforge.net>'
11 1 equemene
12 1 equemene
#
13 1 equemene
# Ported to PyOpenGL 2.0 by Tarn Weisner Burton 10May2001
14 1 equemene
#
15 1 equemene
# This code was created by Richard Campbell '99 (ported to Python/PyOpenGL by John Ferguson 2000)
16 1 equemene
#
17 1 equemene
# The port was based on the lesson5 tutorial module by Tony Colston (tonetheman@hotmail.com).
18 1 equemene
#
19 1 equemene
# If you've found this code useful, please let me know (email John Ferguson at hakuin@voicenet.com).
20 1 equemene
#
21 1 equemene
# See original source and C based tutorial at http:#nehe.gamedev.net
22 1 equemene
#
23 1 equemene
# Note:
24 1 equemene
# -----
25 1 equemene
# Now, I assume you've read the prior tutorial notes and know the deal here.  The one major, new requirement
26 1 equemene
# is to have a working version of PIL (Python Image Library) on your machine.
27 1 equemene
#
28 1 equemene
# General Users:
29 1 equemene
# --------------
30 1 equemene
# I think to use textures at all you need Nunmeric Python, I tried without it and BAM Python didn't "like" the texture API.
31 1 equemene
#
32 1 equemene
# Win32 Users:
33 1 equemene
# ------------
34 1 equemene
# Well, here's the install I used to get it working:
35 1 equemene
# [1] py152.exe - include the TCL install!
36 1 equemene
# [2] PyOpenGL.EXE - probably the latest, the Vaults notes should give you a clue.
37 1 equemene
# [3] Distutils-0.9.win32.exe for step #4
38 1 equemene
# [4] Numerical-15.3.tgz - run the setup.py (need VC++ on your machine, otherwise, have fun with #3, it looks fixable to use gCC).
39 1 equemene
#
40 1 equemene
# Win98 users (yes Win98, I have Mandrake on the other partition okay?), you need to the Tcl bin directory in your PATH, not PYTHONPATH,
41 1 equemene
# just the DOS PATH.
42 1 equemene
#
43 1 equemene
# BTW, since this is Python make sure you use tabs or spaces to indent, I had numerous problems since I
44 1 equemene
# was using editors that were not sensitive to Python.
45 1 equemene
#
46 1 equemene
from OpenGL.GL import *
47 1 equemene
from OpenGL.GLUT import *
48 1 equemene
from OpenGL.GLU import *
49 1 equemene
import sys
50 1 equemene
from Image import *
51 1 equemene
from math import *
52 1 equemene
53 1 equemene
# Some api in the chain is translating the keystrokes to this octal string
54 1 equemene
# so instead of saying: ESCAPE = 27, we use the following.
55 1 equemene
ESCAPE = '\033'
56 1 equemene
57 1 equemene
# Number of the glut window.
58 1 equemene
window = 0
59 1 equemene
60 1 equemene
# Rotations for cube.
61 1 equemene
rot = 0.0
62 1 equemene
63 1 equemene
def LoadTexture(name):
64 1 equemene
        #global texture
65 1 equemene
        image = open(name)
66 1 equemene
67 1 equemene
        ix = image.size[0]
68 1 equemene
        iy = image.size[1]
69 1 equemene
        image = image.tostring("raw", "RGBX", 0, -1)
70 1 equemene
71 1 equemene
        # Create Texture
72 1 equemene
        id = glGenTextures(1)
73 1 equemene
        glBindTexture(GL_TEXTURE_2D, id)   # 2d texture (x and y size)
74 1 equemene
75 1 equemene
        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
76 1 equemene
        glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
77 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
78 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
79 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
80 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
81 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
82 1 equemene
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
83 1 equemene
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
84 1 equemene
85 1 equemene
        return id
86 1 equemene
87 1 equemene
88 1 equemene
# A general OpenGL initialization function.  Sets all of the initial parameters.
89 1 equemene
def InitGL(Width, Height):                                # We call this right after our OpenGL window is created.
90 1 equemene
        global textures, glMultiTexCoord2f, glActiveTexture, GL_TEXTURE0, GL_TEXTURE1
91 1 equemene
92 1 equemene
        print 'Checking for extension support'
93 1 equemene
        if not glMultiTexCoord2f:
94 1 equemene
                print 'No OpenGL v1.3 built-in multi-texture support, checking for extension'
95 1 equemene
                if not glMultiTexCoord2fARB:
96 1 equemene
                        print 'No GL_ARB_multitexture support, sorry, cannot run this demo!'
97 1 equemene
                        sys.exit(1)
98 1 equemene
                else:
99 1 equemene
                        glMultiTexCoord2f = glMultiTexCoord2fARB
100 1 equemene
                        glActiveTexture = glActiveTextureARB
101 1 equemene
                        GL_TEXTURE0 = GL_TEXTURE0_ARB
102 1 equemene
                        GL_TEXTURE1 = GL_TEXTURE1_ARB
103 1 equemene
        else:
104 1 equemene
                print 'Using OpenGL v1.3 built-in multi-texture support'
105 1 equemene
        try:
106 1 equemene
                if not glInitMultitextureARB():
107 1 equemene
                        print "Help!  No GL_ARB_multitexture"
108 1 equemene
                        sys.exit(1)
109 1 equemene
        except NameError, err:
110 1 equemene
                # don't need to init a built-in (or an extension any more, for that matter)
111 1 equemene
                pass
112 1 equemene
113 1 equemene
        glActiveTexture(GL_TEXTURE0)
114 1 equemene
        LoadTexture('Wall.bmp')
115 1 equemene
        glEnable(GL_TEXTURE_2D)
116 1 equemene
117 1 equemene
        glActiveTexture(GL_TEXTURE1)
118 1 equemene
        LoadTexture('NeHe.bmp')
119 1 equemene
        glEnable(GL_TEXTURE_2D)
120 1 equemene
121 1 equemene
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)
122 1 equemene
123 1 equemene
        glClearColor(0.0, 0.0, 0.0, 0.0)        # This Will Clear The Background Color To Black
124 1 equemene
        glClearDepth(1.0)                                        # Enables Clearing Of The Depth Buffer
125 1 equemene
        glDepthFunc(GL_LESS)                                # The Type Of Depth Test To Do
126 1 equemene
        glEnable(GL_DEPTH_TEST)                                # Enables Depth Testing
127 1 equemene
        glShadeModel(GL_SMOOTH)                                # Enables Smooth Color Shading
128 1 equemene
129 1 equemene
        glMatrixMode(GL_PROJECTION)
130 1 equemene
        glLoadIdentity()                                        # Reset The Projection Matrix
131 1 equemene
                                                                                # Calculate The Aspect Ratio Of The Window
132 1 equemene
        gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
133 1 equemene
134 1 equemene
        glMatrixMode(GL_MODELVIEW)
135 1 equemene
136 1 equemene
# The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
137 1 equemene
def ReSizeGLScene(Width, Height):
138 1 equemene
        if Height == 0:                                                # Prevent A Divide By Zero If The Window Is Too Small
139 1 equemene
                Height = 1
140 1 equemene
141 1 equemene
        glViewport(0, 0, Width, Height)                # Reset The Current Viewport And Perspective Transformation
142 1 equemene
        glMatrixMode(GL_PROJECTION)
143 1 equemene
        glLoadIdentity()
144 1 equemene
        gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
145 1 equemene
        glMatrixMode(GL_MODELVIEW)
146 1 equemene
147 1 equemene
deg_rad = pi/180.0
148 1 equemene
149 1 equemene
# The main drawing function.
150 1 equemene
def DrawGLScene():
151 1 equemene
        global rot, texture
152 1 equemene
153 1 equemene
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)        # Clear The Screen And The Depth Buffer
154 1 equemene
        glLoadIdentity()                                        # Reset The View
155 1 equemene
        glTranslatef(0.0,0.0,-5.0)                        # Move Into The Screen
156 1 equemene
157 1 equemene
        glRotatef(rot,1.0,0.0,0.0)                        # Rotate The Cube On It's X Axis
158 1 equemene
        glRotatef(rot,0.0,1.0,0.0)                        # Rotate The Cube On It's Y Axis
159 1 equemene
        glRotatef(rot,0.0,0.0,1.0)                        # Rotate The Cube On It's Z Axis
160 1 equemene
161 1 equemene
        # Note there does not seem to be support for this call.
162 1 equemene
        #glBindTexture(GL_TEXTURE_2D,texture)        # Rotate The Pyramid On It's Y Axis
163 1 equemene
164 1 equemene
        p = cos(rot*deg_rad)**2
165 1 equemene
        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (p, p, p, 1))
166 1 equemene
167 1 equemene
        glBegin(GL_QUADS)                            # Start Drawing The Cube
168 1 equemene
169 1 equemene
        # Front Face (note that the texture's corners have to match the quad's corners)
170 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)        # Bottom Left Of The Texture and Quad
171 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)        # Bottom Right Of The Texture and Quad
172 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0)        # Top Right Of The Texture and Quad
173 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0)        # Top Left Of The Texture and Quad
174 1 equemene
175 1 equemene
        # Back Face
176 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)        # Bottom Right Of The Texture and Quad
177 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)        # Top Right Of The Texture and Quad
178 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)        # Top Left Of The Texture and Quad
179 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)        # Bottom Left Of The Texture and Quad
180 1 equemene
181 1 equemene
        # Top Face
182 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)        # Top Left Of The Texture and Quad
183 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0)        # Bottom Left Of The Texture and Quad
184 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0)        # Bottom Right Of The Texture and Quad
185 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)        # Top Right Of The Texture and Quad
186 1 equemene
187 1 equemene
        # Bottom Face
188 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0)        # Top Right Of The Texture and Quad
189 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0)        # Top Left Of The Texture and Quad
190 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)        # Bottom Left Of The Texture and Quad
191 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)        # Bottom Right Of The Texture and Quad
192 1 equemene
193 1 equemene
        # Right face
194 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)        # Bottom Right Of The Texture and Quad
195 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)        # Top Right Of The Texture and Quad
196 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0)        # Top Left Of The Texture and Quad
197 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)        # Bottom Left Of The Texture and Quad
198 1 equemene
199 1 equemene
        # Left Face
200 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)        # Bottom Left Of The Texture and Quad
201 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)        # Bottom Right Of The Texture and Quad
202 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0)        # Top Right Of The Texture and Quad
203 1 equemene
        glMultiTexCoord2f(GL_TEXTURE0_ARB, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)        # Top Left Of The Texture and Quad
204 1 equemene
205 1 equemene
        glEnd();                                # Done Drawing The Cube
206 1 equemene
207 1 equemene
        rot  = (rot + 0.2) % 360                # rotation
208 1 equemene
209 1 equemene
        #  since this is double buffered, swap the buffers to display what just got drawn.
210 1 equemene
        glutSwapBuffers()
211 1 equemene
212 1 equemene
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
213 1 equemene
def keyPressed(*args):
214 1 equemene
        # If escape is pressed, kill everything.
215 1 equemene
        if args[0] == ESCAPE:
216 1 equemene
                sys.exit()
217 1 equemene
218 1 equemene
def main():
219 1 equemene
        global window
220 1 equemene
        glutInit(sys.argv)
221 1 equemene
222 1 equemene
        # Select type of Display mode:
223 1 equemene
        #  Double buffer
224 1 equemene
        #  RGBA color
225 1 equemene
        # Alpha components supported
226 1 equemene
        # Depth buffer
227 1 equemene
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
228 1 equemene
229 1 equemene
        # get a 640 x 480 window
230 1 equemene
        glutInitWindowSize(640, 480)
231 1 equemene
232 1 equemene
        # the window starts at the upper left corner of the screen
233 1 equemene
        glutInitWindowPosition(0, 0)
234 1 equemene
235 1 equemene
        # Okay, like the C version we retain the window id to use when closing, but for those of you new
236 1 equemene
        # to Python (like myself), remember this assignment would make the variable local and not global
237 1 equemene
        # if it weren't for the global declaration at the start of main.
238 1 equemene
        window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99")
239 1 equemene
240 1 equemene
        # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
241 1 equemene
        # set the function pointer and invoke a function to actually register the callback, otherwise it
242 1 equemene
        # would be very much like the C version of the code.
243 1 equemene
        glutDisplayFunc(DrawGLScene)
244 1 equemene
245 1 equemene
        # Uncomment this line to get full screen.
246 1 equemene
        # glutFullScreen()
247 1 equemene
248 1 equemene
        # When we are doing nothing, redraw the scene.
249 1 equemene
        glutIdleFunc(DrawGLScene)
250 1 equemene
251 1 equemene
        # Register the function called when our window is resized.
252 1 equemene
        glutReshapeFunc(ReSizeGLScene)
253 1 equemene
254 1 equemene
        # Register the function called when the keyboard is pressed.
255 1 equemene
        glutKeyboardFunc(keyPressed)
256 1 equemene
257 1 equemene
        # Initialize our window.
258 1 equemene
        InitGL(640, 480)
259 1 equemene
260 1 equemene
        # Start Event Processing Engine
261 1 equemene
        glutMainLoop()
262 1 equemene
263 1 equemene
# Print message to console, and kick off the main to get it rolling.
264 1 equemene
if __name__ == "__main__":
265 1 equemene
        print "Hit ESC key to quit."
266 1 equemene
        main()