File: headless_ubuntu_18_server.rst

package info (click to toggle)
python-moderngl 5.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,700 kB
  • sloc: python: 15,758; cpp: 14,665; makefile: 14
file content (130 lines) | stat: -rw-r--r-- 3,198 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

Headless on Ubuntu 18 Server
============================

Dependencies
------------

Headless rendering can be achieved with EGL or X11.
We'll cover both cases.

Starting with fresh ubuntu 18 server install we need to install required
packages::

    sudo apt-install python3-pip mesa-utils libegl1-mesa xvfb

This should install mesa an diagnostic tools if needed later.

* ``mesa-utils`` installs libgl1-mesa and tools like ``glxinfo```
* ``libegl1-mesa`` is optional if using EGL instead of X11

Creating a context
------------------

The libraries we are going to interact with has the following locations::

    /usr/lib/x86_64-linux-gnu/libGL.so.1
    /usr/lib/x86_64-linux-gnu/libX11.so.6
    /usr/lib/x86_64-linux-gnu/libEGL.so.1

Double check that you have these libraries installed. ModernGL
through the glcontext library will use ``ctype.find_library``
to locate the latest installed version.

Before we can create a context we to run a virtual display::

    export DISPLAY=:99.0
    Xvfb :99 -screen 0 640x480x24 &

Now we can create a context with x11 or egl:

.. code::

    # X11
    import moderngl
    ctx = moderngl.create_context(
        standalone=True,
        # These are OPTIONAL if you want to load a specific version
        libgl='libGL.so.1',
        libx11='libX11.so.6',
    )

    # EGL
    import moderngl
    ctx = moderngl.create_context(
        standalone=True,
        backend='egl',
        # These are OPTIONAL if you want to load a specific version
        libgl='libGL.so.1',
        libegl='libEGL.so.1',
    )


Running an example
------------------

Checking that everything works can be done with a basic triangle example.

Install dependencies::

    pip3 install moderngl numpy pyrr pillow

The following example renders a triangle and writes
it to a png file so we can verify the contents.

.. image:: output.png

.. code:: python

    import moderngl
    import numpy as np
    from PIL import Image
    from pyrr import Matrix44

    # -------------------
    # CREATE CONTEXT HERE
    # -------------------

    prog = ctx.program(vertex_shader="""
        #version 330
        uniform mat4 model;
        in vec2 in_vert;
        in vec3 in_color;
        out vec3 color;
        void main() {
            gl_Position = model * vec4(in_vert, 0.0, 1.0);
            color = in_color;
        }
        """,
        fragment_shader="""
        #version 330
        in vec3 color;
        out vec4 fragColor;
        void main() {
            fragColor = vec4(color, 1.0);
        }
    """)

    vertices = np.array([
        -0.6, -0.6,
        1.0, 0.0, 0.0,
        0.6, -0.6,
        0.0, 1.0, 0.0,
        0.0, 0.6,
        0.0, 0.0, 1.0,
    ], dtype='f4')

    vbo = ctx.buffer(vertices)
    vao = ctx.simple_vertex_array(prog, vbo, 'in_vert', 'in_color')
    fbo = ctx.framebuffer(color_attachments=[ctx.texture((512, 512), 4)])

    fbo.use()
    ctx.clear()
    prog['model'].write(Matrix44.from_eulers((0.0, 0.1, 0.0), dtype='f4'))
    vao.render(moderngl.TRIANGLES)

    data = fbo.read(components=3)
    image = Image.frombytes('RGB', fbo.size, data)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    image.save('output.png')