Statistics
| Revision:

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

History | View | Annotate | Download (8.8 kB)

1 1 equemene
#! /usr/bin/env python
2 1 equemene
# -*- coding: utf8 -*-
3 1 equemene
"""Port of NeHe Lesson 16 by Ivan Izuver <izuver@users.sourceforge.net>"""
4 1 equemene
from OpenGL.GL import *
5 1 equemene
from OpenGL.GLUT import *
6 1 equemene
from OpenGL.GLU import *
7 1 equemene
import sys
8 1 equemene
from Image import *
9 1 equemene
10 1 equemene
# Some api in the chain is translating the keystrokes to this octal string
11 1 equemene
# so instead of saying: ESCAPE = 27, we use the following.
12 1 equemene
ESCAPE = '\033'
13 1 equemene
14 1 equemene
# Number of the glut window.
15 1 equemene
window = 0
16 1 equemene
17 1 equemene
# Rotations for cube.
18 1 equemene
xrot = yrot = zrot = 0.0
19 1 equemene
20 1 equemene
fogColor=(0.5, 0.5, 0.5, 1.0) # fog color
21 1 equemene
22 1 equemene
texture = 0
23 1 equemene
24 1 equemene
def LoadTextures():
25 1 equemene
    #global texture
26 1 equemene
    image = open("NeHe.bmp")
27 1 equemene
28 1 equemene
    ix = image.size[0]
29 1 equemene
    iy = image.size[1]
30 1 equemene
    image = image.tostring("raw", "RGBX", 0, -1)
31 1 equemene
32 1 equemene
    # Create Texture
33 1 equemene
    glBindTexture(GL_TEXTURE_2D, glGenTextures(1))   # 2d texture (x and y size)
34 1 equemene
35 1 equemene
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
36 1 equemene
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
37 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
38 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
39 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
40 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
41 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
42 1 equemene
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
43 1 equemene
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
44 1 equemene
45 1 equemene
# A general OpenGL initialization function.  Sets all of the initial parameters.
46 1 equemene
def InitGL(Width, Height):                # We call this right after our OpenGL window is created.
47 1 equemene
    LoadTextures()
48 1 equemene
    glEnable(GL_TEXTURE_2D)
49 1 equemene
    glClearColor(0.0, 0.0, 0.0, 0.0)    # This Will Clear The Background Color To Black
50 1 equemene
    glClearDepth(1.0)                    # Enables Clearing Of The Depth Buffer
51 1 equemene
    glDepthFunc(GL_LESS)                # The Type Of Depth Test To Do
52 1 equemene
    glEnable(GL_DEPTH_TEST)                # Enables Depth Testing
53 1 equemene
    glShadeModel(GL_SMOOTH)                # Enables Smooth Color Shading
54 1 equemene
55 1 equemene
    glMatrixMode(GL_PROJECTION)
56 1 equemene
    glLoadIdentity()                    # Reset The Projection Matrix
57 1 equemene
                                        # Calculate The Aspect Ratio Of The Window
58 1 equemene
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
59 1 equemene
60 1 equemene
    glMatrixMode(GL_MODELVIEW)
61 1 equemene
62 1 equemene
# The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
63 1 equemene
def ReSizeGLScene(Width, Height):
64 1 equemene
    if Height == 0:                        # Prevent A Divide By Zero If The Window Is Too Small
65 1 equemene
        Height = 1
66 1 equemene
67 1 equemene
    glViewport(0, 0, Width, Height)        # Reset The Current Viewport And Perspective Transformation
68 1 equemene
    glMatrixMode(GL_PROJECTION)
69 1 equemene
    glLoadIdentity()
70 1 equemene
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
71 1 equemene
    glMatrixMode(GL_MODELVIEW)
72 1 equemene
73 1 equemene
# The main drawing function.
74 1 equemene
def DrawGLScene():
75 1 equemene
    global xrot, yrot, zrot, texture
76 1 equemene
77 1 equemene
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)    # Clear The Screen And The Depth Buffer
78 1 equemene
    glLoadIdentity()                    # Reset The View
79 1 equemene
80 1 equemene
    glClearColor(0.5,0.5,0.5,1.0)
81 1 equemene
82 1 equemene
    glEnable(GL_FOG)                         # Enable fog
83 1 equemene
84 1 equemene
    glFogi(GL_FOG_MODE, GL_LINEAR)           # Set fog settings
85 1 equemene
86 1 equemene
    glFogfv(GL_FOG_COLOR, fogColor);         # Set fog color
87 1 equemene
88 1 equemene
    glFogf(GL_FOG_DENSITY, 0.15);            # Set fog density
89 1 equemene
90 1 equemene
    glHint(GL_FOG_HINT, GL_DONT_CARE);       # Set Hint
91 1 equemene
92 1 equemene
    glFogf(GL_FOG_START, 1.0);               # Fog start
93 1 equemene
94 1 equemene
    glFogf(GL_FOG_END, 5.0);                 # Fog end
95 1 equemene
96 1 equemene
97 1 equemene
    glTranslatef(0.0,0.0,-5.0)            # Move Into The Screen
98 1 equemene
99 1 equemene
    glRotatef(xrot,1.0,0.0,0.0)            # Rotate The Cube On It's X Axis
100 1 equemene
    glRotatef(yrot,0.0,1.0,0.0)            # Rotate The Cube On It's Y Axis
101 1 equemene
    glRotatef(zrot,0.0,0.0,1.0)            # Rotate The Cube On It's Z Axis
102 1 equemene
103 1 equemene
    # Note there does not seem to be support for this call.
104 1 equemene
    #glBindTexture(GL_TEXTURE_2D,texture)    # Rotate The Pyramid On It's Y Axis
105 1 equemene
106 1 equemene
    glBegin(GL_QUADS)                # Start Drawing The Cube
107 1 equemene
108 1 equemene
    # Front Face (note that the texture's corners have to match the quad's corners)
109 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)    # Bottom Left Of The Texture and Quad
110 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)    # Bottom Right Of The Texture and Quad
111 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0)    # Top Right Of The Texture and Quad
112 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0)    # Top Left Of The Texture and Quad
113 1 equemene
114 1 equemene
    # Back Face
115 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)    # Bottom Right Of The Texture and Quad
116 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)    # Top Right Of The Texture and Quad
117 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)    # Top Left Of The Texture and Quad
118 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)    # Bottom Left Of The Texture and Quad
119 1 equemene
120 1 equemene
    # Top Face
121 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)    # Top Left Of The Texture and Quad
122 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0,  1.0)    # Bottom Left Of The Texture and Quad
123 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0,  1.0)    # Bottom Right Of The Texture and Quad
124 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)    # Top Right Of The Texture and Quad
125 1 equemene
126 1 equemene
    # Bottom Face
127 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0)    # Top Right Of The Texture and Quad
128 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0)    # Top Left Of The Texture and Quad
129 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)    # Bottom Left Of The Texture and Quad
130 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)    # Bottom Right Of The Texture and Quad
131 1 equemene
132 1 equemene
    # Right face
133 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0)    # Bottom Right Of The Texture and Quad
134 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0)    # Top Right Of The Texture and Quad
135 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f( 1.0,  1.0,  1.0)    # Top Left Of The Texture and Quad
136 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0,  1.0)    # Bottom Left Of The Texture and Quad
137 1 equemene
138 1 equemene
    # Left Face
139 1 equemene
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0)    # Bottom Left Of The Texture and Quad
140 1 equemene
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0,  1.0)    # Bottom Right Of The Texture and Quad
141 1 equemene
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0)    # Top Right Of The Texture and Quad
142 1 equemene
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0)    # Top Left Of The Texture and Quad
143 1 equemene
144 1 equemene
    glEnd();                # Done Drawing The Cube
145 1 equemene
146 1 equemene
    xrot  = xrot + 0.2                # X rotation
147 1 equemene
    yrot = yrot + 0.2                 # Y rotation
148 1 equemene
    zrot = zrot + 0.2                 # Z rotation
149 1 equemene
150 1 equemene
    #  since this is double buffered, swap the buffers to display what just got drawn.
151 1 equemene
    glutSwapBuffers()
152 1 equemene
153 1 equemene
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
154 1 equemene
def keyPressed(*args):
155 1 equemene
    # If escape is pressed, kill everything.
156 1 equemene
    if args[0] == ESCAPE:
157 1 equemene
        sys.exit()
158 1 equemene
159 1 equemene
def main():
160 1 equemene
    global window
161 1 equemene
    glutInit(sys.argv)
162 1 equemene
163 1 equemene
    # Select type of Display mode:
164 1 equemene
    #  Double buffer
165 1 equemene
    #  RGBA color
166 1 equemene
    # Alpha components supported
167 1 equemene
    # Depth buffer
168 1 equemene
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
169 1 equemene
170 1 equemene
    # get a 640 x 480 window
171 1 equemene
    glutInitWindowSize(640, 480)
172 1 equemene
173 1 equemene
    # the window starts at the upper left corner of the screen
174 1 equemene
    glutInitWindowPosition(0, 0)
175 1 equemene
176 1 equemene
    # Okay, like the C version we retain the window id to use when closing, but for those of you new
177 1 equemene
    # to Python (like myself), remember this assignment would make the variable local and not global
178 1 equemene
    # if it weren't for the global declaration at the start of main.
179 1 equemene
    window = glutCreateWindow("Fog by RISC")
180 1 equemene
181 1 equemene
       # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
182 1 equemene
    # set the function pointer and invoke a function to actually register the callback, otherwise it
183 1 equemene
    # would be very much like the C version of the code.
184 1 equemene
    glutDisplayFunc(DrawGLScene)
185 1 equemene
186 1 equemene
    # Uncomment this line to get full screen.
187 1 equemene
    # glutFullScreen()
188 1 equemene
189 1 equemene
    # When we are doing nothing, redraw the scene.
190 1 equemene
    glutIdleFunc(DrawGLScene)
191 1 equemene
192 1 equemene
    # Register the function called when our window is resized.
193 1 equemene
    glutReshapeFunc(ReSizeGLScene)
194 1 equemene
195 1 equemene
    # Register the function called when the keyboard is pressed.
196 1 equemene
    glutKeyboardFunc(keyPressed)
197 1 equemene
198 1 equemene
    # Initialize our window.
199 1 equemene
    InitGL(640, 480)
200 1 equemene
201 1 equemene
    # Start Event Processing Engine
202 1 equemene
    glutMainLoop()
203 1 equemene
204 1 equemene
# Print message to console, and kick off the main to get it rolling.
205 1 equemene
if __name__ == "__main__":
206 1 equemene
    print "Hit ESC key to quit."
207 1 equemene
    main()