I'm using PyOpenGL+glfw for rendering.
When trying to do the same on a headless machine (e.g a server) glfw.init() fails:
glfw.GLFWError: (65544) b'X11: The DISPLAY environment variable is missing'
Fatal Python error: Couldn't create autoTLSkey mapping
Aborted (core dumped)
I found some information about headless rendering, but only when using OpenGL directly and not through python
EDIT: I understand that maybe glfw isn't able to support it. A solution without glfw, but with something else might also work...
The solution is to use xvfb for a virtual framebuffer.
The problem is that the glfw that is installed in Ubuntu using apt-get install libglfw3 libglfw3-dev is old and unfit, so we need to compile it from source.
Here is a full working docker example:
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
And here is the base of PyOpenGL code to use it:
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)
GLFW does not support headless OpenGL at all.
https://www.glfw.org/docs/latest/context.html#context_offscreen
GLFW doesn't support creating contexts without an associated window.
This isn’t an unusual limitation, the problem is that the normal way to create an OpenGL context is by using the X server. There are now alternatives using EGL, which is relatively new. You will need to use an EGL wrapper for Python.
See: OpenGL without X.org in linux
If you want to use OpenGL without a display environment on linux(eg. x server) the best approach is to use EGL. what EGL does is it separate OpenGL context management from windowing system, so it let you create context without a displaying window.
If you are using Nvidia graphics card, you have to install proprietary driver in order to use it. along with the driver there is a library called GLVND this is a library which include EGL your app need to linked against.
Please refer to following links to learn how to use EGL:
Pro Tip: Linking OpenGL for Server-Side Rendering
EGL Eye: OpenGL Visualization without an X Serve
PS. If your EGL api cannot find any devices, you probably linked wrong EGL library, the EGL library must match the driver.
Related
I'm working on a simple OpenGL project and I'm new to C++. I've been slowly adding features to a very simple primitive 3D "engine" and I've worked to make sure it compiles cross-platform.
I have a make file that I run for OSX and Linux (Ubuntu) and for Windows I have a Visual Studio solution file modified to work with the directory structure of the project.
Each time I make changes I make sure to compile and test on each platform, and its been all great until I added support for load models using Assimp. More specifically, loading models was fine but loading textures is what caused the issue- or rather, reading the texture file name.
What's peculiar is that this code actually runs and compiles properly on all the platforms I'm targeting: Linux (Ubuntu), OSX, and Windows 10- except that in Ubuntu (and only in Ubuntu) the aiString object from Assimp does not seem to be returning the name of the texture file.
This is the code snippet I've narrowed it down to that really displays my problem:
aiString path;
mat->GetTexture(aiTextureType_DIFFUSE, 0, &path);
fprintf(stderr, "Loading texture '%s'...\n", path.data);
std::string full_path = _model_load_path + std::string(path.C_Str());
fprintf(stderr, "Full path: '%s'\n", full_path.c_str());
This is the output on OSX and Windows 10:
Loading texture 'glass_dif.png'...
Full path: 'resources/meshes/nanosuit/glass_dif.png'
This is the output on Ubuntu:
Loading texture ''...
Full path: 'resources/meshes/nanosuit/'
Sure enough the textures are loaded and applied to the model correct in OSX and Windows 10, but not in Ubuntu. Everything else seems to work, including loading the model (it just shows up as black colored since the shader can't sample the texture color).
The only think I can think of is the version I have installed of libassimp-dev, which is 4, versus 5 on OSX. But I'm a skeptical v4 and all before couldn't load textures. Could it be how I'm compiling it?
What should I start looking into to troubleshoot this? I'm using gcc on Ubuntu and clang on OSX.
Alright, so trying to do due diligence I decided to rule out the libassimp-dev version first, since that's really the only thing that's different. I was skeptical this was this problem, because how else did the previous versions of libassimp-dev work on Linux?
Well, I don't know but that was what the problem was. I was avoiding doing that because version 5 on Ubuntu was not available for my version of Linux: https://packages.ubuntu.com/search?keywords=libassimp-dev
With the help of a friend I was able to force install version 5 by temporarily adding the "focal" package repository, install the relevant packages from that new repository and then remove that repository so Ubuntu doesn't upgrade every other package on the system.
Steps:
1.) Append the following config to /etc/apt/sources.list:
# FIXME: remove me after installing libassimp5 and libassimp-dev
deb http://mirrors.kernel.org/ubuntu focal main universe
2.) Update the package registry and install the relevant packages (and their dependencies):
sudo apt-get update
sudo apt-get install libassimp-dev libassimp5
(I also had an issue where I had to run the recommended fix install command or similar after running this)
3.) After that has installed successfully, then remove the lines added to /etc/apt/sources.list
Make sure you do not run sudo apt-get upgrade now, as it will try to upgrade all the packages on your system to that new version of Ubuntu, which may have unforeseen consequences.
4.) Update your package registry again (to remove traces of the new repository)
sudo apt-get update
Recompiling my project after that worked- the string correctly displayed the material file path and the application loaded textures and applied them to the model correctly.
Credit for those steps and instructions to Dominic Barnes: https://stackoverflow.com/users/188702/dominic-barnes
I am running scripts on WSL that requires graphical output from mayavi but I am getting the following error:
GL version 2.1 with the gpu_shader4 extension is not supported by your graphics driver but is required for the new OpenGL rendering backend. Please update your OpenGL driver. If you are using Mesa please make sure you have version 10.6.5 or later and make sure your driver in Mesa supports OpenGL 3.2.
My current OpenGL version is OpenGL version string: 1.4 (2.1 Mesa 19.2.0-devel (git-cdf42f5eaa))
I tried updating the OpenGL drivers via various solutions including:
export DISPLAY=:0
export DISPLAY=localhost:0
export LIBGL_ALWAYS_INDIRECT=1
Added ubuntu-x-swat into repository then upgrading via (ie. sudo apt-get upgrade)
export MESA_GL_VERSION_OVERRIDE=4.5; export MESA_GLSL_VERSION_OVERRIDE=150;
... but none of these solutions work!
Any kind souls got an idea how I can fix this issue?
export LIBGL_ALWAYS_INDIRECT=0
^this worked for me. Im using wsl2 ubuntu-20.04 and running X-server with multiple windows, uncheck native opengl and check disable access control
This maybe because your have use the indirect rendering mode.
What's the output when you execute the command glxinfo -B, if the 'direct rendering' is no, you can set it to yes by execute the command 'LIBGL_ALWAYS_INDIRECT=0'.
Then execute the command 'glxinfo -B' again and observe the version of opengl.
FIRST, it's not the issue that Qt CANNOT found target .so, qt can found it, but it failed to load it and produce not logs... on both terminal and gdb. It seems that qmake/make is using wrong library but I have only one qt installed in my cross compile environment that generated by make install.
I'm struggling for cross compiling qt5.10 for raspberry pi on Windows. I'm using msys2, gnutoolchains's raspberry chains.
The problem here is the examples built by the compiling process runs almost no problem, I only needs to add a qt.conf to fix the prefix override by msys2 and it can run and display something on my pi.
But when it comes to qt creator, or qmake out of cross compiling, it starts to show me:
This application failed to start because it could not find or load the Qt platform plugin "xcb"
Here are two problems, first, the platform plugin should not be xcb since I'm running without x, cross compiled version will use eglfs by default.
And, second, even I specific platform plugin to eglfs, it still tells me it cannot load eglfs.
I'm putting two version of programs in the same place.
qt5pi/examples/opengl/2dpainting $ ls
2dpainting glwidget.cpp helper.h widget.cpp window.h
2dpainting.pro glwidget.h main.cpp widget.h
2dpaint_my helper.cpp qt.conf window.cpp
2dpaint_my is compiled by qmake && make and 2dpainting is by qt's cross compiling process uses the same source.
I'm suspecting qt is adding something during it's cross compiling, but I'm not sure how it happened. Qt'wiki about raspberry pi contains nothing about this issue.
update
It looks even wired to me. I copied a running example from its folder to another and it also crash, things look like this..
pi#raspberrypi:/usr/local/qt5pi/examples/qt_test $ cp ../opengl/2dpainting/2dpainting .
pi#raspberrypi:/usr/local/qt5pi/examples/qt_test $ ./2dpainting
This application failed to start because it could not find or load the Qt platform plugin "xcb"
in "".
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen,vnc, webgl, xcb.
Reinstalling the application may fix this problem.
Aborted
pi#raspberrypi:/usr/local/qt5pi/examples/qt_test $ ../opengl/2dpainting/2dpainting
qt.qpa.egldeviceintegration: EGL device integration plugin keys: ("eglfs_brcm","eglfs_emu")
qt.qpa.egldeviceintegration: EGL device integration plugin keys (sorted): ("eglfs_brcm", "eglfs_emu")
qt.qpa.egldeviceintegration: Trying to load device EGL integration "eglfs_brcm"
qt.qpa.egldeviceintegration: Using EGL device integration "eglfs_brcm"
qt.qpa.input: Initializing tslib plugin "TsLib" ""
qt.qpa.input: tslib device is "/dev/input/event0"
I'm not sure, but it seems that the this step on qt'wiki introduced some qt5.7 files into lib folder.
sudo apt-get update
sudo apt-get build-dep qt4-x11
sudo apt-get build-dep libqt5gui5
sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0
The problem is, qt's examples, when it on their own folders, can magically find (maybe qmake install did something?) and use the correct *.so, and so it works without problem.
But, when compiling with qmake, the program won't find the correct libraries so, newer libq*.so with older libQtXXXXX.so lead to this probleam. And that's how it uses a different qt version with compile.
And, that indicates the optional 00- in step 13 from the wiki:
[on RPi] Update the device to let the linker find the Qt libs:
echo /usr/local/qt5pi/lib | sudo tee /etc/ld.so.conf.d/qt5pi.conf
sudo ldconfig
If you're facing issues with running the example, try to use 00-qt5pi.conf instead of qt5pi.conf, to introduce proper order.
should be taken even the examples run without problem.
I have a unix binary file built with QT and OpenGL which I'm trying to execute on linux-64. It is a simple visual program that shows 2d and 3d graphics.
I have installed all necessary dependencies such as QT and openGL libraries.
However, I have stuck with the following error trying to execute the binary
QXcbIntegration: Cannot create platform OpenGL context, neither GLX
nor EGL are enabled
However, the binary eventually runs but with some missing features such as 3D graphics.
my setup includes: virtual linux-64 using virtualBox, Vagrant, x-11 forwarding, and a Mac machine.
Eventually I realised that OpenGL 3.3 wouldn't work easily on virtual machines .. yet. I had to boot from ubuntu usb and work from there by installing latest mesa 3d package.
This shows a similar issue and the developer in the comment said our 3D support is not very clean in Linux guests, hence the warnings. You can give a try to VMware.
After some time trying to get some opengl working on a particular locked down linux box, I ended up going back to Qt Creator 2.5.2 .
http://download.qt.io/archive/qtcreator/2.5/
http://download.qt.io/archive/qtcreator/2.5/qt-creator-linux-x86_64-opensource-2.5.2.bin
After getting it on the linux box...
chmod u+x *.bin
./qt-creator-linux-x86_64-opensource-2.5.2.bin
And after a short installer, Qt Creator is working!
Basically QtQuick is a requirement in any Qt Creator built after 2.5 (aka Qt 5.x) and QtQuick NEEDS opengl libraries and support.
Hope that helps.
I see this problem when executing Qt App, I was executing in dash prompt. (Ubuntu 16.04 has dash by default). I changed to bash prompt and rebuilt my QT App. This error is gone.
To configure bash I used below command.
sudo dpkg-reconfigure dash
My core problem is that I need to run multiple OpenGL executables concurrently on an EC2 GPU instance; I'm observing non-deterministic segfaults when trying to do this. The same program runs fine (with concurrency) on my Macbook Pro.
The application works as follows:
python script launches multiple worker executables (i.e. concurrent subprocess.call() calls from a multiprocessing.pool.ThreadPool threadpool). The python script provides a JSON file as worker input and the worker writes JSON to a file.
Each worker is a C++ program that does some headless image rendering in OpenGL using fragment shaders and a render-to-texture pipeline. I've tried using both Glut and GLX rendering contexts.
I'm confident that neither the python script nor the C++ workers have major bugs because the whole application runs fine when:
running a single worker on the EC2 GPU instance
running one or more workers on my Macbook (OSX 10.7.4)
The specific error I observe is that one or more of the workers will segfault inside an OpenGL call (e.g. glTexSubImage2D, glDrawElements, etc) after a few minutes of execution. Sometimes I've seen failures in the GLX context setup stage (e.g. glXCreateNewContext or glXChooseFBConfig). If I start more workers (i.e. higher concurrency), I see errors sooner. If I start fewer workers, it can take 15-30 minutes before a crash.
I believe that I'm having some sort of OpenGL context or driver issue. I've tried setting up my context using both GLUT and GLX and neither seems to help.
My procedure for creating the EC2 instance is very close to the instructions given here: http://hpc.nomad-labs.com/archives/139 . The specific packages I install are:
sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libegl1-mesa libglu1-mesa-dev mesa-utils mesa-utils-extra llvm-dev imagemagick libboost-all-dev python2.6 python-imaging python-matplotlib python-numpy python-scipy firefox clang python-setuptools python-scipy libatlas-dev ccache libpng12-dev libmagick++-dev glew-utils xvfb x11-utils qiv xinit
On both OSX and Linux, the C++ worker links: GL GLU glut pthread m X11.
I generated my xorg.conf using:
$ nvidia-xconfig -a --use-display-device=None --virtual=1280x1024
Before running my program, I run:
$ startx &; export DISPLAY=:0
I've tried some non-nvidia drivers, but they don't seem to help either.
I've also consulted the FAQ on parallel processing with OpenGL: http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html
The guide suggests that multithreaded GLX on Ubuntu doesn't work (and I've confirmed that personally.. :) but it seems that multiprocess GLX should be feasible and stable.
Does anybody have any ideas as to
why the OpenGL/GLX calls might be failing? Am I indeed seeing a driver issue? It seems like Mac GPU drivers have some sort of 'magic feature' aiding concurrent OpenGL usage. Are there any Ubuntu/Linux drivers with that same feature?
are there best practices for running multiple OpenGL executables concurrently on an EC2 GPU instance (or any headless Ubuntu/Linux machine for that matter)? Can anybody point me towards Open Source software that does this?
.. 1 year later..
I've found that a lot of times the gpu won't be enable on headless machines.
try to vnc in first and see if that helps.