PyOpenGL Information

Introduction

If you are completely new to PyOpenGL, start here! I will attempt to describe only the basics--if you already have some background, you might want to learn by the tutorials.

Installing

There are several ways to install PyOpenGL.

You need to have Python installed first, obviously.

The simplest and most direct way is to find PyOpenGL on SourceForge, download an installer and follow the directions. That's pretty self-explanatory.

My personal recommendation is to use easy_install--a free program which allows easy, automatic access to practically every Python module imaginable. Google: "easy_install", install it, then go to a command line and type "easy_install PyOpenGL", and PyOpenGL will be installed. Almost any other module can be installed using this method.

Generally, I use combinations of PyGame, PyOpenGL, psyco, and Numpy for all of my programs. You can easily install these at this time with this same method.

Theory

I'll try to keep this short. Long-winded tutorials annoy me too.

OpenGL in Python is really PyOpenGL. The terms are used interchangably, but remember that "OpenGL" doesn't work with Python--only its binding, "PyOpenGL" does. That's an extra syllable, though, so when people talk about "OpenGL" in "Python", think "PyOpenGL" with "Python".

3D objects are really made up of many 3D polygons, each specified by three or more points.

Starting really basically, in your program you will need to have a way to get user input and draw. These can be specified in any number of ways, but I like functions--see my basecode. The surface OpenGL draws on is the display surface (pygame.display.set_mode()). Assuming this function has already been called, we'll continue to describe the basics of OpenGL.

The first thing to know is that OpenGL uses a coordinate system. It has three axes, x, y, and z, where x is left/right, y is up/down, and z is front/back. Points are specified in 3D space and plotted on these axes. The center of your computer's screen is (0,0,0), the origin.

This origin can be moved--and hence any objects' positions on the coordinate system can be moved. This is accomplished by rotating and/or translating. These are specified by glRotate() and glTranslate() respectively.

If a point is at (0,0,0), translating the coordinate system 5 units into the screen (that's the z-axis, remember), and then drawing the point will cause that point to appear to be 5 units inside the screen, instead of 0. If the coordinate system is then translated 3 units to the right, then the same point drawn again, there will be two points, one at (0,0,-5), and the other at (3,0,-5). The example code folllows (and can be found in PyOpenGL Tutorial 1):

glTranslatef(0,0,-5) #Translate 5 units into the screen.
glBegin(GL_POINTS) #Begin drawing points
glVertex3f(0,0,0) #Draw a point at the origin (now 5 units inside the screen)
glEnd() #Done drawing points for now

glTranslatef(3,0,0) #Translate 3 units right
glBegin(GL_POINTS) #Begin drawing points
glVertex3f(0,0,0) #Draw a point at the origin (now 5 units inside the screen and 3 to the right)
glEnd() #Done drawing points

Polygons can be specified in a similar way. The best way is just to play around with it.

You are now ready to try some tutorials.

FAQ Regarding OpenGL Useage

Q. Translating and rotating x,y,z seem to be wrong! z translates in/out and y translates up!
A. That's what they're supposed to do. If you you're familiar with 3D math graphs, you know that z is normally up and x and y define a horizontal plane. Not so in OpenGL. y is up/down, z is in/out and x is left/right.

Q. What order should I draw things in?
A. That's up to you. OpenGL draws everything--regardless of the order they are specified in. If polygon A completely overlaps polygon B, no matter which is specified first, polygon A will always be seen--that is unless GL_DEPTH_TEST is disabled. Normally, you will have that on, though.

Q. Texturing in the latest version of PyOpenGL is broken.
A. My code is broken in the latest version of PyOpenGL. There is an easy way to fix it:
The old way of generating and selecting textures looked like:

#Generate PyOpenGL Texture
textures = glGenTextures(2)
#Load the image file
Surface = pygame.image.load(path)
#Convert it to load any alpha channel
Surface.convert_alpha()
#Convert to PyOpenGL Data
Data = pygame.image.tostring(Surface, "RGBA", 1)
#Select our Texture Object
glBindTexture(GL_TEXTURE_2D, textures[0])
#Load the Data into the Texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, Surface.get_width(), Surface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Data )
#Define some Parameters for this Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
This no longer works. To fix it, textures must be a simple object:
#Generate PyOpenGL Texture
texture = glGenTextures(1)
#Load the image file
Surface = pygame.image.load(path)
#Convert it to load any alpha channel
Surface.convert_alpha()
#Convert to PyOpenGL Data
Data = pygame.image.tostring(Surface, "RGBA", 1)
#Select our Texture Object
glBindTexture(GL_TEXTURE_2D, texture)
#Load the Data into the Texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, Surface.get_width(), Surface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Data )
#Define some Parameters for this Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

Do you have a question which you feel belongs here? Tell me.