Skip to content

pmp-p/zengl-wasm

 
 

Repository files navigation

ZenGL

ZenGL

pip install zengl

Concept

ZenGL provides a simple, structured way to render with OpenGL in Python.

Pipelines are self-contained, no global state affects the render.

State changes between pipelines are optimized; framebuffers, descriptor sets are re-used.

ZenGL is a low level library, it adds no magic on the rendering side. All you need to know is OpenGL.

ZenGL runs Natively (Desktop OpenGL), on top of Angle (DirectX, Vulkan, Metal), or WebGL2 (In the Browser).

bezier_curves deferred_rendering envmap fractal grass normal_mapping rigged_objects wireframe

Complete Pipeline Definition

Probably the only documentation needed.

pipeline = ctx.pipeline(
    # program definition
    vertex_shader='...',
    fragment_shader='...',
    layout=[
        {
            'name': 'Uniforms',
            'binding': 0,
        },
        {
            'name': 'Texture',
            'binding': 0,
        },
    ],

    # descriptor sets
    resources=[
        {
            'type': 'uniform_buffer',
            'binding': 0,
            'buffer': uniform_buffer,
        },
        {
            'type': 'sampler',
            'binding': 0,
            'image': texture,
        },
    ],

    # uniforms
    uniforms={
        'color': [0.0, 0.5, 1.0],
        'iterations': 10,
    },

    # program definition global state
    depth={
        'func': 'less',
        'write': False,
    },
    stencil={
        'front': {
            'fail_op': 'replace',
            'pass_op': 'replace',
            'depth_fail_op': 'replace',
            'compare_op': 'always',
            'compare_mask': 1,
            'write_mask': 1,
            'reference': 1,
        },
        'back': ...,
        # or
        'both': ...,
    },
    blend={
        'enable': True,
        'src_color': 'src_alpha',
        'dst_color': 'one_minus_src_alpha',
    },
    cull_face='back',
    topology='triangles',

    # framebuffer
    framebuffer=[color1, color2, ..., depth],
    viewport=(x, y, width, height),

    # vertex array
    vertex_buffers=[
        *zengl.bind(vertex_buffer, '3f 3f', 0, 1), # bound vertex attributes
        *zengl.bind(None, '2f', 2), # unused vertex attribute
    ],
    index_buffer=index_buffer, # or None
    short_index=False, # 2 or 4 byte intex
    vertex_count=...,
    instance_count=1,
    first_vertex=0,

    # override includes
    includes={
        'common': '...',
    },
)

# some members are actually mutable and calls no OpenGL functions
pipeline.viewport = ...
pipeline.vertex_count = ...
pipeline.uniforms['iterations'][:] = struct.pack('i', 50) # writable memoryview

# rendering
pipeline.render() # no parameters for hot code