如何在Python中同时使用xlib和OpenGL模块?

10 投票
1 回答
2187 浏览
提问于 2025-04-17 16:14

我知道可以把 Xlib 和 OpenGL 一起使用,方法是通过 GLX(我自己在 C 语言中做过)。

问题是,我该怎么在 Python 中做到这一点呢?OpenGL 模块有 GLX 的功能 [文档],但看起来它使用的是 C 语言的类型,而我对此一无所知(似乎其他人也不太清楚)怎么把 xlib 类型 和 PyOpenGL 一起使用。

我还尝试过使用 ctypes 直接加载库,但在尝试使用 Xlib 头文件中定义的 C 宏时遇到了(显而易见的)问题,比如 DefaultRootWindow

我是不是漏掉了什么明显的东西,比如 PyOpenGL 有自己的 xlib 实现,还是说没有一些(编译过的)模块就不可能做到这一点?

1 个回答

5

你不能直接把python-xlib的类型和python-opengl一起用。不过,你可以利用窗口的XID其实就是一个数字这一点,在同一个窗口上使用python-opengl。

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()

不过,这样做真的很糟糕。(为了清晰起见,省略了错误检查和选择合适的fbConfig的部分)

其实,应该可以通过ctypes来完成所有必要的xlib调用。比如,Pyglet就能做到这一点,但我不太确定你遇到了什么具体问题。

撰写回答