我正在尝试通过带有X转发的SSH运行OpenGL + GLUT程序。程序提供以下错误,然后是seg错误。
Xlib:显示“localhost:10.0”时缺少扩展名“NV-GLX”。
这似乎是因为我的“服务器”计算机有一个nvidia卡,然后告诉我的客户端计算机使用这些nvidia特定的渲染功能,当客户端没有nvidia卡时。我当然搜索了这一点,看到很多其他人也遇到过类似的问题;但是,我真正看到的唯一解决方案是(https://superuser.com/questions/196838/opengl-program-not-work-with-x-forwarding)尝试
$ export LIBGL_ALWAYS_INDIRECT=1 or use any nonzero value
哪个不起作用。我不关心硬件加速/维护ssh连接的良好性能。我只想让窗口呈现。
答案 0 :(得分:4)
首先,使用X11,服务器是产生显示输出的计算机。客户端是在远程计算机上运行的程序,它利用服务器的显示服务。
您是正确的,因为您的客户端(在远程计算机上运行)在具有NVidia GPU的计算机上执行,因此您收到此消息。然而,不是GPU正在制造麻烦,而是它的驱动因素。 Linux OpenGL ABI(应用程序二进制接口)的一个主要缺点是驱动程序还负责提供系统的libGL.so
;如果你考虑一下,这是一个相当错误的构思规范,因为它主动阻止为不同供应商的多个GPU安装驱动程序。 (由于它的ICD OpenGL驱动程序模型,Windows从未出现过这个问题。)
无论如何,你的NVidia GPU libGL.so
在连接到没有运行NVidia驱动程序的远程X服务器时会看到某些服务器扩展不可用,因此拒绝工作。
那么你能做些什么呢?
好吧,你可以安装Mesa3D和NVidia驱动程序;大多数Linux发行版都有适当的机制(Gentoo eselect,Debian替代方案),可以安装API提供程序的多个变体,并选择一个默认变体。
安装Mesa3D后,您可以使用LD_PRELOAD
环境变量预加载Mesa3D libGL.so
(它将位于/usr/lib64/opengl/xorg-x11/lib/libGL.so
之类的某个位置 - 使用Linux发行版的软件包管理器工具查找,找到它;或者find /usr -iname 'libGL.so*'
并选择一个,哪个目录不包含nvidia
)而不是系统默认libGL.so
。
另一种可行的方法是使用lxc
容器,使用Mesa3D作为默认OpenGL提供程序创建辅助系统安装,并且当通过SSH登录系统时,您将被放入这样的lxc
容器(请注意,给定正确的配置,完全可以使容器仅仅覆盖在基本系统上,其中仍然可以突破裸系统。)
Mesa3D libGL.so
将很乐意在远程X会话上工作。但请记住,已经为OpenGL-2.1指定了完全间接操作,但没有进一步指定(即对于OpenGL-3的许多功能以及之后没有定义GLX操作码);然而,许多扩展(也使它成为OpenGL-3核心)定义了GLX操作码,所以如果你依赖于间接OpenGL,你可能会回退到那些。
使用扩展和现代OpenGL功能时也要小心。必须在运行时使用glXGetProcAddress加载的所有函数都很容易无法使用。您收到的段错误表示您可能正在调用函数指针(通过GLEW或类似函数加载),这根本不可用,因此您将取消引用导致崩溃的无效指针。请务必检查您调用的所有功能和扩展名是否确实存在!