예제 #1
0
    animated_quat_mat4=lambda data: ngl.AnimatedQuat(
        keyframes=_get_anim_kf(ngl.AnimKeyFrameQuat, data), as_mat4=True),
    animated_quat_vec4=lambda data: ngl.AnimatedQuat(
        keyframes=_get_anim_kf(ngl.AnimKeyFrameQuat, data), as_mat4=False),
    array_float=lambda data: ngl.BufferFloat(data=data),
    array_int=lambda data: ngl.BufferInt(data=data),
    array_ivec2=lambda data: ngl.BufferIVec2(data=data),
    array_ivec3=lambda data: ngl.BufferIVec3(data=data),
    array_ivec4=lambda data: ngl.BufferIVec4(data=data),
    array_mat4=lambda data: ngl.BufferMat4(data=data),
    array_vec2=lambda data: ngl.BufferVec2(data=data),
    array_vec3=lambda data: ngl.BufferVec3(data=data),
    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),
)
예제 #2
0
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)

    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)

    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)
        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:
        color_fields = ngl.Block(fields=[f for _, f in color_fields],
                                 layout=layout,
                                 label="colors_block")
        block_fields = ngl.Block(fields=[f for _, f in block_fields],
                                 layout=layout,
                                 label="fields_block")
        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
예제 #3
0
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 _ 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 = tuple(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
예제 #4
0
def mountain(cfg, ndim=3, nb_layers=7,
             ref_color=(0.5, .75, .75, 1.0), nb_mountains=6):
    '''Mountain generated with a stack of noise shaders using Textures as random source'''
    random.seed(0)
    random_dim = 1 << ndim
    cfg.aspect_ratio = (16, 9)
    cfg.duration = nb_mountains ** 2

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

    black, white = (0, 0, 0, 1), (1, 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.
    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.),
                           ngl.AnimKeyFrameFloat(cfg.duration/2.0, yoffset),
                           ngl.AnimKeyFrameFloat(cfg.duration, yoffset/2.)]
        uyoffset = ngl.AnimatedFloat(uyoffset_animkf)

        render = ngl.Render(quad, prog)
        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.UniformVec4(mcolor))
        render.update_frag_resources(yoffset=uyoffset)
        render.update_frag_resources(hscale=ngl.UniformFloat(hscale))

        mountains.append(render)

    prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color'))
    sky = ngl.Render(quad, prog)
    sky.update_frag_resources(color=ngl.UniformVec4(white))

    group = ngl.Group(children=[sky] + mountains)
    blend = ngl.GraphicConfig(group,
                              blend=True,
                              blend_src_factor='src_alpha',
                              blend_dst_factor='one_minus_src_alpha',
                              blend_src_factor_a='zero',
                              blend_dst_factor_a='one')
    return blend