2

I'm trying to run moderngl in Colab. I installed it and ran a virtual display:

!sudo apt-get update --fix-missing && apt-get -qqq install x11-utils > /dev/null
!sudo apt-get update --fix-missing && apt-get -qqq install xvfb > /dev/null
!python3 -m pip install -U -qqq moderngl
!python3 -m pip install -U -qqq moderngl-window
!python3 -m pip install -U -qqq pyvirtualdisplay

from pyvirtualdisplay import Display
display = Display(visible=0, size=(960, 540)).start()

import moderngl
ctx = moderngl.create_standalone_context()
buf = ctx.buffer(b'Hello World!')  # allocated on the GPU
buf.read()

b'Hello World!'

It printed as expected, but when I run an example I see the error:

!python3 /content/moderngl/examples/basic_alpha_blending.py --window pyglet

2020-03-28 10:25:48,312 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.pyglet.Window
Traceback (most recent call last):
  File "/content/moderngl/examples/basic_alpha_blending.py", line 74, in <module>
    AlphaBlending.run()
  File "/content/moderngl/examples/ported/_example.py", line 21, in run
    mglw.run_window_config(cls)
  File "/usr/local/lib/python3.6/dist-packages/moderngl_window/__init__.py", line 185, in run_window_config
    cursor=show_cursor if show_cursor is not None else True,
  File "/usr/local/lib/python3.6/dist-packages/moderngl_window/context/pyglet/window.py", line 54, in __init__
    config=config,
  File "/usr/local/lib/python3.6/dist-packages/pyglet/window/xlib/__init__.py", line 165, in __init__
    super(XlibWindow, self).__init__(*args, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/pyglet/window/__init__.py", line 588, in __init__
    config = screen.get_best_config(config)
  File "/usr/local/lib/python3.6/dist-packages/pyglet/canvas/base.py", line 194, in get_best_config
    raise window.NoSuchConfigException()
pyglet.window.NoSuchConfigException

I also tried with another virtual display, but the result is the same:

!python3 -m pip install -U -qqq  xvfbwrapper
from xvfbwrapper import Xvfb
display = Xvfb(width=960, height=540).start()

pyglet.window.NoSuchConfigException
Joys
  • 311
  • 3
  • 15
  • Neither Xvfb nor Xephyr will provide you access to hardware-accelerated OpenGL, so what do you expect? – derhass Mar 28 '20 at 12:29
  • I know that `pyglet` [can work in Colab](https://colab.research.google.com/drive/12osEZByXOlGy8J-MSpkl3faObhzPGIrB). I'm trying to run `moderngl` in the same way. – Joys Mar 28 '20 at 12:38
  • 1
    But `moderngl`, as the name implies, requires a somewhat _modern_ GL implementation (3.3 core profile or better), the only way you might get this to work with your `virtualdisplay` stuff would be mesa in software rasterizer mode (llvmpipe,softpipe etc.). No hw-acceleration that way. – derhass Mar 28 '20 at 12:47
  • So, it's impossible to run `moderngl` on colab gpu? Are you sure that there is no other way? – Joys Mar 28 '20 at 12:57
  • 1
    I don;t know if there isn't any other way (I don't know much about Colab's architecture), I just know that you won't get a modern hw-accelerated GL context via _that_ way. As far as I see, google Colab uses googles compute enginge cloud infrastructure(?) which exposes nvidia GPUs, so there might be chances that you get some [headless GL via EGL](https://devblogs.nvidia.com/egl-eye-opengl-visualization-without-x-server/). – derhass Mar 28 '20 at 17:16
  • @derhass Do you know any alternative to `pyglet` that could do the same thing but does not require physical, or virtual display? – Joys Mar 29 '20 at 13:22
  • 1
    No. I'm not that familiar with python opengl pythons. I know that SDL can use egl, but not sure if it can use nvidia's specific way for headless GL. – derhass Mar 29 '20 at 13:33
  • @derhass We figured out Google Colab has a hw default display that can be reached with egl backend in moderngl. Check answer. – Grimmy Mar 31 '20 at 18:33

1 Answers1

3

In Google Colab you can use the EGL backend with moderngl 5.6.

ctx = moderngl.create_context(standalone=True, backend='egl')
print(ctx.info)

Output (partial):

{
    'GL_VENDOR': 'NVIDIA Corporation',
    'GL_RENDERER': 'Tesla P100-PCIE-16GB/PCIe/SSE2',
    'GL_VERSION': '3.3.0 NVIDIA 418.67',
    ....
}

moderngl creates an OpenGL 3.3 core context by default. If you need a higher context version you can pass in require=430 for OpenGL 4.3 for example. I don't know what these Tesla cards support.

There is a standard example in moderngl for this. It would be able to create the standard RGB triangle: https://github.com/moderngl/moderngl/blob/master/examples/headless_egl.py

The underlying library creating the contexts is glcontext (https://github.com/moderngl/glcontext).

if you are using the moderngl-window package you have to use the headless.Window because pyglet currently is not able to work in headless mode (It might in the future: https://github.com/pyglet/pyglet/issues/51)

If you run into issue make an issue in the moderngl project: https://github.com/moderngl/moderngl or invade their discord server.

Grimmy
  • 3,992
  • 22
  • 25
  • Can this example work with Anti-aliasing? https://github.com/moderngl/moderngl/blob/master/examples/headless_egl.py – Joys Apr 18 '20 at 13:08
  • 1
    @Joys Yes. Just create a framebuffer with samples. Be sure you cap the value to `ctx.info['MAX_SAMPLES']` or the framebuffer creation can fail. – Grimmy Apr 18 '20 at 16:18
  • I replaced `simple_framebuffer` from the example with this: ```fbo = ctx.framebuffer( color_attachments=ctx.texture((512, 512), 4, samples=2), depth_attachment=ctx.depth_texture((512, 512), samples=2) )``` and it doesn't create a triangle. `samples=0` works fine. `MAX_SAMPLES=32` – Joys Apr 18 '20 at 16:29
  • 1
    @Joys ahh right. I think you cannot read pixels from multisample fbos or textures directly. Need to blit or render it to another fbo without multisampling first. – Grimmy Apr 19 '20 at 04:26
  • Can you show how to do this? I created a [question](https://stackoverflow.com/questions/61302400/how-to-enable-anti-aliasing-in-moderngl-egl-backend) for that. – Joys Apr 19 '20 at 09:51