mirror of
https://github.com/dyne/FreeJ.git
synced 2026-02-07 05:19:26 +01:00
273 lines
11 KiB
Python
273 lines
11 KiB
Python
#!/usr/bin/env python
|
|
|
|
#
|
|
# This code was created by Richard Campbell '99 (ported to Python/PyOpenGL by John Ferguson 2000)
|
|
#
|
|
# The port was based on the lesson5 tutorial module by Tony Colston (tonetheman@hotmail.com).
|
|
#
|
|
# If you've found this code useful, please let me know (email John Ferguson at hakuin@voicenet.com).
|
|
#
|
|
# See original source and C based tutorial at http:#nehe.gamedev.net
|
|
#
|
|
# Note:
|
|
# -----
|
|
# Now, I assume you've read the prior tutorial notes and know the deal here. The one major, new requirement
|
|
# is to have a working version of PIL (Python Image Library) on your machine.
|
|
#
|
|
# General Users:
|
|
# --------------
|
|
# I think to use textures at all you need Nunmeric Python, I tried without it and BAM Python didn't "like" the texture API.
|
|
#
|
|
# Win32 Users:
|
|
# ------------
|
|
# Well, here's the install I used to get it working:
|
|
# [1] py152.exe - include the TCL install!
|
|
# [2] PyOpenGL.EXE - probably the latest, the Vaults notes should give you a clue.
|
|
# [3] Distutils-0.9.win32.exe for step #4
|
|
# [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).
|
|
#
|
|
# Win98 users (yes Win98, I have Mandrake on the other partition okay?), you need to the Tcl bin directory in your PATH, not PYTHONPATH,
|
|
# just the DOS PATH.
|
|
#
|
|
# BTW, since this is Python make sure you use tabs or spaces to indent, I had numerous problems since I
|
|
# was using editors that were not sensitive to Python.
|
|
#
|
|
from OpenGL.GL import *
|
|
from OpenGL.GLUT import *
|
|
from OpenGL.GLU import *
|
|
from Image import *
|
|
|
|
# Some api in the chain is translating the keystrokes to this octal string
|
|
# so instead of saying: ESCAPE = 27, we use the following.
|
|
ESCAPE = '\033'
|
|
|
|
# Number of the glut window.
|
|
window = 0
|
|
|
|
# Rotations for cube.
|
|
xrot = yrot = zrot = 0.0
|
|
|
|
texture = 0
|
|
|
|
def LoadTextures():
|
|
#global texture
|
|
#image = open("NeHe.bmp")
|
|
|
|
#ix = image.size[0]
|
|
#iy = image.size[1]
|
|
#image = image.tostring("raw", "RGBX", 0, -1)
|
|
ix = 512
|
|
iy = 512
|
|
|
|
# Create Texture
|
|
# There does not seem to be support for this call or the version of PyOGL I have is broken.
|
|
#glGenTextures(1, texture)
|
|
#glBindTexture(GL_TEXTURE_2D, texture) # 2d texture (x and y size)
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
|
|
glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, None)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
|
#glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
|
|
|
|
# A general OpenGL initialization function. Sets all of the initial parameters.
|
|
def InitGL(Width, Height): # We call this right after our OpenGL window is created.
|
|
LoadTextures()
|
|
glEnable(GL_TEXTURE_2D)
|
|
glClearColor(0.0, 0.0, 0.0, 0.0) # This Will Clear The Background Color To Black
|
|
glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
|
|
glDepthFunc(GL_LESS) # The Type Of Depth Test To Do
|
|
glEnable(GL_DEPTH_TEST) # Enables Depth Testing
|
|
glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading
|
|
|
|
glMatrixMode(GL_PROJECTION)
|
|
glLoadIdentity() # Reset The Projection Matrix
|
|
# Calculate The Aspect Ratio Of The Window
|
|
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
|
|
|
|
glMatrixMode(GL_MODELVIEW)
|
|
|
|
# The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
|
|
def ReSizeGLScene(Width, Height):
|
|
if Height == 0: # Prevent A Divide By Zero If The Window Is Too Small
|
|
Height = 1
|
|
|
|
glViewport(0, 0, Width, Height) # Reset The Current Viewport And Perspective Transformation
|
|
glMatrixMode(GL_PROJECTION)
|
|
glLoadIdentity()
|
|
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
|
|
glMatrixMode(GL_MODELVIEW)
|
|
|
|
def DrawPlane(i):
|
|
global xrot, yrot, zrot, texture
|
|
glPushMatrix()
|
|
#glRotatef(xrot+i*0.8,1.0,0.0,0.0) # Rotate The Cube On It's X Axis
|
|
glRotatef(yrot+i*0.8,0.0,1.0,0.0) # Rotate The Cube On It's Y Axis
|
|
#glRotatef(zrot+i*0.8,0.0,0.0,1.0) # Rotate The Cube On It's Z Axis
|
|
glBegin(GL_QUADS) # Start Drawing The Cube
|
|
|
|
# Front Face (note that the texture's corners have to match the quad's corners)
|
|
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 0.0) # Bottom Left Of The Texture and Quad
|
|
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 0.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 0.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0) # Top Left Of The Texture and Quad
|
|
|
|
# Back Face
|
|
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 0.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 0.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 0.0) # Top Left Of The Texture and Quad
|
|
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 0.0) # Bottom Left Of The Texture and Quad
|
|
|
|
glEnd(); # Done Drawing The Cube
|
|
glPopMatrix()
|
|
|
|
|
|
|
|
def DrawCube(i):
|
|
global xrot, yrot, zrot, texture
|
|
glPushMatrix()
|
|
glRotatef(xrot+i*0.8,1.0,0.0,0.0) # Rotate The Cube On It's X Axis
|
|
glRotatef(yrot+i*0.8,0.0,1.0,0.0) # Rotate The Cube On It's Y Axis
|
|
glRotatef(zrot+i*0.8,0.0,0.0,1.0) # Rotate The Cube On It's Z Axis
|
|
glBegin(GL_QUADS) # Start Drawing The Cube
|
|
|
|
# Front Face (note that the texture's corners have to match the quad's corners)
|
|
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
|
|
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) # Top Left Of The Texture and Quad
|
|
|
|
# Back Face
|
|
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
|
|
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) # Bottom Left Of The Texture and Quad
|
|
|
|
# Top Face
|
|
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
|
|
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0) # Bottom Left Of The Texture and Quad
|
|
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
|
|
|
|
# Bottom Face
|
|
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0) # Top Left Of The Texture and Quad
|
|
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
|
|
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
|
|
|
|
# Right face
|
|
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0) # Top Left Of The Texture and Quad
|
|
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0) # Bottom Left Of The Texture and Quad
|
|
|
|
# Left Face
|
|
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0) # Bottom Left Of The Texture and Quad
|
|
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0) # Bottom Right Of The Texture and Quad
|
|
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0) # Top Right Of The Texture and Quad
|
|
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0) # Top Left Of The Texture and Quad
|
|
|
|
glEnd(); # Done Drawing The Cube
|
|
glPopMatrix()
|
|
|
|
|
|
|
|
# The main drawing function.
|
|
def DrawGLScene():
|
|
global xrot, yrot, zrot, texture
|
|
|
|
data = Screen.get_surface_buffer()
|
|
glEnable(GL_BLEND)
|
|
glDrawPixels (Screen.w, Screen.h, GL_BGRA, GL_UNSIGNED_BYTE,
|
|
str(data))
|
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 0, 0, Screen.w, Screen.h, 0)
|
|
glColor3f (1.0, 1.0, 0.0)
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Clear The Screen And The Depth Buffer
|
|
glLoadIdentity() # Reset The View
|
|
glTranslatef(0.0,0.0,-3.0) # Move Into The Screen
|
|
|
|
|
|
# Note there does not seem to be support for this call.
|
|
#glBindTexture(GL_TEXTURE_2D,texture) # Rotate The Pyramid On It's Y Axis
|
|
glBlendFunc( GL_ONE, GL_ONE )
|
|
glColor3f (0.5,0.5,0.5)
|
|
glDisable(GL_DEPTH_TEST)
|
|
for i in range(10):
|
|
glEnable(GL_DEPTH_TEST)
|
|
DrawPlane(i)
|
|
#glEnable(GL_DEPTH_TEST)
|
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE )
|
|
glColor3f (1.0, 1.0, 1.0)
|
|
xrot = xrot + 0.2 # X rotation
|
|
yrot = yrot + 0.2 # Y rotation
|
|
zrot = zrot + 0.2 # Z rotation
|
|
# since this is double buffered, swap the buffers to display what just got drawn.
|
|
glutSwapBuffers()
|
|
|
|
def close_system(*args):
|
|
print "close",args
|
|
return False
|
|
|
|
# The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
|
|
def keyPressed(*args):
|
|
# If escape is pressed, kill everything.
|
|
if args[0] == ESCAPE:
|
|
glutDestroyWindow(window)
|
|
|
|
def main():
|
|
global window
|
|
# For now we just pass glutInit one empty argument. I wasn't sure what should or could be passed in (tuple, list, ...)
|
|
# Once I find out the right stuff based on reading the PyOpenGL source, I'll address this.
|
|
glutInit("")
|
|
|
|
# Select type of Display mode:
|
|
# Double buffer
|
|
# RGBA color
|
|
# Alpha components supported
|
|
# Depth buffer
|
|
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
|
|
|
|
# get a 640 x 480 window
|
|
glutInitWindowSize(640, 480)
|
|
|
|
# the window starts at the upper left corner of the screen
|
|
glutInitWindowPosition(0, 0)
|
|
|
|
# Okay, like the C version we retain the window id to use when closing, but for those of you new
|
|
# to Python (like myself), remember this assignment would make the variable local and not global
|
|
# if it weren't for the global declaration at the start of main.
|
|
window = glutCreateWindow("freejgl")
|
|
|
|
# Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
|
|
# set the function pointer and invoke a function to actually register the callback, otherwise it
|
|
# would be very much like the C version of the code.
|
|
glutDisplayFunc(DrawGLScene)
|
|
#glutDisplayFunc()
|
|
|
|
# Uncomment this line to get full screen.
|
|
# glutFullScreen()
|
|
|
|
# When we are doing nothing, redraw the scene.
|
|
glutIdleFunc(DrawGLScene)
|
|
|
|
# Register the function called when our window is resized.
|
|
glutReshapeFunc(ReSizeGLScene)
|
|
|
|
# Register the function called when the keyboard is pressed.
|
|
glutKeyboardFunc(keyPressed)
|
|
|
|
# Initialize our window.
|
|
InitGL(640, 480)
|
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS)
|
|
glutCloseFunc(close_system)
|
|
# Start Event Processing Engine
|
|
glutMainLoop()
|
|
|
|
import threading
|
|
th = threading.Thread(target = main , name = "glut")
|
|
th.start()
|