Statistics
| Revision:

root / PyOpenGL-Demo / NeHe / lesson42.py @ 1

History | View | Annotate | Download (19.5 kB)

1
# NeHe Tutorial Lesson: 42 - Multiple Viewports
2
#
3
# Ported to PyOpenGL 2.0 by Brian Leair 18 Jan 2004
4
#
5
# This code was created by Jeff Molofee 2000
6
#
7
# The port was based on the PyOpenGL tutorials and from 
8
# PyOpenGLContext (tests/glprint.py)
9
#
10
# If you've found this code useful, feel free to let me know 
11
# at (Brian Leair telcom_sage@yahoo.com).
12
#
13
# See original source and C based tutorial at http://nehe.gamedev.net
14
#
15
# Note:
16
# -----
17
# This code is not an ideal example of Pythonic coding or use of OO techniques.  
18
# It is a simple and direct exposition of how to use the Open GL API in 
19
# Python via the PyOpenGL package. It also uses GLUT, a high quality 
20
# platform independent library. Due to using these APIs, this code is 
21
# more like a C program using procedural based programming.
22
#
23
# To run this example you will need:
24
# Python         - www.python.org (v 2.3 as of 1/2004)
25
# PyOpenGL         - pyopengl.sourceforge.net (v 2.0.1.07 as of 1/2004)
26
# Numeric Python        - (v.22 of "numpy" as of 1/2004) numpy.sourceforge.net
27
#
28
# Make sure to get versions of Numeric, and PyOpenGL to match your
29
# version of python.
30
#
31
#
32
# /***************************************************************************************************************
33
# *                                                      *                                                       *
34
# *  Lesson 42: Multiple Viewports                       *  Created:  05/17/2003                                 *
35
# *                                                      *                                                       *
36
# *  This Program Was Written By Jeff Molofee (NeHe)     *  Runs Much Faster (Many Useless Loops Removed)        *
37
# *  From http://nehe.gamedev.net.                       *                                                       *
38
# *                                                      *  Maze Code Is Still Very Unoptimized.  Speed Can Be   *
39
# *  I Wanted To Create A Maze, And Was Able To Find     *  Increased Considerably By Keeping Track Of Cells     *
40
# *  Example Code, But Most Of It Was Uncommented And    *  That Have Been Visited Rather Than Randomly          *
41
# *  Difficult To Figure Out.                            *  Searching For Cells That Still Need To Be Visited.   *
42
# *                                                      *                                                       *
43
# *  This Is A Direct Conversion Of Basic Code I Wrote   *  This Tutorial Demonstrates Multiple Viewports In A   *
44
# *  On The Atari XE Many Years Ago.                     *  Single Window With Both Ortho And Perspective Modes  *
45
# *                                                      *  Used At The Same Time.  As Well, Two Of The Views    *
46
# *  It Barely Resembles The Basic Code, But The Idea    *  Have Lighting Enabled, While The Other Two Do Not.   *
47
# *  Is Exactly The Same.                                *                                                       *
48
# *                                                      *********************************************************
49
# *  Branches Are Always Made From An Existing Path      *
50
# *  So There Should Always Be A Path Through The Maze   *
51
# *  Although It Could Be Quite Short :)                 *
52
# *                                                      *
53
# *  Do Whatever You Want With This Code.  If You Found  *
54
# *  It Useful Or Have Made Some Nice Changes To It,     *
55
# *  Send Me An Email: nehe@connect.ab.ca                *
56
# *                                                      *
57
# *******************************************************/
58
#
59

    
60
#
61
# Ported to PyOpenGL 2.0 by Brian Leair  Feb, 2004
62
#
63
from OpenGL.GL import *
64
from OpenGL.GLUT import *
65
from OpenGL.GLU import *
66
try:
67
        import numpy as Numeric
68
except ImportError, err:
69
        try: 
70
                import Numeric
71
        except ImportError, err:
72
                print "This demo requires the numpy or Numeric extension, sorry"
73
                import sys
74
                sys.exit()
75
import random
76
import time                                        # sleep () pause for 5 seconds when maze is complete
77
import sys
78

    
79

    
80

    
81
# *********************** Globals *********************** 
82
# Python 2.2 defines these directly
83
try:
84
        True
85
except NameError:
86
        True = 1==1
87
        False = 1==0
88

    
89

    
90
# Some api in the chain is translating the keystrokes to this octal string
91
# so instead of saying: ESCAPE = 27, we use the following.
92
ESCAPE = '\033'
93

    
94
# Number of the glut window.
95
window = 0
96

    
97

    
98
# // User Defined Variables
99

    
100
# // General Loops (Used For Seeking)
101
mx = 0
102
my = 0
103
done = False;                                                                                                        # // Flag To Let Us Know When It's Done
104

    
105
width        = 128;                                                                                                        # // Maze Width  (Must Be A Power Of 2)
106
height        = 128;                                                                                                        # // Maze Height (Must Be A Power Of 2)
107

    
108
tex_data = None                                                                                                        # numarray of unsigned bytes - # // Holds Our RGB Texture Data 
109

    
110
quadric = None                                                                                                        # // The Quadric Object
111

    
112
r = [None ] * 4
113
g = [None ] * 4
114
b = [None ] * 4                                                                                                        # // Random Colors (4 Red, 4 Green, 4 Blue)
115

    
116
xrot = 0
117
yrot = 0
118
zrot = 0                                                                                                                # // Use For Rotation Of Objects
119

    
120

    
121

    
122
def UpdateTex(dmx, dmy):
123
        """ // Update Pixel dmx, dmy On The Texture """
124
        global tex_data
125

    
126
        tex_data[0+((dmx+(width*dmy))*3)]=255;                                                # // Set Red Pixel To Full Bright
127
        tex_data[1+((dmx+(width*dmy))*3)]=255;                                                # // Set Green Pixel To Full Bright
128
        tex_data[2+((dmx+(width*dmy))*3)]=255;                                                # // Set Blue Pixel To Full Bright
129
        return
130

    
131

    
132
def Reset ():
133
        """ // Reset The Maze, Colors, Start Point, Etc        """
134
        global tex_data, r, g, b, mx, my
135

    
136
        # ZeroMemory(tex_data, width * height *3);                                                        // Clear Out The Texture Memory With 0's
137
        # This creates or array of unsigned bytes for our texture data. All values initialized to 0
138
        # tex_data = numarray.zeros ((width * height * 3), type="u1")
139
        tex_data = Numeric.zeros ((width * height * 3), "b")
140

    
141
        # This Will seed the random num stream with current system time.
142
        random.seed ()
143

    
144
        for loop in xrange (4):                                                                                                # // Loop So We Can Assign 4 Random Colors
145
                r[loop]=128 + random.randint (0,127)                                                         # // Pick A Random Red Color (Bright)
146
                g[loop]=128 + random.randint (0,127)                                                         # // Pick A Random Green Color (Bright)
147
                b[loop]=128 + random.randint (0,127)                                                         # // Pick A Random Blue Color (Bright)
148

    
149
        mx = random.randint (0, (width/2) - 1) * 2                                                                # // Pick A New Random X Position
150
        my = random.randint (0, (width/2) - 1) * 2                                                                # // Pick A New Random Y Position
151
        return
152

    
153

    
154

    
155
# // Any GL Init Code & User Initialiazation Goes Here
156
def InitGL(Width, Height):                                # We call this right after our OpenGL window is created.
157
        global tex_data, width, height, quadric
158

    
159
        Reset ()                                                        # // Call Reset To Build Our Initial Texture, Etc.
160

    
161
        glEnable(GL_TEXTURE_2D);                                                                        # // Enable Texture Mapping
162
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
163
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
164
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
165
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
166
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_data.tostring ());
167

    
168
        glClearColor (0.0, 0.0, 0.0, 0.0);                                                        # // Black Background
169
        glClearDepth (1.0);                                                                                        # // Depth Buffer Setup
170
        glDepthFunc (GL_LEQUAL);                                                                        # // The Type Of Depth Testing
171
        glEnable (GL_DEPTH_TEST);                                                                        # // Enable Depth Testing
172

    
173
        glEnable(GL_COLOR_MATERIAL);                                                                # // Enable Color Material (Allows Us To Tint Textures)
174

    
175
        quadric=gluNewQuadric();                                                                        # // Create A Pointer To The Quadric Object
176
        gluQuadricNormals(quadric, GLU_SMOOTH);                                                # // Create Smooth Normals 
177
        gluQuadricTexture(quadric, GL_TRUE);                                                # // Create Texture Coords
178

    
179
        glEnable(GL_LIGHT0);                                                                                # // Enable Light0 (Default GL Light)
180

    
181
        return True;                                                                                                # // Return TRUE (Initialization Successful)
182

    
183
def Update ():
184
        """ Solves/builds the maze. """
185
        global width, height, done, mx, my
186

    
187
        done=True;                                                                                                                        # // Set done To True
188
        for x in xrange (0, width, 2):                                                                                # // Loop Through All The Rooms
189
                for y in xrange (0, height, 2):                                                                        # // On X And Y Axis
190
                        if (tex_data[((x+(width*y))*3)]==0):                                                # // If Current Texture Pixel (Room) Is Blank
191
                                done=False;                                                                                                # // We Have To Set done To False (Not Finished Yet)
192

    
193
        if (done):                                                                                                                        # // If done Is True Then There Were No Unvisited Rooms
194
                # // Display A Message At The Top Of The Window, Pause For A Bit And Then Start Building A New Maze!
195
                glutSetWindowTitle ("Lesson 42: Multiple Viewports... 2003 NeHe Productions... Maze Complete!");
196
                time.sleep (5)
197
                glutSetWindowTitle ("Lesson 42: Multiple Viewports... 2003 NeHe Productions... Building Maze!");
198
                Reset();
199

    
200
        # // Check To Make Sure We Are Not Trapped (Nowhere Else To Move)
201
        if (((mx>(width-4) or tex_data[(((mx+2)+(width*my))*3)]==255)) and ((mx<2 or tex_data[(((mx-2)+(width*my))*3)]==255)) and
202
                ((my>(height-4) or tex_data[((mx+(width*(my+2)))*3)]==255)) and ((my<2 or tex_data[((mx+(width*(my-2)))*3)]==255))):
203
                while True:                                                                                                # // If We Are Trapped
204
                        mx = random.randint (0, (width/2) - 1) * 2                                # // Pick A New Random X Position
205
                        my = random.randint (0, (height/2) - 1) * 2                                # // Pick A New Random Y Position
206
                        if (tex_data[((mx+(width*my))*3)]==0):
207
                                break
208
                                # // Keep Picking A Random Position Until We Find
209
                                # // One That Has Already Been Tagged (Safe Starting Point)
210

    
211
        dir = random.randint (0,3)                                                                        # // Pick A Random Direction
212

    
213
        if ((dir==0) and (mx<=(width-4))):                                                                        # // If The Direction Is 0 (Right) And We Are Not At The Far Right
214
                if (tex_data[(((mx+2)+(width*my))*3)]==0):                                                # // And If The Room To The Right Has Not Already Been Visited
215
                        UpdateTex(mx+1,my);                                                                                        # // Update The Texture To Show Path Cut Out Between Rooms
216
                        mx+=2;                                                                                                                # // Move To The Right (Room To The Right)
217

    
218
        if ((dir==1) and (my<=(height-4))):                                                                        # // If The Direction Is 1 (Down) And We Are Not At The Bottom
219
                if (tex_data[((mx+(width*(my+2)))*3)]==0):                                                # // And If The Room Below Has Not Already Been Visited
220
                        UpdateTex(mx,my+1);                                                                                        # // Update The Texture To Show Path Cut Out Between Rooms
221
                        my+=2;                                                                                                                # // Move Down (Room Below)
222

    
223
        if ((dir==2) and (mx>=2)):                                                                                        # // If The Direction Is 2 (Left) And We Are Not At The Far Left
224
                if (tex_data[(((mx-2)+(width*my))*3)]==0):                                                # // And If The Room To The Left Has Not Already Been Visited
225
                        UpdateTex(mx-1,my);                                                                                        # // Update The Texture To Show Path Cut Out Between Rooms
226
                        mx-=2;                                                                                                                # // Move To The Left (Room To The Left)
227

    
228
        if ((dir==3) and (my>=2)):                                                                                        # // If The Direction Is 3 (Up) And We Are Not At The Top
229
                if (tex_data[((mx+(width*(my-2)))*3)]==0):                                                # // And If The Room Above Has Not Already Been Visited
230
                        UpdateTex(mx,my-1);                                                                                        # // Update The Texture To Show Path Cut Out Between Rooms
231
                        my-=2;                                                                                                                # // Move Up (Room Above)
232

    
233
        UpdateTex(mx,my);                                                                                                        # // Update Current Room
234
        return
235

    
236
last_milliseconds = 0
237
def DrawGLScene ():
238
        """ // Our Drawing Routine """
239
        global xrot, yrot, zrot
240
        global width, height, tex_data
241
        global quadric
242
        global r, g, b
243
        global last_milliseconds
244

    
245
        cur_milliseconds = glutGet (GLUT_ELAPSED_TIME)
246
        milliseconds = cur_milliseconds - last_milliseconds
247
        last_milliseconds = cur_milliseconds
248
        xrot+=milliseconds * .02;                                                                        # // Increase Rotation On The X-Axis
249
        yrot+=milliseconds * .03;                                                                        # // Increase Rotation On The Y-Axis
250
        zrot+=milliseconds * .015;                                                                        # // Increase Rotation On The Z-Axis
251

    
252
        Update ()
253

    
254
        # // Get Window Dimensions
255
        window_width = glutGet (GLUT_WINDOW_WIDTH)
256
        window_height = glutGet (GLUT_WINDOW_HEIGHT)
257

    
258
        # // Update Our Texture... This Is The Key To The Programs Speed... Much Faster Than Rebuilding The Texture Each Time
259
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, 
260
                GL_RGB, GL_UNSIGNED_BYTE, tex_data.tostring ());
261

    
262
        glClear (GL_COLOR_BUFFER_BIT);                                                                                # // Clear Screen
263

    
264
        for loop in xrange (4):                                                                                                # // Loop To Draw Our 4 Views
265
                glColor3ub(r[loop],g[loop],b[loop]);                                                        # // Assign Color To Current View
266

    
267
                if (loop==0):                                                                                                        # // If We Are Drawing The First Scene
268
                        # // Set The Viewport To The Top Left.  It Will Take Up Half The Screen Width And Height
269
                        glViewport (0, window_height/2, window_width/2, window_height/2);
270
                        glMatrixMode (GL_PROJECTION);                                                                # // Select The Projection Matrix
271
                        glLoadIdentity ();                                                                                        # // Reset The Projection Matrix
272
                        # // Set Up Ortho Mode To Fit 1/4 The Screen (Size Of A Viewport)
273
                        gluOrtho2D(0, window_width/2, window_height/2, 0);
274

    
275
                if (loop==1):                                                                                                        # // If We Are Drawing The Second Scene
276
                        # // Set The Viewport To The Top Right.  It Will Take Up Half The Screen Width And Height
277
                        glViewport (window_width/2, window_height/2, window_width/2, window_height/2);
278
                        glMatrixMode (GL_PROJECTION);                                                                # // Select The Projection Matrix
279
                        glLoadIdentity ();                                                                                        # // Reset The Projection Matrix
280
                        # // Set Up Perspective Mode To Fit 1/4 The Screen (Size Of A Viewport)
281
                        gluPerspective( 45.0, float (width) / float (height), 0.1, 500.0 ); 
282

    
283
                if (loop==2):                                                                                                        # // If We Are Drawing The Third Scene
284
                        # // Set The Viewport To The Bottom Right.  It Will Take Up Half The Screen Width And Height
285
                        glViewport (window_width/2, 0, window_width/2, window_height/2);
286
                        glMatrixMode (GL_PROJECTION);                                                                # // Select The Projection Matrix
287
                        glLoadIdentity ();                                                                                        # // Reset The Projection Matrix
288
                        # // Set Up Perspective Mode To Fit 1/4 The Screen (Size Of A Viewport)
289
                        gluPerspective( 45.0, float (width) / float(height), 0.1, 500.0 ); 
290

    
291
                if (loop==3):                                                                                                        # // If We Are Drawing The Fourth Scene
292
                        # // Set The Viewport To The Bottom Left.  It Will Take Up Half The Screen Width And Height
293
                        glViewport (0, 0, window_width/2, window_height/2);
294
                        glMatrixMode (GL_PROJECTION);                                                                # // Select The Projection Matrix
295
                        glLoadIdentity ();                                                                                        # // Reset The Projection Matrix
296
                        # // Set Up Perspective Mode To Fit 1/4 The Screen (Size Of A Viewport)
297
                        gluPerspective( 45.0, float(width) / float(height), 0.1, 500.0 ); 
298

    
299
                glMatrixMode (GL_MODELVIEW);                                                                        # // Select The Modelview Matrix
300
                glLoadIdentity ();                                                                                                # // Reset The Modelview Matrix
301

    
302
                glClear (GL_DEPTH_BUFFER_BIT);                                                                        # // Clear Depth Buffer
303

    
304
                if (loop==0):                                                                                                        # // Are We Drawing The First Image?  (Original Texture... Ortho)
305
                        glBegin(GL_QUADS);                                                                                        # // Begin Drawing A Single Quad
306

    
307
                        # // We Fill The Entire 1/4 Section With A Single Textured Quad.
308
                        glTexCoord2f(1.0, 0.0);         glVertex2i(window_width/2, 0              );
309
                        glTexCoord2f(0.0, 0.0);         glVertex2i(0,              0              );
310
                        glTexCoord2f(0.0, 1.0);         glVertex2i(0,              window_height/2);
311
                        glTexCoord2f(1.0, 1.0);         glVertex2i(window_width/2, window_height/2);
312

    
313
                        glEnd();                                                                                                        # // Done Drawing The Textured Quad
314

    
315
                if (loop==1):                                                                                                        # // Are We Drawing The Second Image?  (3D Texture Mapped Sphere... Perspective)
316
                        glTranslatef(0.0,0.0,-14.0);                                                                # // Move 14 Units Into The Screen
317

    
318
                        glRotatef(xrot,1.0,0.0,0.0);                                                                # // Rotate By xrot On The X-Axis
319
                        glRotatef(yrot,0.0,1.0,0.0);                                                                # // Rotate By yrot On The Y-Axis
320
                        glRotatef(zrot,0.0,0.0,1.0);                                                                # // Rotate By zrot On The Z-Axis
321

    
322
                        glEnable(GL_LIGHTING);                                                                                # // Enable Lighting
323
                        gluSphere(quadric,4.0,32,32);                                                                # // Draw A Sphere
324
                        glDisable(GL_LIGHTING);                                                                                # // Disable Lighting
325
                
326
                if (loop==2):                                                                                                        # // Are We Drawing The Third Image?  (Texture At An Angle... Perspective)
327
                        glTranslatef(0.0,0.0,-2.0);                                                                        # // Move 2 Units Into The Screen
328
                        glRotatef(-45.0,1.0,0.0,0.0);                                                                # // Tilt The Quad Below Back 45 Degrees.
329
                        glRotatef(zrot/1.5,0.0,0.0,1.0);                                                        # // Rotate By zrot/1.5 On The Z-Axis
330

    
331
                        glBegin(GL_QUADS);                                                                                        # // Begin Drawing A Single Quad
332

    
333
                        glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, 0.0);
334
                        glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, 0.0);
335
                        glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 0.0);
336
                        glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 0.0);
337

    
338
                        glEnd();                                                                                                        # // Done Drawing The Textured Quad
339

    
340

    
341
                if (loop==3):                                                                                                        # // Are We Drawing The Fourth Image?  (3D Texture Mapped Cylinder... Perspective)
342
                        glTranslatef(0.0,0.0,-7.0);                                                                        # // Move 7 Units Into The Screen
343
                        glRotatef(-xrot/2,1.0,0.0,0.0);                                                                # // Rotate By -xrot/2 On The X-Axis
344
                        glRotatef(-yrot/2,0.0,1.0,0.0);                                                                # // Rotate By -yrot/2 On The Y-Axis
345
                        glRotatef(-zrot/2,0.0,0.0,1.0);                                                                # // Rotate By -zrot/2 On The Z-Axis
346

    
347
                        glEnable(GL_LIGHTING);                                                                                # // Enable Lighting
348
                        glTranslatef(0.0,0.0,-2.0);                                                                        # // Translate -2 On The Z-Axis (To Rotate Cylinder Around The Center, Not An End)
349
                        gluCylinder(quadric,1.5,1.5,4.0,32,16);                                                # // Draw A Cylinder
350
                        glDisable(GL_LIGHTING);                                                                                # // Disable Lighting
351

    
352
        glutSwapBuffers()                                                                                                        # // Flush The GL Rendering Pipeline
353
        return True
354

    
355
# The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
356
def ReSizeGLScene(Width, Height):
357
        if Height == 0:                                                # Prevent A Divide By Zero If The Window Is Too Small 
358
                Height = 1
359

    
360
        glViewport(0, 0, Width, Height)                # Reset The Current Viewport And Perspective Transformation
361
        glMatrixMode(GL_PROJECTION)
362
        glLoadIdentity()
363
        # // field of view, aspect ratio, near and far
364
        # This will squash and stretch our objects as the window is resized.
365
        gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
366

    
367
        glMatrixMode(GL_MODELVIEW)
368
        glLoadIdentity()
369

    
370

    
371
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)  
372
def keyPressed(*args):
373
        global window
374

    
375
        # If escape is pressed, kill everything.
376
        if args[0] == ESCAPE:
377
                sys.exit ()
378
        # // Check To See If Spacebar Is Pressed
379
        if (args[0] == ' '):
380
                Reset();                                                                                                                # // If So, Call Reset And Start A New Maze
381

    
382
        return
383

    
384
def main():
385
        global window
386
        # pass arguments to init
387
        glutInit(sys.argv)
388

    
389
        # Select type of Display mode:   
390
        #  Double buffer 
391
        #  RGBA color
392
        # Alpha components supported 
393
        # Depth buffer
394
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
395
        
396
        glutInitWindowSize(1024, 768)
397
        
398
        # the window starts at the upper left corner of the screen 
399
        glutInitWindowPosition(0, 0)
400
        
401
        # Okay, like the C version we retain the window id to use when closing, but for those of you new
402
        # to Python, remember this assignment would make the variable local and not global
403
        # if it weren't for the global declaration at the start of main.
404
        window = glutCreateWindow("Lesson 42: Multiple Viewports... 2003 NeHe Productions... Building Maze!");
405

    
406
        # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
407
        # set the function pointer and invoke a function to actually register the callback, otherwise it
408
        # would be very much like the C version of the code.        
409
        glutDisplayFunc(DrawGLScene)
410
        
411
        # Uncomment this line to get full screen.
412
        #glutFullScreen()
413

    
414
        # When we are doing nothing, redraw the scene.
415
        glutIdleFunc(DrawGLScene)
416
        
417
        # Register the function called when our window is resized.
418
        glutReshapeFunc(ReSizeGLScene)
419
        
420
        # Register the function called when the keyboard is pressed.  
421
        # The call setup glutSpecialFunc () is needed to receive 
422
        # "keyboard function or directional keys." 
423
        glutKeyboardFunc(keyPressed)
424
        glutSpecialFunc(keyPressed)
425

    
426
        # We've told Glut the type of window we want, and we've told glut about
427
        # various functions that we want invoked (idle, resizing, keyboard events).
428
        # Glut has done the hard work of building up thw windows DC context and 
429
        # tying in a rendering context, so we are ready to start making immediate mode
430
        # GL calls.
431
        # Call to perform inital GL setup (the clear colors, enabling modes, and most releveant -
432
        # consturct the displays lists for the bitmap font.
433
        InitGL(640, 480)
434

    
435
        # Start Event Processing Engine        
436
        glutMainLoop()
437

    
438
# Print message to console, and kick off the main to get it rolling.
439
if __name__ == "__main__":
440
        print "Hit ESC key to quit."
441
        main()
442

    
443