Пример #1
0
def _path_scene(cfg, path, points=None, controls=None, easing="linear"):
    cfg.aspect_ratio = (1, 1)

    anim_kf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1, easing),
    ]

    geom = ngl.Circle(radius=0.03, npoints=32)
    shape = ngl.RenderColor(COLORS.orange, geometry=geom)

    moving_shape = ngl.Translate(shape, vector=ngl.AnimatedPath(anim_kf, path))

    objects = []

    if points:
        debug_points = {f"P{i}": p[:2] for i, p in enumerate(points)}
        objects.append(get_debug_points(cfg, debug_points))

    if controls:
        debug_controls = {f"C{i}": p[:2] for i, p in enumerate(controls)}
        objects.append(get_debug_points(cfg, debug_controls,
                                        color=COLORS.cyan))

    objects.append(moving_shape)

    return ngl.Group(children=objects)
Пример #2
0
def texture_mipmap(cfg, show_dbg_points=False):
    cfg.aspect_ratio = (1, 1)
    cuepoints = _get_texture_mipmap_cuepoints()
    black = (0, 0, 0, 255)
    white = (255, 255, 255, 255)
    p = _N // 2
    cb_data = array.array(
        'B',
        ((black + white) * p + (white + black) * p) * p,
    )
    cb_buffer = ngl.BufferUBVec4(data=cb_data)

    texture = ngl.Texture2D(
        width=_N,
        height=_N,
        min_filter='nearest',
        mipmap_filter='linear',
        data_src=cb_buffer,
    )

    program = ngl.Program(vertex=_RENDER_TEXTURE_LOD_VERT,
                          fragment=_RENDER_TEXTURE_LOD_FRAG)
    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)
    render.update_frag_resources(tex0=texture)

    group = ngl.Group(children=(render, ))
    if show_dbg_points:
        group.add_children(get_debug_points(cfg, cuepoints))

    return group
Пример #3
0
def _get_live_shared_uniform_with_block_scene(cfg, color, layout,
                                              debug_positions):
    vertex = '''
void main()
{
    ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * ngl_position;
}
'''
    fragment = '''
void main()
{
    ngl_out_color = data.color;
}
'''
    program = ngl.Program(vertex=vertex, fragment=fragment)
    group = ngl.Group()
    for i in range(2):
        block = ngl.Block(fields=[color], layout=layout)
        quad = ngl.Quad((-1 + i, -1 + i, 0), (1, 0, 0), (0, 1, 0))
        render = ngl.Render(quad, program)
        render.update_frag_resources(data=block)
        group.add_children(render)
    if debug_positions:
        group.add_children(get_debug_points(cfg, _SHARED_UNIFORM_CUEPOINTS))
    return group
Пример #4
0
def texture_mipmap(cfg, show_dbg_points=False):
    cfg.aspect_ratio = (1, 1)
    cuepoints = _get_texture_mipmap_cuepoints()
    black = (0, 0, 0, 255)
    white = (255, 255, 255, 255)
    p = _N // 2
    cb_data = array.array(
        'B',
        ((black + white) * p + (white + black) * p) * p,
    )
    cb_buffer = ngl.BufferUBVec4(data=cb_data)

    texture = ngl.Texture2D(
        width=_N,
        height=_N,
        min_filter='nearest',
        mipmap_filter='linear',
        data_src=cb_buffer,
    )

    shader_version = '300 es' if cfg.backend == 'gles' else '330'
    program = ngl.Program(
        vertex=_RENDER_TEXTURE_LOD_VERT % dict(version=shader_version),
        fragment=_RENDER_TEXTURE_LOD_FRAG % dict(version=shader_version),
    )

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    render = ngl.Render(quad, program)
    render.update_textures(tex0=texture)

    group = ngl.Group(children=(render, ))
    if show_dbg_points:
        group.add_children(get_debug_points(cfg, cuepoints))

    return group
Пример #5
0
def _get_live_shared_uniform_scene(cfg, color, debug_positions):
    group = ngl.Group()
    for i in range(2):
        quad = ngl.Quad((-1 + i, -1 + i, 0), (1, 0, 0), (0, 1, 0))
        render = ngl.RenderColor(color, geometry=quad)
        group.add_children(render)
    if debug_positions:
        group.add_children(get_debug_points(cfg, _SHARED_UNIFORM_CUEPOINTS))
    return group
Пример #6
0
def get_render(cfg,
               quad,
               fields,
               block_definition,
               color_definition,
               block_fields,
               color_fields,
               layout,
               debug_positions=False):

    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())
    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_debug_positions_from_fields(fields)
        dbg_circles = get_debug_points(cfg, debug_points, text_size=(.2, .1))
        g = ngl.Group(children=(render, dbg_circles))
        return g

    return render
Пример #7
0
def _get_data_streamed_buffer_vec4_scene(cfg, scale, show_dbg_points):
    duration = _N
    cfg.duration = duration * scale
    cfg.aspect_ratio = (1, 1)
    size, data_size, = _N, _N * _N

    time_anim = None
    if scale != 1:
        kfs = [
            ngl.AnimKeyFrameFloat(0, 0),
            ngl.AnimKeyFrameFloat(cfg.duration, duration),
        ]
        time_anim = ngl.AnimatedTime(kfs)

    pts_data = array.array('q')
    assert pts_data.itemsize == 8

    for i in range(duration):
        offset = 10000 if i == 0 else 0
        pts_data.extend([i * 1000000 + offset])

    vec4_data = array.array('f')
    for i in range(duration):
        for j in range(data_size):
            v = i / float(duration) + j / float(data_size * duration)
            vec4_data.extend([v, v, v, v])

    pts_buffer = ngl.BufferInt64(data=pts_data)
    vec4_buffer = ngl.BufferVec4(data=vec4_data)
    streamed_buffer = ngl.StreamedBufferVec4(data_size,
                                             pts_buffer,
                                             vec4_buffer,
                                             time_anim=time_anim,
                                             label='data')
    streamed_block = ngl.Block(layout='std140',
                               label='streamed_block',
                               fields=(streamed_buffer, ))

    shader_params = dict(data_size=data_size, size=size)

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=_RENDER_STREAMEDBUFFER_VERT,
        fragment=_RENDER_STREAMEDBUFFER_FRAG % shader_params,
    )
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(streamed=streamed_block)

    group = ngl.Group(children=(render, ))
    if show_dbg_points:
        cuepoints = _get_data_streamed_buffer_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    return group
Пример #8
0
def _get_live_shared_uniform_scene(cfg, color, debug_positions):
    program = ngl.Program(vertex=cfg.get_vert('color'),
                          fragment=cfg.get_frag('color'))
    group = ngl.Group()
    for i in range(2):
        quad = ngl.Quad((-1 + i, -1 + i, 0), (1, 0, 0), (0, 1, 0))
        render = ngl.Render(quad, program)
        render.update_frag_resources(color=color)
        group.add_children(render)
    if debug_positions:
        group.add_children(get_debug_points(cfg, _SHARED_UNIFORM_CUEPOINTS))
    return group
Пример #9
0
def _debug_overlay(cfg,
                   scene,
                   grid_names,
                   show_dbg_points=False,
                   show_labels=False):
    if not show_dbg_points and not show_labels:
        return scene

    assert grid_names is not None

    text_height = 0.25

    overlay = ngl.Group()

    if show_labels:
        text_group = ngl.Group()
        ag = AutoGrid(grid_names)
        for grid_name, _, col, row in ag:
            text = ngl.Text(
                grid_name,
                fg_color=COLORS.white,
                bg_opacity=1,
                valign="top",
                box_width=(2.0, 0, 0),
                box_height=(0, text_height, 0),
                box_corner=(-1, 1.0 - text_height, 0),
            )
            text = ag.place_node(text, (col, row))
            text_group.add_children(text)

        scene = ngl.Translate(scene, (0, -text_height / 2.0 * ag.scale, 0),
                              label="text offsetting")
        overlay.add_children(scene, text_group)
    else:
        overlay.add_children(scene)

    if show_dbg_points:
        nb = len(grid_names)
        dbg_positions = _get_dbg_positions(nb)
        if show_labels:
            dbg_positions = {
                name: (p[0], p[1] - text_height / 2.0 * ag.scale)
                for name, p in dbg_positions.items()
            }
        dbg_points = get_debug_points(cfg,
                                      dbg_positions,
                                      radius=0.01,
                                      text_size=(0.08, 0.08))

        overlay.add_children(dbg_points)

    return overlay
Пример #10
0
def get_render(cfg, quad, fields, block_definition, color_definition, block_fields, color_fields, layout, debug_positions=False):

    func_calls = []
    func_definitions = []
    for i, field in enumerate(fields):
        is_array = 'len' in field
        func_calls.append('get_color_%s(w, h, 0.0, %f * h)' % (field['name'], i))
        func_definitions.append(_get_display_glsl_func(layout, field['name'], field['type'], is_array=is_array))

    frag_data = dict(
        block_definition=_get_glsl_fields_definition(1, layout, 'fields', block_definition),
        color_definition=_get_glsl_fields_definition(2, layout, 'colors', color_definition),
        layout=layout,
        func_definitions='\n'.join(func_definitions),
        func_calls=' + '.join(func_calls),
    )

    if layout == 'std430':
        shader_version = '310 es' if cfg.backend == 'gles' else '430'
    else:
        shader_version = '300 es' if cfg.backend == 'gles' else '330'

    header = '#version %s\n' % shader_version

    fragment = header + _FIELDS_FRAG % frag_data
    vertex = header + _FIELDS_VERT

    program = ngl.Program(vertex=vertex, fragment=fragment)
    render = ngl.Render(quad, program)

    if isinstance(color_fields, dict):
        assert isinstance(block_fields, dict)
        field_names = set(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_uniforms(**d)
    else:
        render.update_blocks(fields_block=block_fields, colors_block=color_fields)

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

    if debug_positions:
        debug_points = _get_debug_positions_from_fields(fields)
        dbg_circles = get_debug_points(cfg, debug_points, text_size=(.2, .1))
        g = ngl.Group(children=(render, dbg_circles))
        return g

    return render
Пример #11
0
def compute_image_load_store(cfg, show_dbg_points=False):
    size = _N
    texture_data = ngl.BufferFloat(
        data=array.array("f", [x / (size**2) for x in range(size**2)]))
    texture_r = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    texture_g = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    texture_b = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    scale = ngl.Block(
        fields=[ngl.UniformVec2(value=(-1.0, 1.0), label="factors")],
        layout="std140",
    )
    texture_rgba = ngl.Texture2D(width=size, height=size)
    program = ngl.ComputeProgram(_IMAGE_LOAD_STORE_COMPUTE,
                                 workgroup_size=(size, size, 1))
    program.update_properties(
        texture_r=ngl.ResourceProps(as_image=True),
        texture_g=ngl.ResourceProps(as_image=True),
        texture_b=ngl.ResourceProps(as_image=True),
        texture_rgba=ngl.ResourceProps(as_image=True, writable=True),
    )
    compute = ngl.Compute(workgroup_count=(1, 1, 1), program=program)
    compute.update_resources(texture_r=texture_r,
                             texture_g=texture_g,
                             texture_b=texture_b,
                             scale=scale,
                             texture_rgba=texture_rgba)

    render = ngl.RenderTexture(texture_rgba)
    group = ngl.Group(children=(compute, render))

    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))

    return group
Пример #12
0
def compute_histogram(cfg, show_dbg_points=False):
    cfg.duration = 10
    cfg.aspect_ratio = (1, 1)
    hsize, size, local_size = _N * _N, _N, _N // 2
    data = array.array("f")
    for i in range(size * size):
        data.extend((
            cfg.rng.uniform(0.0, 0.5),
            cfg.rng.uniform(0.25, 0.75),
            cfg.rng.uniform(0.5, 1.0),
            1.0,
        ))
    texture_buffer = ngl.BufferVec4(data=data)
    texture = ngl.Texture2D(width=size, height=size, data_src=texture_buffer)
    texture.set_format("r32g32b32a32_sfloat")

    histogram_block = ngl.Block(layout="std140", label="histogram")
    histogram_block.add_fields(
        ngl.BufferUInt(hsize, label="r"),
        ngl.BufferUInt(hsize, label="g"),
        ngl.BufferUInt(hsize, label="b"),
        ngl.UniformUIVec3(label="max"),
    )

    shader_params = dict(hsize=hsize, size=size, local_size=local_size)

    group_size = hsize // local_size
    clear_histogram_shader = _COMPUTE_HISTOGRAM_CLEAR % shader_params
    clear_histogram_program = ngl.ComputeProgram(clear_histogram_shader,
                                                 workgroup_size=(local_size, 1,
                                                                 1))
    clear_histogram_program.update_properties(hist=ngl.ResourceProps(
        writable=True))
    clear_histogram = ngl.Compute(
        workgroup_count=(group_size, 1, 1),
        program=clear_histogram_program,
        label="clear_histogram",
    )
    clear_histogram.update_resources(hist=histogram_block)

    group_size = size // local_size
    exec_histogram_shader = _COMPUTE_HISTOGRAM_EXEC % shader_params
    exec_histogram_program = ngl.ComputeProgram(exec_histogram_shader,
                                                workgroup_size=(local_size,
                                                                local_size, 1))
    exec_histogram_program.update_properties(hist=ngl.ResourceProps(
        writable=True))
    exec_histogram = ngl.Compute(workgroup_count=(group_size, group_size, 1),
                                 program=exec_histogram_program,
                                 label="compute_histogram")
    exec_histogram.update_resources(hist=histogram_block, source=texture)
    exec_histogram_program.update_properties(source=ngl.ResourceProps(
        as_image=True))

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=_RENDER_HISTOGRAM_VERT,
        fragment=_RENDER_HISTOGRAM_FRAG % shader_params,
    )
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program, label="render_histogram")
    render.update_frag_resources(hist=histogram_block)

    group = ngl.Group(children=(clear_histogram, exec_histogram, render))
    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    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
Пример #14
0
def compute_histogram(cfg, show_dbg_points=False):
    random.seed(0)
    cfg.duration = 10
    cfg.aspect_ratio = (1, 1)
    hsize, size, local_size = _N * _N, _N, _N // 2
    data = array.array('f')
    for i in range(size * size):
        data.extend((
            random.uniform(0.0, 0.5),
            random.uniform(0.25, 0.75),
            random.uniform(0.5, 1.0),
            1.0,
        ))
    texture_buffer = ngl.BufferVec4(data=data)
    texture = ngl.Texture2D(width=size, height=size, data_src=texture_buffer)

    histogram_block = ngl.Block(layout='std430', label='histogram')
    histogram_block.add_fields(
        ngl.BufferUInt(hsize),
        ngl.BufferUInt(hsize),
        ngl.BufferUInt(hsize),
        ngl.UniformUIVec3(),
    )

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_header = '#version %s\n' % shader_version
    if cfg.backend == 'gles' and cfg.system == 'Android':
        shader_header += '#extension GL_ANDROID_extension_pack_es31a: require\n'
    shader_params = dict(hsize=hsize, size=size, local_size=local_size)

    group_size = hsize // local_size
    clear_histogram_shader = _COMPUTE_HISTOGRAM_CLEAR % shader_params
    clear_histogram_program = ngl.ComputeProgram(shader_header + clear_histogram_shader)
    clear_histogram = ngl.Compute(
        group_size,
        1,
        1,
        clear_histogram_program,
        label='clear_histogram',
    )
    clear_histogram.update_blocks(histogram=histogram_block)

    group_size = size // local_size
    exec_histogram_shader = _COMPUTE_HISTOGRAM_EXEC % shader_params
    exec_histogram_program = ngl.ComputeProgram(shader_header + exec_histogram_shader)
    exec_histogram = ngl.Compute(
        group_size,
        group_size,
        1,
        exec_histogram_program,
        label='compute_histogram'
    )
    exec_histogram.update_blocks(histogram=histogram_block)
    exec_histogram.update_textures(source=texture)

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=shader_header + _RENDER_HISTOGRAM_VERT,
        fragment=shader_header + _RENDER_HISTOGRAM_FRAG % shader_params,
    )
    render = ngl.Render(quad, program, label='render_histogram')
    render.update_blocks(histogram=histogram_block)

    group = ngl.Group(children=(clear_histogram, exec_histogram, render,))
    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    return group