Exemple #1
0
def _get_compositing_scene(cfg, op, show_label=False):
    cfg.aspect_ratio = (1, 1)
    cfg.duration = 6

    # We can not use a circle geometry because the whole areas must be
    # rasterized for the compositing to work, so instead we build 2 overlapping
    # quad into which we draw colored circles, offsetted with an animation.
    # Alternatively, we could use a RTT.
    quad = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0))
    prog = ngl.Program(vertex=_VERTEX, fragment=_FRAGMENT)
    prog.update_vert_out_vars(uv=ngl.IOVec2())

    A_off_kf = (
        ngl.AnimKeyFrameVec2(0, (-1 / 3, 0)),
        ngl.AnimKeyFrameVec2(cfg.duration / 2, (1 / 3, 0)),
        ngl.AnimKeyFrameVec2(cfg.duration, (-1 / 3, 0)),
    )
    B_off_kf = (
        ngl.AnimKeyFrameVec2(0, (1 / 3, 0)),
        ngl.AnimKeyFrameVec2(cfg.duration / 2, (-1 / 3, 0)),
        ngl.AnimKeyFrameVec2(cfg.duration, (1 / 3, 0)),
    )
    A_off = ngl.AnimatedVec2(A_off_kf)
    B_off = ngl.AnimatedVec2(B_off_kf)

    A = ngl.Render(quad, prog, label="A")
    A.update_frag_resources(color=ngl.UniformVec3(value=COLORS.azure),
                            off=A_off)

    B = ngl.Render(quad, prog, label="B", blending=op)
    B.update_frag_resources(color=ngl.UniformVec3(value=COLORS.orange),
                            off=B_off)

    bg = ngl.RenderColor(blending="dst_over")

    # draw A in current FBO, then draw B with the current operator, and
    # then result goes over the white background
    ret = ngl.Group(children=(A, B, bg))

    if show_label:
        label_h = 1 / 4
        label_pad = 0.1
        label = ngl.Text(
            op,
            fg_color=COLORS.black,
            bg_color=(0.8, 0.8, 0.8),
            bg_opacity=1,
            box_corner=(label_pad / 2 - 1, 1 - label_h - label_pad / 2, 0),
            box_width=(2 - label_pad, 0, 0),
            box_height=(0, label_h, 0),
        )
        ret.add_children(label)

    return ret
Exemple #2
0
def velocity_circle_distort_2d(cfg):
    cfg.duration = 4.0
    cfg.aspect_ratio = (1, 1)

    coords = list(equilateral_triangle_coords())
    coords.append(coords[0])

    pos_kf = [
        ngl.AnimKeyFrameVec2(cfg.duration * i / 3.0, pos[0:2], "exp_in_out")
        for i, pos in enumerate(coords)
    ]
    anim = ngl.AnimatedVec2(pos_kf)
    velocity = ngl.VelocityVec2(anim)

    vert = textwrap.dedent("""\
        void main()
        {
            float distort_max = 0.1;
            float velocity_l = length(velocity);
            float direction_l = length(ngl_position);
            vec2 normed_velocity = velocity_l == 0.0 ? vec2(0.0) : -velocity / velocity_l;
            vec2 normed_direction = direction_l == 0.0 ? vec2(0.0) : ngl_position.xy / direction_l;
            float distort = clamp(dot(normed_velocity, normed_direction) / 2.0 * distort_max, 0.0, 1.0);
            vec4 pos = vec4(ngl_position, 1.0) + vec4(translate, 0.0, 0.0) + vec4(-distort * velocity, 0.0, 0.0);
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * pos;
        }
        """)

    geom = ngl.Circle(radius=0.2, npoints=128)
    prog = ngl.Program(vertex=vert, fragment=cfg.get_frag("color"))
    shape = ngl.Render(geom, prog)
    shape.update_frag_resources(color=ngl.UniformVec3(COLORS.white),
                                opacity=ngl.UniformFloat(1))
    shape.update_vert_resources(velocity=velocity, translate=anim)
    return shape
Exemple #3
0
def _get_live_shared_uniform_function(layout=None):
    data = [COLORS.red, COLORS.blue]
    color = ngl.UniformVec3(value=COLORS.black, label="color")

    def keyframes_callback(t_id):
        color.set_value(*data[t_id])

    @test_cuepoints(
        points=_SHARED_UNIFORM_CUEPOINTS,
        nb_keyframes=len(data),
        keyframes_callback=keyframes_callback,
        tolerance=1,
        exercise_serialization=False,
        debug_positions=False,
    )
    @scene(debug_positions=scene.Bool())
    def scene_func(cfg, debug_positions=True):
        cfg.duration = 0
        cfg.aspect_ratio = (1, 1)
        if layout:
            return _get_live_shared_uniform_with_block_scene(
                cfg, color, layout, debug_positions)
        else:
            return _get_live_shared_uniform_scene(cfg, color, debug_positions)

    return scene_func
Exemple #4
0
def _compute_animation(cfg, animate_pre_render=True):
    cfg.duration = 5
    cfg.aspect_ratio = (1, 1)
    local_size = 2

    vertices_data = array.array(
        "f",
        [
            # fmt: off
            -0.5,
            -0.5,
            0.0,
            0.5,
            -0.5,
            0.0,
            -0.5,
            0.5,
            0.0,
            0.5,
            0.5,
            0.0,
            # fmt: on
        ],
    )
    nb_vertices = 4

    input_vertices = ngl.BufferVec3(data=vertices_data, label="vertices")
    output_vertices = ngl.BufferVec3(data=vertices_data, label="vertices")
    input_block = ngl.Block(fields=[input_vertices], layout="std140")
    output_block = ngl.Block(fields=[output_vertices], layout="std140")

    rotate_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 360)
    ]
    rotate = ngl.Rotate(ngl.Identity(),
                        axis=(0, 0, 1),
                        angle=ngl.AnimatedFloat(rotate_animkf))
    transform = ngl.UniformMat4(transform=rotate)

    program = ngl.ComputeProgram(_ANIMATION_COMPUTE,
                                 workgroup_size=(local_size, local_size, 1))
    program.update_properties(dst=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroup_count=(nb_vertices / (local_size**2), 1,
                                           1),
                          program=program)
    compute.update_resources(transform=transform,
                             src=input_block,
                             dst=output_block)

    quad_buffer = ngl.BufferVec3(block=output_block, block_field=0)
    geometry = ngl.Geometry(quad_buffer, topology="triangle_strip")
    program = ngl.Program(vertex=cfg.get_vert("color"),
                          fragment=cfg.get_frag("color"))
    render = ngl.Render(geometry, program)
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.sgreen),
                                 opacity=ngl.UniformFloat(1))

    children = (compute, render) if animate_pre_render else (render, compute)
    return ngl.Group(children=children)
Exemple #5
0
def compute_particles(cfg):
    cfg.duration = 10
    workgroups = (2, 1, 4)
    local_size = (4, 4, 1)
    nb_particles = workgroups[0] * workgroups[1] * workgroups[2] * local_size[
        0] * local_size[1] * local_size[2]

    positions = array.array("f")
    velocities = array.array("f")
    for i in range(nb_particles):
        positions.extend([
            cfg.rng.uniform(-2.0, 1.0),
            cfg.rng.uniform(-1.0, 1.0),
            0.0,
        ])
        velocities.extend([
            cfg.rng.uniform(1.0, 2.0),
            cfg.rng.uniform(0.5, 1.5),
        ])

    ipositions = ngl.Block(
        fields=[
            ngl.BufferVec3(data=positions, label="positions"),
            ngl.BufferVec2(data=velocities, label="velocities"),
        ],
        layout="std430",
    )
    opositions = ngl.Block(
        fields=[ngl.BufferVec3(count=nb_particles, label="positions")],
        layout="std140")

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1.0),
    ]
    time = ngl.AnimatedFloat(animkf)
    duration = ngl.UniformFloat(cfg.duration)

    program = ngl.ComputeProgram(_PARTICULES_COMPUTE,
                                 workgroup_size=local_size)
    program.update_properties(odata=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroups, program)
    compute.update_resources(time=time,
                             duration=duration,
                             idata=ipositions,
                             odata=opositions)

    circle = ngl.Circle(radius=0.05)
    program = ngl.Program(vertex=_PARTICULES_VERT,
                          fragment=cfg.get_frag("color"))
    render = ngl.Render(circle, program, nb_instances=nb_particles)
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.sgreen),
                                 opacity=ngl.UniformFloat(1))
    render.update_vert_resources(data=opositions)

    group = ngl.Group()
    group.add_children(compute, render)
    return group
Exemple #6
0
def api_denied_node_live_change(width=320, height=240):
    ctx = ngl.Context()
    ret = ctx.configure(offscreen=1, width=width, height=height, backend=_backend)
    assert ret == 0

    scene = ngl.Translate(ngl.Group())

    # Check that we can live change but not into a node
    assert ctx.set_scene(scene) == 0
    assert scene.set_vector(1, 2, 3) == 0
    assert scene.set_vector(ngl.UniformVec3(value=(3, 2, 1))) != 0

    # Check that we can do the change after a reset of the context
    assert ctx.set_scene(None) == 0
    assert scene.set_vector(ngl.UniformVec3(value=(4, 5, 6))) == 0

    # Check that we can not live unplug a node from a live changeable parameter
    assert ctx.set_scene(scene) == 0
    assert scene.set_vector(ngl.UniformVec3(value=(7, 8, 9))) != 0
Exemple #7
0
def _data_vertex_and_fragment_blocks(cfg, layout):
    """
    This test ensures that the block bindings are properly set by pgcraft
    when UBOs or SSBOs are bound to different stages.
    """
    cfg.aspect_ratio = (1, 1)

    src = ngl.Block(
        fields=[
            ngl.UniformVec3(value=COLORS.red, label="color"),
            ngl.UniformFloat(value=0.5, label="opacity"),
        ],
        layout="std140",
    )
    dst = ngl.Block(
        fields=[
            ngl.UniformVec3(value=COLORS.white, label="color"),
        ],
        layout=layout,
    )
    vert = textwrap.dedent("""\
        void main()
        {
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0);
            var_src = vec4(src.color, 1.0) * src.opacity;
        }
        """)
    frag = textwrap.dedent("""\
        void main()
        {
            vec3 color = var_src.rgb + (1.0 - var_src.a) * dst.color;
            ngl_out_color = vec4(color, 1.0);
        }
        """)

    program = ngl.Program(vertex=vert, fragment=frag)
    program.update_vert_out_vars(var_src=ngl.IOVec4(), )
    geometry = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0))
    render = ngl.Render(geometry, program)
    render.update_vert_resources(src=src)
    render.update_frag_resources(dst=dst)

    return render
Exemple #8
0
def color_negative_values_srgb(cfg):
    cfg.duration = 5
    kfs = (
        # The elastic_in easing has the special property to undershoot under 0
        ngl.AnimKeyFrameVec3(-5, value=(0.0, 0.0, 0.0)),
        ngl.AnimKeyFrameVec3(5, value=(0.0, 0.0, 1.0), easing="elastic_in"),
    )
    color0 = ngl.AnimatedVec3(keyframes=kfs)
    color1 = ngl.UniformVec3(value=(-1.0, -1.0, 1.0))
    return ngl.RenderGradient(color0=color0, color1=color1, linear=True)
Exemple #9
0
def shape_triangles_mat4_attribute(cfg):
    cfg.aspect_ratio = (1, 1)
    p0, p1, p2 = equilateral_triangle_coords(1)
    geometry = ngl.Triangle(p0, p1, p2)
    matrices = ngl.BufferMat4(data=array.array(
        "f",
        [
            # fmt: off
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            -0.5,
            0.0,
            0.0,
            1.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0,
            0.0,
            0.5,
            0.0,
            0.0,
            1.0,
            # fmt: on
        ],
    ))

    program = ngl.Program(
        vertex=TRIANGLES_MAT4_ATTRIBUTE_VERT,
        fragment=cfg.get_frag("color"),
    )
    render = ngl.Render(geometry, program, nb_instances=2)
    render.update_instance_attributes(matrix=matrices)
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.orange),
                                 opacity=ngl.UniformFloat(1))
    return render
Exemple #10
0
def get_random_block_info(spec, seed=0, layout=LAYOUTS[0], color_tint=True):

    # Seed only defines the random for the position of the fields
    random.seed(seed)
    fields_pos = random.sample(range(len(spec)), len(spec))

    # Always the same colors whatever the user seed
    random.seed(0)

    fields_info = []
    max_id_len = 0
    for i, field_info in enumerate(spec):
        node = field_info['func'](field_info.get('data'))
        node.set_label(field_info['name'])
        field_info['node'] = node
        field_info['decl'] = _get_field_decl(layout, field_info)
        field_info['pos'] = fields_pos.index(i)
        max_id_len = max(len(field_info['decl']), max_id_len)
        if color_tint:
            hue = random.uniform(0, 1)
            field_info['color'] = colorsys.hls_to_rgb(hue, 0.6, 1.0)
        else:
            field_info['color'] = (1, 1, 1)
        fields_info.append(field_info)

    shuf_fields = [fields_info[pos] for pos in fields_pos]
    color_fields = [(f['name'], ngl.UniformVec3(f['color'], label=f['name']))
                    for f in fields_info]
    block_fields = [(f['name'], f['node']) for f in shuf_fields]
    if layout == 'uniform':
        color_fields = dict(color_fields)
        block_fields = dict(block_fields)
    else:
        color_fields = ngl.Block(fields=[f for n, f in color_fields],
                                 layout=layout,
                                 label='colors_block')
        block_fields = ngl.Block(fields=[f for n, f in block_fields],
                                 layout=layout,
                                 label='fields_block')

    pad = lambda s: (max_id_len - len(s)) * ' '
    block_definition = '\n'.join('%s;%s // #%02d' %
                                 (f['decl'], pad(f['decl']), i)
                                 for i, f in enumerate(shuf_fields))

    color_prefix = 'color_' if layout == 'uniform' else ''
    color_u = 'uniform ' if layout == 'uniform' else ''
    color_definition = '\n'.join(
        color_u + 'vec3 %s;' % (color_prefix + f['name']) for f in fields_info)

    return fields_info, block_fields, color_fields, block_definition, color_definition
Exemple #11
0
def py_bindings_allow_node():
    c = ngl.Camera(eye=(0, 1, 0))
    assert c.set_eye(ngl.EvalVec3()) == 0
    assert c.set_eye(1, 0, 0) == 0

    c = ngl.Camera(eye=ngl.NoiseVec3())
    assert c.set_eye(1, 0, 0) == 0
    assert c.set_eye(ngl.UniformVec3()) == 0

    r = ngl.Rotate(angle=30)
    assert r.set_angle(ngl.NoiseFloat()) == 0
    assert r.set_angle(-45) == 0

    r = ngl.Rotate(angle=ngl.EvalFloat())
    assert r.set_angle(90) == 0
    assert r.set_angle(ngl.UniformFloat()) == 0
Exemple #12
0
def urchin(cfg, npoints=25):
    """Urchin with animated vertices"""
    cfg.duration = 5
    cfg.aspect_ratio = (1, 1)

    def get_vertices(n, radius_func, offset=0.0):
        vertices = []
        step = 2 * math.pi / n
        for i in range(n):
            angle = (i + offset) * step
            radius = radius_func()
            x, y = math.sin(angle) * radius, math.cos(angle) * radius
            vertices.append([x, y, 0])
        return vertices

    k = 16
    n, m = 0.1, 0.9

    inner_rfunc = lambda: n
    inner_vertices = get_vertices(npoints, inner_rfunc)

    vdata = []
    for i in range(k):
        outer_rfunc = lambda: cfg.rng.uniform(n, m)
        outer_vertices = get_vertices(npoints, outer_rfunc, offset=0.5)
        vertices_data = array.array("f")
        for inner_vertex, outer_vertex in zip(inner_vertices, outer_vertices):
            vertices_data.extend(inner_vertex + outer_vertex)
        vertices_data.extend(inner_vertices[0])
        vdata.append(vertices_data)

    animkf = []
    for i, v in enumerate(vdata + [vdata[0]]):
        animkf.append(ngl.AnimKeyFrameBuffer(i * cfg.duration / float(k), v))

    vertices = ngl.AnimatedBufferVec3(animkf)

    geom = ngl.Geometry(vertices)
    geom.set_topology("line_strip")
    p = ngl.Program(vertex=cfg.get_vert("color"),
                    fragment=cfg.get_frag("color"))
    render = ngl.Render(geom, p)
    render.update_frag_resources(color=ngl.UniformVec3(value=(0.9, 0.1, 0.3)),
                                 opacity=ngl.UniformFloat(1))
    return render
Exemple #13
0
def py_bindings_dict():
    foo = ngl.UniformVec3(value=(1, 2, 3), label="foo-node")
    assert foo.set_value(3, 2, 1) == 0
    render = ngl.Render(vert_resources=dict(foo=foo))

    assert render.set_label("r") == 0
    # Delete the previous entry and add another
    ret = render.update_vert_resources(
        foo=None,
        bar=ngl.UniformFloat(value=4, label="bar-node"),
    )
    assert ret == 0
    # Update by using a dict
    ret = render.update_vert_resources(
        dict(
            foo=ngl.UniformVec2(),
            bar=ngl.EvalFloat(),
        ))
    assert ret == 0
Exemple #14
0
def data_noise_wiggle(cfg):
    cfg.aspect_ratio = (1, 1)
    cfg.duration = 3
    vert = textwrap.dedent("""\
        void main()
        {
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0);
            ngl_out_pos += vec4(wiggle, 0.0, 0.0);
        }
        """)
    frag = textwrap.dedent("""\
        void main()
        {
            ngl_out_color = vec4(color, 1.0);
        }
        """)

    geometry = ngl.Circle(radius=0.25, npoints=6)
    program = ngl.Program(vertex=vert, fragment=frag)
    render = ngl.Render(geometry, program)
    render.update_vert_resources(wiggle=ngl.NoiseVec2(octaves=8))
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.white))
    return render
Exemple #15
0
def shape_morphing(cfg, n=6):
    cfg.duration = 5.0
    vertices_tl = _get_morphing_coordinates(cfg.rng, n, -1, 0)
    vertices_tr = _get_morphing_coordinates(cfg.rng, n, 0, 0)
    vertices_bl = _get_morphing_coordinates(cfg.rng, n, -1, -1)
    vertices_br = _get_morphing_coordinates(cfg.rng, n, 0, -1)

    vertices_animkf = []
    for i, coords in enumerate(
            zip(vertices_tl, vertices_tr, vertices_bl, vertices_br)):
        flat_coords = list(itertools.chain(*coords))
        coords_array = array.array("f", flat_coords)
        vertices_animkf.append(
            ngl.AnimKeyFrameBuffer(i * cfg.duration / (n - 1), coords_array))
    vertices = ngl.AnimatedBufferVec3(vertices_animkf)

    geom = ngl.Geometry(vertices)
    geom.set_topology("triangle_strip")
    p = ngl.Program(vertex=cfg.get_vert("color"),
                    fragment=cfg.get_frag("color"))
    render = ngl.Render(geom, p)
    render.update_frag_resources(color=ngl.UniformVec3(COLORS.cyan),
                                 opacity=ngl.UniformFloat(1))
    return render
def particles(cfg, particles=32):
    """Particules demo using compute shaders and instancing"""

    compute_shader = cfg.get_comp("particles")
    vertex_shader = cfg.get_vert("particles")
    fragment_shader = cfg.get_frag("color")

    cfg.duration = 6

    x = 64
    p = x * particles

    positions = array.array("f")
    velocities = array.array("f")

    for i in range(p):
        positions.extend([
            cfg.rng.uniform(-1.0, 1.0),
            cfg.rng.uniform(0.0, 1.0),
            0.0,
        ])

        velocities.extend([
            cfg.rng.uniform(-0.01, 0.01),
            cfg.rng.uniform(-0.05, 0.05),
        ])

    ipositions = ngl.Block(
        fields=[ngl.BufferVec3(data=positions, label="data")], layout="std430")
    ivelocities = ngl.Block(
        fields=[ngl.BufferVec2(data=velocities, label="data")],
        layout="std430")
    opositions = ngl.Block(fields=[ngl.BufferVec3(count=p, label="data")],
                           layout="std430")

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1)
    ]
    utime = ngl.AnimatedFloat(animkf)
    uduration = ngl.UniformFloat(cfg.duration)

    cp = ngl.ComputeProgram(compute_shader, workgroup_size=(1, 1, 1))
    cp.update_properties(opositions=ngl.ResourceProps(writable=True))

    c = ngl.Compute(workgroup_count=(x, particles, 1), program=cp)
    c.update_resources(
        time=utime,
        duration=uduration,
        ipositions=ipositions,
        ivelocities=ivelocities,
        opositions=opositions,
    )

    quad_width = 0.01
    quad = ngl.Quad(corner=(-quad_width / 2, -quad_width / 2, 0),
                    width=(quad_width, 0, 0),
                    height=(0, quad_width, 0))
    p = ngl.Program(
        vertex=vertex_shader,
        fragment=fragment_shader,
    )
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    r = ngl.Render(quad, p, nb_instances=particles, blending="src_over")
    r.update_frag_resources(color=ngl.UniformVec3(value=(0, 0.6, 0.8)),
                            opacity=ngl.UniformFloat(0.9))
    r.update_vert_resources(positions=opositions)

    g = ngl.Group()
    g.add_children(c, r)

    return ngl.Camera(g)
Exemple #17
0
def _shape_geometry(cfg, set_normals=False, set_indices=False):
    # Fake cube (3 faces only) obtained from:
    # echo 'cube();'>x.scad; openscad x.scad -o x.stl
    vertices = array.array(
        "f",
        [
            x - 0.5 for x in [
                # fmt: off
                1,
                1,
                0,
                0,
                1,
                1,
                1,
                1,
                1,
                0,
                1,
                1,
                1,
                1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                1,
                1,
                0,
                1,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                1,
                0,
                1,
                1,
                1,
                1,
                1,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                1,
                # fmt: on
            ]
        ],
    )

    normals = array.array(
        "f",
        [
            # fmt: off
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            -1,
            0,
            0,
            -1,
            0,
            0,
            -1,
            0,
            0,
            -1,
            0,
            0,
            -1,
            0,
            0,
            -1,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            # fmt: on
        ],
    )

    vertices_buffer = ngl.BufferVec3(data=vertices)
    normals_buffer = ngl.BufferVec3(data=normals)

    cfg.aspect_ratio = (1, 1)
    geometry = ngl.Geometry(vertices=vertices_buffer)

    if set_normals:
        geometry.set_normals(normals_buffer)
        prog = ngl.Program(vertex=cfg.get_vert("colored-normals"),
                           fragment=cfg.get_frag("colored-normals"))
        prog.update_vert_out_vars(var_normal=ngl.IOVec3())
        render = ngl.Render(geometry, prog)
    else:
        prog = ngl.Program(vertex=cfg.get_vert("color"),
                           fragment=cfg.get_frag("color"))
        render = ngl.Render(geometry, prog)
        render.update_frag_resources(
            color=ngl.UniformVec3(value=COLORS.magenta),
            opacity=ngl.UniformFloat(1))

    if set_indices:
        indices = array.array("H", list(range(3 * 6)))
        indices_buffer = ngl.BufferUShort(data=indices)
        geometry.set_indices(indices_buffer)

    return ngl.Rotate(render, 45, axis=(1, 1, 1))
def mountain(cfg,
             ndim=3,
             nb_layers=7,
             ref_color=(0.5, 0.75, 0.75),
             nb_mountains=6):
    """Mountain generated with a stack of noise shaders using Textures as random source"""
    random_dim = 1 << ndim
    cfg.aspect_ratio = (16, 9)
    cfg.duration = nb_mountains**2

    def get_rand():
        return array.array("f",
                           [cfg.rng.uniform(0, 1) for x in range(random_dim)])

    black, white = (0, 0, 0), (1, 1, 1)
    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))

    prog = ngl.Program(vertex=cfg.get_vert("texture"),
                       fragment=cfg.get_frag("mountain"))
    prog.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                              var_tex0_coord=ngl.IOVec2())
    hscale = 1 / 2.0
    mountains = []
    for i in range(nb_mountains):
        yoffset = (nb_mountains - i - 1) / float(nb_mountains - 1) * (1.0 -
                                                                      hscale)

        if i < nb_mountains / 2:
            c0, c1 = ref_color, white
            x = (i + 1) / float(nb_mountains / 2 + 1)
        else:
            c0, c1 = black, ref_color
            x = (i - nb_mountains / 2) / float((nb_mountains - 1) / 2)
        mcolor = [x * a + (1.0 - x) * b for a, b in zip(c0, c1)]

        random_buf = ngl.BufferFloat(data=get_rand())
        random_tex = ngl.Texture2D(data_src=random_buf,
                                   width=random_dim,
                                   height=1)

        utime_animkf = [
            ngl.AnimKeyFrameFloat(0, 0),
            ngl.AnimKeyFrameFloat(cfg.duration, i + 1)
        ]
        utime = ngl.AnimatedFloat(utime_animkf)

        uyoffset_animkf = [
            ngl.AnimKeyFrameFloat(0, yoffset / 2.0),
            ngl.AnimKeyFrameFloat(cfg.duration / 2.0, yoffset),
            ngl.AnimKeyFrameFloat(cfg.duration, yoffset / 2.0),
        ]
        uyoffset = ngl.AnimatedFloat(uyoffset_animkf)

        render = ngl.Render(quad, prog, blending="src_over")
        render.update_frag_resources(tex0=random_tex)
        render.update_frag_resources(dim=ngl.UniformInt(random_dim))
        render.update_frag_resources(nb_layers=ngl.UniformInt(nb_layers))
        render.update_frag_resources(time=utime)
        render.update_frag_resources(lacunarity=ngl.UniformFloat(2.0))
        render.update_frag_resources(gain=ngl.UniformFloat(0.5))
        render.update_frag_resources(mcolor=ngl.UniformVec3(mcolor))
        render.update_frag_resources(yoffset=uyoffset)
        render.update_frag_resources(hscale=ngl.UniformFloat(hscale))

        mountains.append(render)

    sky = ngl.RenderColor(white[:3])

    group = ngl.Group(children=[sky] + mountains)
    return group
def get_field_scene(cfg, spec, category, field_type, seed, debug_positions,
                    layout, color_tint):
    """
    Build a scene testing that a given data has been properly uploaded to the
    GPU memory.

    - `spec` contains all the fields that should also be declared (either in a
      block or as uniforms). All the fields are shuffled such that the field we
      are testing is always in a random position. This makes sure that we get
      the data alignment right.
    - `category` and `field_type` are filters in the spec to select the
      field(s) from which we want to read the data
    - `seed` is used to control the fields shuffling
    - `debug_positions` controls whether there are debug circles in the scene
      in order to make sure we are reading back the data colors at the
      appropriate position
    - `layout` controls the block layout or whether we are working with uniforms
    - `color_tint` is a debug helper to give a different color for each field
      (because if they have the same data, it is hard to indiscriminate them).
    """

    cfg.aspect_ratio = (1, 1)

    # Seed only defines the random for the position of the fields
    fields_pos = random.Random(seed).sample(range(len(spec)), len(spec))

    # Always the same colors whatever the user seed
    clr_rng = random.Random(0)

    fields_info = []
    for i, field_info in enumerate(spec):
        create_func = field_info.get("func")
        if create_func is None:
            create_func = _FUNCS["{category}_{type}".format(**field_info)]
        node = create_func(field_info.get("data"))
        node.set_label(field_info["name"])
        field_info["node"] = node
        if color_tint:
            hue = clr_rng.uniform(0, 1)
            field_info["color"] = colorsys.hls_to_rgb(hue, 0.6, 1.0)
        else:
            field_info["color"] = (1, 1, 1)
        fields_info.append(field_info)

    shuf_fields = [fields_info[pos] for pos in fields_pos]
    color_fields = [(f["name"], ngl.UniformVec3(f["color"], label=f["name"]))
                    for f in fields_info]
    block_fields = [(f["name"], f["node"]) for f in shuf_fields]
    if layout == "uniform":
        color_fields = dict(color_fields)
        block_fields = dict(block_fields)
    else:
        color_fields = ngl.Block(fields=[f for n, f in color_fields],
                                 layout=layout,
                                 label="colors_block")
        block_fields = ngl.Block(fields=[f for n, f in block_fields],
                                 layout=layout,
                                 label="fields_block")

    fields = match_fields(fields_info, category, field_type)

    func_calls = []
    func_definitions = []
    for i, field in enumerate(fields):
        field_len = field.get("len")
        func_calls.append("get_color_{}(w, h, 0.0, {:f} * h)".format(
            field["name"], i))
        func_definitions.append(
            _get_display_glsl_func(layout,
                                   field["name"],
                                   field["type"],
                                   field_len=field_len))

    frag_data = dict(
        func_definitions="\n".join(func_definitions),
        func_calls=" + ".join(func_calls),
    )

    fragment = _FIELDS_FRAG % frag_data
    vertex = _FIELDS_VERT

    program = ngl.Program(vertex=vertex, fragment=fragment)
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    render = ngl.Render(quad, program)

    if isinstance(color_fields, dict):
        assert isinstance(block_fields, dict)
        field_names = {f["name"] for f in fields}
        d = {}
        d.update(("color_" + n, u) for (n, u) in color_fields.items()
                 if n in field_names)
        d.update(("field_" + n, u) for (n, u) in block_fields.items()
                 if n in field_names)
        render.update_frag_resources(**d)
    else:
        render.update_frag_resources(fields=block_fields, colors=color_fields)

    render.update_frag_resources(nb_fields=ngl.UniformInt(len(fields)))

    if debug_positions:
        debug_points = get_data_debug_positions(fields)
        dbg_circles = get_debug_points(cfg, debug_points, text_size=(0.2, 0.1))
        g = ngl.Group(children=(render, dbg_circles))
        return g

    return render
def _get_easing_node(cfg, easing, curve_zoom, color_program, nb_points=128):
    text_vratio = 1 / 8.0
    graph_hpad_ratio = 1 / 16.0

    area_size = 2.0
    width, height = area_size, area_size
    text_height = text_vratio * height
    pad_height = graph_hpad_ratio * height

    # Colors
    hue = cfg.rng.uniform(0, 0.6)
    color = colorsys.hls_to_rgb(hue, 0.6, 1.0)
    ucolor = ngl.UniformVec3(value=color)
    line_ucolor = ngl.UniformVec3(value=(1, 1, 1))

    # Text legend
    text = ngl.Text(
        text=easing,
        fg_color=color[:3],
        padding=3,
        bg_opacity=1,
        box_corner=(-width / 2.0, height / 2.0 - text_height, 0),
        box_width=(width, 0, 0),
        box_height=(0, text_height, 0),
        label="%s legend" % easing,
    )

    # Graph drawing area (where the curve may overflow)
    graph_size = area_size - text_height - pad_height * 2
    graph_block = _block(graph_size,
                         graph_size, (0.15, 0.15, 0.15),
                         corner=(-graph_size / 2,
                                 -(graph_size + text_height) / 2, 0))

    # Normed area of the graph
    normed_graph_size = graph_size * curve_zoom
    normed_graph_block = _block(
        normed_graph_size,
        normed_graph_size,
        (0, 0, 0),
        corner=(-normed_graph_size / 2, -(normed_graph_size + text_height) / 2,
                0),
    )

    # Curve
    easing_name, easing_args = _easing_split(easing)
    curve_scale_factor = graph_size / area_size * curve_zoom
    vertices_data = array.array("f")
    for i in range(nb_points + 1):
        t = i / float(nb_points)
        v = ngl.easing_evaluate(easing_name, t, easing_args)
        x = curve_scale_factor * (t * width - width / 2.0)
        y = curve_scale_factor * (v * height - height / 2.0)
        y -= text_height / 2.0
        vertices_data.extend([x, y, 0])
    vertices = ngl.BufferVec3(data=vertices_data)
    geometry = ngl.Geometry(vertices, topology="line_strip")
    curve = ngl.Render(geometry, color_program, label="%s curve" % easing)
    curve.update_frag_resources(color=ucolor, opacity=ngl.UniformFloat(1))

    # Value cursor
    y = 2 / 3.0 * pad_height
    x = y * math.sqrt(3)
    cursor_geometry = ngl.Triangle((-x, y, 0), (0, 0, 0), (-x, -y, 0))
    cursor = ngl.RenderColor(color[:3],
                             geometry=cursor_geometry,
                             label="%s cursor" % easing)

    # Horizontal value line
    hline_data = array.array("f", (0, 0, 0, graph_size, 0, 0))
    hline_vertices = ngl.BufferVec3(data=hline_data)
    hline_geometry = ngl.Geometry(hline_vertices, topology="line_strip")
    hline = ngl.Render(hline_geometry,
                       color_program,
                       blending="src_over",
                       label="%s value line" % easing)
    hline.update_frag_resources(color=line_ucolor,
                                opacity=ngl.UniformFloat(0.4))

    # Value animation (cursor + h-line)
    value_x = -graph_size / 2.0
    value_y = (-text_height - normed_graph_size) / 2.0
    value_animkf = (
        ngl.AnimKeyFrameVec3(0, (value_x, value_y, 0)),
        ngl.AnimKeyFrameVec3(cfg.duration,
                             (value_x, value_y + normed_graph_size, 0),
                             easing_name, easing_args),
    )
    value_anim = ngl.Group(children=(hline, cursor))
    value_anim = ngl.Translate(value_anim,
                               vector=ngl.AnimatedVec3(value_animkf),
                               label="%s value anim" % easing)

    # Vertical time line
    vline_data = array.array("f", (0, 0, 0, 0, graph_size, 0))
    vline_vertices = ngl.BufferVec3(data=vline_data)
    vline_geometry = ngl.Geometry(vline_vertices, topology="line_strip")
    vline = ngl.Render(vline_geometry,
                       color_program,
                       blending="src_over",
                       label="%s time line" % easing)
    vline.update_frag_resources(color=line_ucolor,
                                opacity=ngl.UniformFloat(0.4))

    # Time animation (v-line only)
    time_x = -normed_graph_size / 2.0
    time_y = (-text_height - graph_size) / 2.0
    time_animkf = (
        ngl.AnimKeyFrameVec3(0, (time_x, time_y, 0)),
        ngl.AnimKeyFrameVec3(cfg.duration,
                             (time_x + normed_graph_size, time_y, 0)),
    )
    time_anim = ngl.Translate(vline,
                              vector=ngl.AnimatedVec3(time_animkf),
                              label="%s time anim" % easing)

    group = ngl.Group(label="%s block" % easing)
    group.add_children(text, graph_block, normed_graph_block, curve,
                       value_anim, time_anim)
    return group
Exemple #21
0
    array_vec4=lambda data: ngl.BufferVec4(data=data),
    single_bool=lambda data: ngl.UniformBool(data),
    single_float=lambda data: ngl.UniformFloat(data),
    single_int=lambda data: ngl.UniformInt(data),
    single_ivec2=lambda data: ngl.UniformIVec2(data),
    single_ivec3=lambda data: ngl.UniformIVec3(data),
    single_ivec4=lambda data: ngl.UniformIVec4(data),
    single_uint=lambda data: ngl.UniformUInt(data),
    single_uvec2=lambda data: ngl.UniformUIVec2(data),
    single_uvec3=lambda data: ngl.UniformUIVec3(data),
    single_uvec4=lambda data: ngl.UniformUIVec4(data),
    single_mat4=lambda data: ngl.UniformMat4(data),
    single_quat_mat4=lambda data: ngl.UniformQuat(data, as_mat4=True),
    single_quat_vec4=lambda data: ngl.UniformQuat(data, as_mat4=False),
    single_vec2=lambda data: ngl.UniformVec2(data),
    single_vec3=lambda data: ngl.UniformVec3(data),
    single_vec4=lambda data: ngl.UniformVec4(data),
)


def _get_field_decl(layout, f):
    t = f['type']
    t = t.split('_')[1] if t.startswith('quat') else t
    return '{}{:<5} {}{}{}'.format('uniform ' if layout == 'uniform' else '',
                                   t, 'field_' if layout == 'uniform' else '',
                                   f['name'],
                                   '[%d]' % f['len'] if 'len' in f else '')


def get_random_block_info(spec, seed=0, layout=LAYOUTS[0], color_tint=True):
def blending_and_stencil(cfg):
    """Scene using blending and stencil graphic features"""
    cfg.duration = 5
    vertex = cfg.get_vert("color")
    fragment = cfg.get_frag("color")

    program = ngl.Program(vertex=vertex, fragment=fragment)
    circle = ngl.Circle(npoints=256)
    cloud_color = ngl.UniformVec3(value=(1, 1, 1))
    cloud_opacity = ngl.UniformFloat(0.4)

    main_group = ngl.Group()

    render = ngl.RenderColor(color=(0.2, 0.6, 1), label="sky")
    config = ngl.GraphicConfig(
        render,
        stencil_test=True,
        stencil_write_mask=0xFF,
        stencil_func="always",
        stencil_ref=1,
        stencil_read_mask=0xFF,
        stencil_fail="replace",
        stencil_depth_fail="replace",
        stencil_depth_pass="******",
    )
    main_group.add_children(config)

    render = ngl.RenderColor(color=(1, 0.8, 0), geometry=circle, label="sun")

    scale = ngl.Scale(render, (0.15, 0.15, 0.0))
    translate = ngl.Translate(scale, (0.4, 0.3, 0))
    main_group.add_children(translate)

    cloud_group = ngl.Group(label="clouds")

    centers = [
        (-1.0, 0.85, 0.4),
        (-0.5, 2.0, 1.0),
        (0, 0.85, 0.4),
        (1.0, 1.55, 0.8),
        (0.6, 0.65, 0.075),
        (0.5, 1.80, 1.25),
    ]

    for center in centers:
        render = ngl.Render(circle, program, blending="src_over")
        render.update_frag_resources(color=cloud_color, opacity=cloud_opacity)

        factor = cfg.rng.random() * 0.4 + center[2]
        keyframe = cfg.duration * (cfg.rng.random() * 0.4 + 0.2)
        animkf = (
            ngl.AnimKeyFrameVec3(0, (factor, factor, 0)),
            ngl.AnimKeyFrameVec3(keyframe, (factor + 0.1, factor + 0.1, 0)),
            ngl.AnimKeyFrameVec3(cfg.duration, (factor, factor, 0)),
        )
        scale = ngl.Scale(render, factors=ngl.AnimatedVec3(animkf))

        translate = ngl.Translate(scale, vector=(center[0], center[1], 0))
        cloud_group.add_children(translate)

    config = ngl.GraphicConfig(
        cloud_group,
        stencil_test=True,
        stencil_write_mask=0x0,
        stencil_func="equal",
        stencil_ref=1,
        stencil_read_mask=0xFF,
        stencil_fail="keep",
        stencil_depth_fail="keep",
        stencil_depth_pass="******",
    )
    main_group.add_children(config)

    camera = ngl.Camera(main_group)
    camera.set_eye(0.0, 0.0, 2.0)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_orthographic(-cfg.aspect_ratio_float, cfg.aspect_ratio_float,
                            -1.0, 1.0)
    camera.set_clipping(1.0, 10.0)

    return camera
Exemple #23
0
def _get_cube_side(texture, program, corner, width, height, color):
    render = ngl.Render(ngl.Quad(corner, width, height), program)
    render.update_textures(tex0=texture)
    render.update_uniforms(blend_color=ngl.UniformVec3(value=color))
    render.update_uniforms(mix_factor=ngl.UniformFloat(value=0.2))
    return render