Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the xlib and OpenGL modules together with python?

I know it is possible to use Xlib and OpenGL together, with GLX (I've done it myself in C).

The problem is, how do I do this in python? The OpenGL module has GLX functionality [documentation], but it appears to be using C types and I have no idea (nor, it appears does anyone else) how to use the xlib types with PyOpenGL.

I also tried using ctypes and loading libraries directly, but ran into (obvious) problems when trying to use the C macros defined in the Xlib header file, like DefaultRootWindow.

Am I missing something obvious, like PyOpenGL having its own xlib implementation, or is this just not possible without some (compiled) module-writing?

like image 748
Michael Rawson Avatar asked Feb 18 '13 09:02

Michael Rawson


1 Answers

You can't use python-xlib types directly with python-opengl. But you can use the fact that a window XID is just a number to use python-opengl on the same window.

from Xlib import X, display
from OpenGL import GL, GLX
from OpenGL.raw._GLX import struct__XDisplay
from ctypes import *

# some python-xlib code...
pd = display.Display()
pw = pd.screen().root.create_window(50, 50, 200, 200, 0,
                                    pd.screen().root_depth,
                                    X.InputOutput, X.CopyFromParent)
pw.map()

# ensure that the XID is valid on the server
pd.sync()

# get the window XID
xid = pw.__resource__()

# a separate ctypes Display object for OpenGL.GLX
xlib = cdll.LoadLibrary('libX11.so')
xlib.XOpenDisplay.argtypes = [c_char_p]
xlib.XOpenDisplay.restype = POINTER(struct__XDisplay)
d = xlib.XOpenDisplay("")

# use GLX to create an OpenGL context on the same window XID
elements = c_int()
configs = GLX.glXChooseFBConfig(d, 0, None, byref(elements))
w = GLX.glXCreateWindow(d, configs[0], c_ulong(xid), None)
context = GLX.glXCreateNewContext(d, configs[0], GLX.GLX_RGBA_TYPE, None, True)
GLX.glXMakeContextCurrent(d, w, w, context)

# some python-opengl code....
GL.glShadeModel(GL.GL_FLAT)
GL.glClearColor(0.5, 0.5, 0.5, 1.0)

GL.glViewport(0, 0, 200, 200)
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0)

GL.glClear(GL.GL_COLOR_BUFFER_BIT)
GL.glColor3f(1.0, 1.0, 0.0)
GL.glRectf(-0.8, -0.8, 0.8, 0.8)

# assume we got a double buffered fbConfig and show what we drew
GLX.glXSwapBuffers(d, w)

# a terrible end to a terrible piece of code...
raw_input()

This is really horrible though. (Error checking and choosing a sensible fbConfig omitted for clarity)

It really should be possible to do all the necessary xlib calls with ctypes though. Pyglet, for example, manages somehow, but I'm not sure what specific problem you ran into.

like image 171
jturney Avatar answered Sep 21 '22 12:09

jturney