Alternative to PyOpenGL

I've created an alternative to PyOpenGL that I am now releasing in time for PyWeek. I basically wanted something leaner and meaner than PyOpenGL: that doesn't use ctypes (which is nice for most things but slow for OpenGL), that doesn't call glGetError() after every call, and especially, does not use entry hooks, so it won't be a pain to use with py2exe and friends.

Bad news is you have to compile it yourself. Well, that, and there's probably a brazillion bugs.

http://www.aerojockey.com/files/tegl-001.zip
http://www.aerojockey.com/files/tegl-001.tar.gz

BSD license. I'll try to give a little support to anyone who uses it for PyWeek.

(log in to comment)

Comments

Oooh - might take a look. I was planning on using Pyglet if I do a solo entry, as that seems to be a pretty neat standalone package.
Note that pyglet doesn't invoke glGetError after every call if you run python with -O (or set the pyglet debug option off). You're still stuck with the overall slowness of ctypes calls (though using things like pyglet.graphics to reduce that gives big benefits). Having glGetError run after every call during OpenGL development is essential to sanity, in my books :)

Have you looked at rabbyt? It uses pyrex to interface to OpenGL and has a really nice set of functionality in a lovely Pythonesque API.

I've been programming OpenGL for 5 years or so--up until a few months ago entirely with PyOpenGL and C extensions--and I don't think I've gotten more than half a dozen OpenGL errors. Each time it was flagging an error that was caused earlier in C, so I would see stuff like glLoadIdentity raising an exception thanks to something some other function did. Talk about misleading.

None of the other OpenGL solutions really appealed to me. They all seem to heap layers upon a library that really ought to be laid bare and used as is.

But the situation you've outlined is exactly why we invoke glGetError after every call when in debugging mode. You've got a much better chance of discovering where the error came from. Well, in pyglet anyway ;)
TEGL looks quite nice. Here's a simple setup.py to compile it under Linux:
from distutils.core import setup, Extension

setup(name="stuff", version="1.0",
      ext_modules=[
        Extension("tegl", ["tegl.c"], extra_compile_args=['-Wall'],
            libraries=['GL'], library_dirs=["/usr/X11R6/lib"]),
        Extension("teglu", ["teglu.c"], extra_compile_args=['-Wall'],
            libraries=['GLU'], library_dirs=["/usr/X11R6/lib"]),
      ])
Unfortunately I ran into a problem compiling teglu.c:
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -O2 -Wall
 -Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c teglu.c
 -o build/temp.linux-i686-2.5/teglu.o -Wall
teglu.c: In function ‘tegluUnProject4’:
teglu.c:701: error: incompatible type for argument 8 of ‘gluUnProject4’
teglu.c:701: error: incompatible type for argument 9 of ‘gluUnProject4’
teglu.c:701: error: too few arguments to function ‘gluUnProject4’
error: command 'gcc' failed with exit status 1
Skipping that (and just using pyglet's gluPerspective) I modified pyglet's examples/opengl.py to use tegl for the gl calls. Unfortunately nothing displayed :)

I suspect there's some issue how I built / passed the vertex (etc) arrays. I just changed the code from:

vertices = (GLfloat * len(vertices))(*vertices)
normals = (GLfloat * len(normals))(*normals)
indices = (GLuint * len(indices))(*indices)
to
vertices = array.array('f', vertices)
normals = array.array('f', normals)
indices = array.array('I', indices)
(amongst other minor changes like the args to glLightfv etc).
gluUnProject is defined as follows for me:
GLAPI GLint GLAPIENTRY gluUnProject4 (
   GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW,
   const GLdouble *model, const GLdouble *proj, const GLint *view,
   GLdouble nearVal, GLdouble farVal,
   GLdouble* objX, GLdouble* objY, GLdouble*objZ, GLdouble* objW);
Though when I change maketegl.py to match this signature I get:
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -O2 -Wall
 -Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c teglu.c
 -o build/temp.linux-i686-2.5/teglu.o -Wall
teglu.c: In function ‘tegluUnProject4’:
teglu.c:707: warning: passing argument 7 of ‘gluUnProject4’ from
 incompatible pointer type
It links, and I can replace the single pyglet.gl call in the opengl.py script, but I still don't see the torus I expect to see :)

Thanks. I need to remember to retest all last minute changes, no matter how trivial. :)

First thing to check is whether it built the tegl extension wih static libraries. It probably shouldn't, but I have run into that problem once. I can't see anything obviously wrong with glVertexPointer and friends. I'll go have a look at it when I can.

Uploaded a new version of Tegl, with some fixes and (hopefully) support of glShaderSource:

http://www.aerojockey.com/files/tegl-002.zip
http://www.aerojockey.com/files/tegl-002.tar.gz

According to contest rules, I will now leave this alone until PyWeek starts.

I recommend panda3d for any serous 3d python coding.
as an alternative to an alternative to PyOpenGL, I've got a windows installer for PyOpenGL 2.0 for python 2.5. It's missing numeric support and tcl/tk support, but in most cases should be a drop in replacement for PyOpenGL 3.0.
The core advantage is py2exe support, Like tegl. It has a fix for the "version" file loading so it's py2exe ready out of the box.
You can get it here
I reccommend ModernGL.


- modern opengl exposed for python programmers

- no annoying functions that require ctypes

- Only a few calls to make things happen

- It has documentation.

- Open source, feel free to contribute to it on github.