Statistics
| Revision:

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

History | View | Annotate | Download (7.5 kB)

1
#!
2

    
3
# This is statement is required by the build system to query build info
4
if __name__ == '__build__':
5
        raise Exception
6

    
7
import string
8
__version__ = string.split('$Revision: 1.1.1.1 $')[1]
9
__date__ = string.join(string.split('$Date: 2007/02/15 19:25:21 $')[1:3], ' ')
10
__author__ = 'Tarn Weisner Burton <twburton@users.sourceforge.net>'
11

    
12
#
13
# Ported to PyOpenGL 2.0 by Tarn Weisner Burton 10May2001
14
#
15
# This code was created by Richard Campbell '99 (ported to Python/PyOpenGL by John Ferguson 2000)
16
#
17
# The port was based on the PyOpenGL tutorial module: dots.py  
18
#
19
# If you've found this code useful, please let me know (email John Ferguson at hakuin@voicenet.com).
20
#
21
# See original source and C based tutorial at http://nehe.gamedev.net
22
#
23
# Note:
24
# -----
25
# This code is not a good example of Python and using OO techniques.  It is a simple and direct
26
# exposition of how to use the Open GL API in Python via the PyOpenGL package.  It also uses GLUT,
27
# which in my opinion is a high quality library in that it makes my work simpler.  Due to using
28
# these APIs, this code is more like a C program using function based programming (which Python
29
# is in fact based upon, note the use of closures and lambda) than a "good" OO program.
30
#
31
# To run this code get and install OpenGL, GLUT, PyOpenGL (see http://www.python.org), and NumPy.
32
# Installing PyNumeric means having a C compiler that is configured properly, or so I found.  For 
33
# Win32 this assumes VC++, I poked through the setup.py for Numeric, and chased through disutils code
34
# and noticed what seemed to be hard coded preferences for VC++ in the case of a Win32 OS.  However,
35
# I am new to Python and know little about disutils, so I may just be not using it right.
36
#
37
# NumPy is not a hard requirement, as I am led to believe (based on skimming PyOpenGL sources) that
38
# PyOpenGL could run without it. However preformance may be impacted since NumPy provides an efficient
39
# multi-dimensional array type and a linear algebra library.
40
#
41
# BTW, since this is Python make sure you use tabs or spaces to indent, I had numerous problems since I 
42
# was using editors that were not sensitive to Python.
43
#
44
from OpenGL.GL import *
45
from OpenGL.GLUT import *
46
from OpenGL.GLU import *
47
import sys
48

    
49
# Some api in the chain is translating the keystrokes to this octal string
50
# so instead of saying: ESCAPE = 27, we use the following.
51
ESCAPE = '\033'
52

    
53
# Number of the glut window.
54
window = 0
55

    
56
# Rotation angle for the triangle. 
57
rtri = 0.0
58

    
59
# Rotation angle for the quadrilateral.
60
rquad = 0.0
61

    
62
# A general OpenGL initialization function.  Sets all of the initial parameters. 
63
def InitGL(Width, Height):                                # We call this right after our OpenGL window is created.
64
    glClearColor(0.0, 0.0, 0.0, 0.0)        # This Will Clear The Background Color To Black
65
    glClearDepth(1.0)                                        # Enables Clearing Of The Depth Buffer
66
    glDepthFunc(GL_LESS)                                # The Type Of Depth Test To Do
67
    glEnable(GL_DEPTH_TEST)                                # Enables Depth Testing
68
    glShadeModel(GL_SMOOTH)                                # Enables Smooth Color Shading
69
        
70
    glMatrixMode(GL_PROJECTION)
71
    glLoadIdentity()                                        # Reset The Projection Matrix
72
                                                                                # Calculate The Aspect Ratio Of The Window
73
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
74

    
75
    glMatrixMode(GL_MODELVIEW)
76

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

    
82
    glViewport(0, 0, Width, Height)                # Reset The Current Viewport And Perspective Transformation
83
    glMatrixMode(GL_PROJECTION)
84
    glLoadIdentity()
85
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
86
    glMatrixMode(GL_MODELVIEW)
87

    
88
# The main drawing function. 
89
def DrawGLScene():
90
        global rtri, rquad
91
        
92
        # Clear The Screen And The Depth Buffer
93
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
94
        glLoadIdentity()                                        # Reset The View 
95

    
96
        # Move Left 1.5 units and into the screen 6.0 units.
97
        glTranslatef(-1.5, 0.0, -6.0)
98

    
99
        # We have smooth color mode on, this will blend across the vertices.
100
        # Draw a triangle rotated on the Y axis. 
101
        glRotatef(rtri, 0.0, 1.0, 0.0)      # Rotate
102
        glBegin(GL_POLYGON)                 # Start drawing a polygon
103
        glColor3f(1.0, 0.0, 0.0)            # Red
104
        glVertex3f(0.0, 1.0, 0.0)           # Top
105
        glColor3f(0.0, 1.0, 0.0)            # Green
106
        glVertex3f(1.0, -1.0, 0.0)          # Bottom Right
107
        glColor3f(0.0, 0.0, 1.0)            # Blue
108
        glVertex3f(-1.0, -1.0, 0.0)         # Bottom Left
109
        glEnd()                             # We are done with the polygon
110

    
111
        # We are "undoing" the rotation so that we may rotate the quad on its own axis.
112
        # We also "undo" the prior translate.  This could also have been done using the
113
        # matrix stack.
114
        glLoadIdentity()
115
        
116
        # Move Right 1.5 units and into the screen 6.0 units.
117
        glTranslatef(1.5, 0.0, -6.0)
118

    
119
        # Draw a square (quadrilateral) rotated on the X axis.
120
        glRotatef(rquad, 1.0, 0.0, 0.0)                # Rotate 
121
        glColor3f(0.3, 0.5, 1.0)            # Bluish shade
122
        glBegin(GL_QUADS)                   # Start drawing a 4 sided polygon
123
        glVertex3f(-1.0, 1.0, 0.0)          # Top Left
124
        glVertex3f(1.0, 1.0, 0.0)           # Top Right
125
        glVertex3f(1.0, -1.0, 0.0)          # Bottom Right
126
        glVertex3f(-1.0, -1.0, 0.0)         # Bottom Left
127
        glEnd()                             # We are done with the polygon
128

    
129
        # What values to use?  Well, if you have a FAST machine and a FAST 3D Card, then
130
        # large values make an unpleasant display with flickering and tearing.  I found that
131
        # smaller values work better, but this was based on my experience.
132
        rtri  = rtri + 1.0                  # Increase The Rotation Variable For The Triangle
133
        rquad = rquad - 1.0                 # Decrease The Rotation Variable For The Quad
134

    
135

    
136
        #  since this is double buffered, swap the buffers to display what just got drawn. 
137
        glutSwapBuffers()
138

    
139
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)  
140
def keyPressed(*args):
141
        # If escape is pressed, kill everything.
142
    if args[0] == ESCAPE:
143
            sys.exit()
144

    
145
def main():
146
        global window
147
        glutInit(sys.argv)
148

    
149
        # Select type of Display mode:   
150
        #  Double buffer 
151
        #  RGBA color
152
        # Alpha components supported 
153
        # Depth buffer
154
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
155
        
156
        # get a 640 x 480 window 
157
        glutInitWindowSize(640, 480)
158
        
159
        # the window starts at the upper left corner of the screen 
160
        glutInitWindowPosition(0, 0)
161
        
162
        # Okay, like the C version we retain the window id to use when closing, but for those of you new
163
        # to Python (like myself), remember this assignment would make the variable local and not global
164
        # if it weren't for the global declaration at the start of main.
165
        window = glutCreateWindow("Jeff Molofee's GL Code Tutorial ... NeHe '99")
166

    
167
           # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
168
        # set the function pointer and invoke a function to actually register the callback, otherwise it
169
        # would be very much like the C version of the code.        
170
        glutDisplayFunc(DrawGLScene)
171
        
172
        # Uncomment this line to get full screen.
173
        # glutFullScreen()
174

    
175
        # When we are doing nothing, redraw the scene.
176
        glutIdleFunc(DrawGLScene)
177
        
178
        # Register the function called when our window is resized.
179
        glutReshapeFunc(ReSizeGLScene)
180
        
181
        # Register the function called when the keyboard is pressed.  
182
        glutKeyboardFunc(keyPressed)
183

    
184
        # Initialize our window. 
185
        InitGL(640, 480)
186

    
187
        # Start Event Processing Engine        
188
        glutMainLoop()
189

    
190
# Print message to console, and kick off the main to get it rolling.
191
print "Hit ESC key to quit."
192
main()
193