Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# Standalone rendering

Standalone (offline) rendering allows you to render without using a window, and is included in ModernGL by default.

Rendering occurs when `VertexArray.render()` is called. By default, the `mode` parameter is `moderngl.TRIANGLES`, but since we need to draw a line, we change the mode value to `moderngl.LINES`:

    vao.render(moderngl.LINES)  # "mode" is the first optional argument

To display the rendering result, we use the Pillow (PIL) library that comes with Python. Let’s return the texture from the GPU memory to RAM and call the `PIL.Image.show()` method to show it.

Entire source

     1import moderngl
     2import numpy as np
     3
     4from PIL import Image
     5
     6ctx = moderngl.create_context(standalone=True)
     7
     8prog = ctx.program(
     9    vertex_shader="""
    10        #version 330
    11
    12        in vec2 in_vert;
    13        in vec3 in_color;
    14
    15        out vec3 v_color;
    16
    17        void main() {
    18            v_color = in_color;
    19            gl_Position = vec4(in_vert, 0.0, 1.0);
    20        }
    21    """,
    22    fragment_shader="""
    23        #version 330
    24
    25        in vec3 v_color;
    26
    27        out vec3 f_color;
    28
    29        void main() {
    30            f_color = v_color;
    31        }
    32    """,
    33)
    34
    35x = np.linspace(-1.0, 1.0, 50)
    36y = np.random.rand(50) - 0.5
    37r = np.zeros(50)
    38g = np.ones(50)
    39b = np.zeros(50)
    40
    41vertices = np.dstack([x, y, r, g, b])
    42
    43vbo = ctx.buffer(vertices.astype("f4").tobytes())
    44vao = ctx.vertex_array(prog, vbo, "in_vert", "in_color")
    45
    46fbo = ctx.framebuffer(
    47    color_attachments=[ctx.texture((512, 512), 3)]
    48)
    49fbo.use()
    50fbo.clear(0.0, 0.0, 0.0, 1.0)
    51vao.render(moderngl.LINE_STRIP)
    52
    53Image.frombytes(
    54    "RGB", fbo.size, fbo.color_attachments[0].read(),
    55    "raw", "RGB", 0, -1
    56).show()

The result will be something like this:

Rendering result