PyOpenGL 无头渲染

Posted

技术标签:

【中文标题】PyOpenGL 无头渲染【英文标题】:PyOpenGL headless rendering 【发布时间】:2019-06-26 07:03:24 【问题描述】:

我正在使用 PyOpenGL+glfw 进行渲染。

尝试在无头机器(例如服务器)上执行相同操作时,glfw.init() 失败:

glfw.GLFWError: (65544) b'X11: The DISPLAY environment variable is missing'
Fatal Python error: Couldn't create autoTLSkey mapping
Aborted (core dumped)

我找到了一些关于无头渲染的信息,但仅限于直接使用OpenGL而不是通过python时

编辑:我知道 glfw 可能无法支持它。没有 glfw 的解决方案,但有其他东西也可以工作......

【问题讨论】:

【参考方案1】:

解决方案是使用 xvfb 作为虚拟帧缓冲区。

问题是Ubuntu中使用apt-get install libglfw3 libglfw3-dev安装的glfw老旧不适合,所以需要从源码编译。

这是一个完整的 docker 示例:

docker run --name headless_test -ti ubuntu /bin/bash

# Inside the ubuntu shell:
apt update && apt install -y python3 python3-pip git python-opengl xvfb xorg-dev cmake
pip3 install pyopengl glfw
mkdir /projects
git clone https://github.com/glfw/glfw.git /projects/glfw
cd /projects/glfw
cmake -DBUILD_SHARED_LIBS=ON .
make
export PYGLFW_LIBRARY=/projects/glfw/src/libglfw.so
xvfb-run python3 some_script_using_pyopengl_and_glfw.py

这里是使用它的 PyOpenGL 代码的基础:

from OpenGL.GL import *
from OpenGL.GLU import *
import glfw

glfw.init()
# Set window hint NOT visible
glfw.window_hint(glfw.VISIBLE, False)
# Create a windowed mode window and its OpenGL context
window = glfw.create_window(DISPLAY_WIDTH, DISPLAY_HEIGHT, "hidden window", None, None)
# Make the window's context current
glfw.make_context_current(window)

【讨论】:

【参考方案2】:

GLFW 根本不支持无头 OpenGL。

https://www.glfw.org/docs/latest/context.html#context_offscreen

GLFW 不支持创建没有关联窗口的上下文。

这不是一个不寻常的限制,问题在于创建 OpenGL 上下文的常规方法是使用 X 服务器。现在有使用 EGL 的替代方案,这是相对较新的。您将需要为 Python 使用 EGL 包装器。

见:OpenGL without X.org in linux

【讨论】:

【参考方案3】:

如果您想在没有显示环境的情况下在 linux(例如 x 服务器)上使用 OpenGL,最好的方法是使用 EGL。 EGL 所做的是将 OpenGL 上下文管理与窗口系统分开,因此它允许您在没有显示窗口的情况下创建上下文。

如果您使用的是 Nvidia 显卡,您必须安装专有驱动程序才能使用它。除了驱动程序之外,还有一个名为 GLVND 的库,这是一个包含您的应用需要链接的 EGL 的库。

请参考以下链接了解如何使用EGL

Pro Tip: Linking OpenGL for Server-Side Rendering

EGL Eye: OpenGL Visualization without an X Serve

PS。如果您的 EGL api 找不到任何设备,则可能是您链接了错误的 EGL 库,EGL 库必须与驱动程序匹配。

【讨论】:

以上是关于PyOpenGL 无头渲染的主要内容,如果未能解决你的问题,请参考以下文章

在python中没有可见窗口的OpenGL渲染视图

是否可以使用 LWJGL 以无头模式渲染到 FBO?

使用 python opengl (PyOpenGL) 创建几何着色器失败

(Python OpenGL)Uniform变量 PyOpenGL

Python OpenGL第一个三角形(Pyopengl)

尝试渲染三角形时,PyOpenGL 中的应用程序崩溃