Monday, November 05, 2007

First steps in OpenGL with Python

I have always wanted to sink my teeth in OpenGL (ever since the days of the first Voodoo graphics cards). It always seemed to be the best tool for graphics programming on the PC (but boy, how I still miss my A1200's blitter chip!).

My main problem has always been my penchant for scripting languages ever since I switched from the Amiga (AmigaE and 68k assembler) to the PC. Which can be translated as: I never learned C, or C++ for that matter.

Python's been my latest love for the last few years now. First as a simple scripting language, then some GUI stuff with Tkinter, later Django came along and now I feel confident enough to tackle OpenGL.

As I started reading the red book (the online version for OpenGL 1.1 can be found here), I tried to convert some of the examples found there to Python, using pyglet (I like its easy way of setting up screens and windows compared to pygame's).

Here's a translation of example 2-5 (found near here):

from pyglet import window
from pyglet.gl import *

def drawOneLine(x1,y1,x2,y2):
glBegin(GL_LINES)
glVertex2f ((x1),(y1))
glVertex2f ((x2),(y2))
glEnd()

def init():
glClearColor (0.0, 0.0, 0.0, 0.0)
glShadeModel (GL_FLAT)

def display():
i = 0

glClear (GL_COLOR_BUFFER_BIT)
# select white for all lines
glColor3f (1.0, 1.0, 1.0)

# in 1st row, 3 lines, each with a different stipple
glEnable (GL_LINE_STIPPLE)

glLineStipple (1, 0x0101) # dotted
drawOneLine (50.0, 125.0, 150.0, 125.0)
glLineStipple (1, 0x00FF) # dashed
drawOneLine (150.0, 125.0, 250.0, 125.0)
glLineStipple (1, 0x1C47) # dash/dot/dash
drawOneLine (250.0, 125.0, 350.0, 125.0)
# in 2nd row, 3 wide lines, each with different stipple
glLineWidth (5.0)
glLineStipple (1, 0x0101) # dotted
drawOneLine (50.0, 100.0, 150.0, 100.0)
glLineStipple (1, 0x00FF) # dashed
drawOneLine (150.0, 100.0, 250.0, 100.0)
glLineStipple (1, 0x1C47) # dash/dot/dash
drawOneLine (250.0, 100.0, 350.0, 100.0)
glLineWidth (1.0)

# in 3rd row, 6 lines, with dash/dot/dash stipple
# as part of a single connected line strip
glLineStipple (1, 0x1C47) # dash/dot/dash

glBegin (GL_LINE_STRIP)
for i in range(0, 7):
glVertex2f (50.0 + (i * 50.0), 75.0)
glEnd ()

# in 4th row, 6 independent lines with same stipple
for i in range(0, 5):
drawOneLine (50.0 + (i * 50.0), 50.0, 50.0 + ((i+1) * 50.0), 50.0)


# in 5th row, 1 line, with dash/dot/dash stipple
# and a stipple repeat factor of 5
glLineStipple (5, 0x1C47) # dash/dot/dash
drawOneLine (50.0, 25.0, 350.0, 25.0)

glDisable (GL_LINE_STIPPLE)

# glFlush ()
# glFlush() is unnecessary, as flip() is called on window (ie double buffered window).

win = window.Window()
init()

while not win.has_exit:
win.dispatch_events()
win.clear()
display()
win.flip()

No comments: