def _rtt_load_attachment(cfg): quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) background = ngl.Render(quad, program) background.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['orange'])) texture = ngl.Texture2D(width=16, height=16) rtt = ngl.RenderToTexture(render, [texture]) texture_noop = ngl.Texture2D(width=16, height=16) rtt_noop = ngl.RenderToTexture(render, [texture_noop]) quad = ngl.Quad((0, 0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) foreground = ngl.Render(quad, program) foreground.update_frag_resources(tex0=texture) return ngl.Group(children=(background, rtt, rtt_noop, foreground))
def rtt_clear_attachment_with_timeranges(cfg): cfg.aspect_ratio = (1, 1) # Time-disabled full screen white quad quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) time_range_filter = ngl.TimeRangeFilter(render) time_range_filter.add_ranges(ngl.TimeRangeModeNoop(0)) # Intermediate no-op RTT to force the use of a different render pass internally texture = ngl.Texture2D(width=32, height=32) rtt_noop = ngl.RenderToTexture(ngl.Identity(), [texture]) # Centered rotating quad quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['orange'])) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, -360) ] render = ngl.Rotate(render, anim=ngl.AnimatedFloat(animkf)) group = ngl.Group(children=(time_range_filter, rtt_noop, render)) # Root RTT texture = ngl.Texture2D(width=512, height=512) rtt = ngl.RenderToTexture(group, [texture]) # Full screen render of the root RTT result quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture) return ngl.Group(children=(rtt, render))
def _transform_shape(cfg): w, h = 0.75, 0.45 geometry = ngl.Quad(corner=(-w/2., -h/2., 0), width=(w, 0, 0), height=(0, h, 0)) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(geometry, prog) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['rose'])) return render
def compute_particules(cfg): random.seed(0) cfg.duration = 10 local_size = 4 nb_particules = 128 shader_version = '310 es' if cfg.backend == 'gles' else '430' shader_data = dict( version=shader_version, local_size=local_size, nb_particules=nb_particules, ) compute_shader = _PARTICULES_COMPUTE % shader_data vertex_shader = _PARTICULES_VERT % shader_data fragment_shader = _PARTICULES_FRAG % shader_data positions = array.array('f') velocities = array.array('f') for i in range(nb_particules): positions.extend([ random.uniform(-2.0, 1.0), random.uniform(-1.0, 1.0), 0.0, ]) velocities.extend([ random.uniform(1.0, 2.0), random.uniform(0.5, 1.5), ]) ipositions = ngl.Block( fields=[ ngl.BufferVec3(data=positions), ngl.BufferVec2(data=velocities), ], layout='std430', ) opositions = ngl.Block(fields=[ngl.BufferVec3(count=nb_particules)], layout='std430') animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 1.0), ] time = ngl.AnimatedFloat(animkf) duration = ngl.UniformFloat(cfg.duration) group_size = nb_particules / local_size program = ngl.ComputeProgram(compute_shader) compute = ngl.Compute(nb_particules, 1, 1, program) compute.update_uniforms(time=time, duration=duration) compute.update_blocks(ipositions_buffer=ipositions, opositions_buffer=opositions) circle = ngl.Circle(radius=0.05) program = ngl.Program(vertex=vertex_shader, fragment=fragment_shader) render = ngl.Render(circle, program, nb_instances=nb_particules) render.update_uniforms(color=ngl.UniformVec4(value=COLORS['sgreen'])) render.update_blocks(positions_buffer=opositions) group = ngl.Group() group.add_children(compute, render) return group
def get_debug_points(cfg, points, radius=0.025, color=COLORS['green'], text_size=(0.1, 0.1)): prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) g = ngl.Group() circle = ngl.Circle(radius=radius) circle_render = ngl.Render(circle, prog) circle_render.update_uniforms(color=ngl.UniformVec4(value=color)) box_w = (text_size[0], 0, 0) box_h = (0, text_size[1], 0) for pos_name, position in points.items(): text = ngl.Text(pos_name, box_width=box_w, box_height=box_h, bg_color=(0, 0, 0, 0), valign='top') text = ngl.Translate(text, (1 + radius, 1 - radius - text_size[1], 0)) point = ngl.Group(children=(circle_render, text)) point = ngl.Translate(point, list(position) + [0]) g.add_children(point) return ngl.GraphicConfig(g, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one', label='Debug circles')
def easings(cfg, easing_id='*'): '''Display all the easings (primitive for animation / motion design) at once''' random.seed(0) cfg.duration = 2. vert_data = cfg.get_vert('color') frag_data = cfg.get_frag('color') color_program = ngl.Program(vertex=vert_data, fragment=frag_data, label='color') full_block = _block(2, 2, color_program, color=ngl.UniformVec4(value=(.3, .3, .3, 1))) group = ngl.Group() group.add_children(full_block) if easing_id == '*': for easing_node in _get_easing_nodes(cfg, color_program): group.add_children(easing_node) else: cfg.aspect_ratio = (1, 1) easing_index = _easing_names.index(easing_id) random.seed(easing_index) easing, zoom = _easing_list[easing_index] easing_node = _get_easing_node(cfg, easing, zoom, color_program) group.add_children(easing_node) return 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')
def _get_background_circles(circle, prog, positions, bcolor): blend_bg = ngl.Group() render = ngl.Render(circle, prog) render.update_frag_resources(color=ngl.UniformVec4(value=bcolor)) for position in positions: trender = ngl.Translate(render, position) blend_bg.add_children(trender) return blend_bg
def _get_scene(geometry=None): program = ngl.Program(vertex=_vert, fragment=_frag) if geometry is None: geometry = ngl.Quad() scene = ngl.Render(geometry, program) scene.update_frag_resources(color=ngl.UniformVec4(value=(1.0, 1.0, 1.0, 1.0))) return scene
def shape_diamond_colormask(cfg): color_write_masks = ('r+g+b+a', 'r+g+a', 'g+b+a', 'r+b+a') geometry = ngl.Circle(npoints=5) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(geometry, prog) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) scenes = [ngl.GraphicConfig(render, color_write_mask=cwm) for cwm in color_write_masks] return autogrid_simple(scenes)
def compute_particles(cfg): random.seed(0) 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([ random.uniform(-2.0, 1.0), random.uniform(-1.0, 1.0), 0.0, ]) velocities.extend([ random.uniform(1.0, 2.0), random.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.UniformVec4(value=COLORS['sgreen'])) render.update_vert_resources(data=opositions) group = ngl.Group() group.add_children(compute, render) return group
def square2circle(cfg, square_color=(0.9, 0.1, 0.3, 1.0), circle_color=(1.0, 1.0, 1.0, 1.0)): '''Morphing of a square (composed of many vertices) into a circle''' cfg.duration = 5 cfg.aspect_ratio = (1, 1) def sqxf(t): # square x coordinates clockwise starting top-left if t < 1 / 4.: return t * 4 if t < 1 / 2.: return 1 if t < 3 / 4.: return 1. - (t - .5) * 4 return 0 def sqyf(t): # square y coordinates clockwise starting top-left if t < 1 / 4.: return 1 if t < 1 / 2.: return 1. - (t - .25) * 4 if t < 3 / 4.: return 0 return (t - .75) * 4 n = 1024 # number of vertices s = 1.25 # shapes scale interp = 'exp_in_out' square_vertices = array.array('f') for i in range(n): x = (sqxf(i / float(n)) - .5) * s y = (sqyf(i / float(n)) - .5) * s square_vertices.extend([x, y, 0]) circle_vertices = array.array('f') step = 2 * math.pi / float(n) for i in range(n): angle = i * step - math.pi / 4. x = math.sin(angle) * .5 * s y = math.cos(angle) * .5 * s circle_vertices.extend([x, y, 0]) vertices_animkf = [ ngl.AnimKeyFrameBuffer(0, square_vertices), ngl.AnimKeyFrameBuffer(cfg.duration / 2., circle_vertices, interp), ngl.AnimKeyFrameBuffer(cfg.duration, square_vertices, interp), ] vertices = ngl.AnimatedBufferVec3(vertices_animkf) color_animkf = [ ngl.AnimKeyFrameVec4(0, square_color), ngl.AnimKeyFrameVec4(cfg.duration / 2., circle_color, interp), ngl.AnimKeyFrameVec4(cfg.duration, square_color, interp), ] ucolor = ngl.UniformVec4(anim=ngl.AnimatedVec4(color_animkf)) geom = ngl.Geometry(vertices) geom.set_topology('triangle_fan') p = ngl.Program(fragment=cfg.get_frag('color')) render = ngl.Render(geom, p) render.update_uniforms(color=ucolor) return render
def transform_animated_camera(cfg): cfg.duration = 5. g = ngl.Group() elems = ( ('red', None), ('yellow', (-0.6, 0.8, -1)), ('green', (0.6, 0.8, -1)), ('cyan', (-0.6, -0.5, -1)), ('magenta', (0.6, -0.5, -1)), ) quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) for color, vector in elems: node = ngl.Render(quad, prog) node.update_uniforms(color=ngl.UniformVec4(value=COLORS[color])) if vector: node = ngl.Translate(node, vector=vector) g.add_children(node) g = ngl.GraphicConfig(g, depth_test=True) camera = ngl.Camera(g) camera.set_eye(0, 0, 2) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(cfg.duration, (0.0, 0.0, 3.0)) ] eye_transform = ngl.Translate(ngl.Identity(), anim=ngl.AnimatedVec3(tr_animkf)) rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360) ] eye_transform = ngl.Rotate(eye_transform, axis=(0, 1, 0), anim=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(eye_transform) fov_animkf = [ ngl.AnimKeyFrameFloat(0.5, 60.0), ngl.AnimKeyFrameFloat(cfg.duration, 45.0) ] camera.set_fov_anim(ngl.AnimatedFloat(fov_animkf)) return camera
def _get_blending_base_objects(cfg): circle = ngl.Circle(radius=_CIRCLE_RADIUS, npoints=100) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) positions = _equilateral_triangle_coords(_CIRCLE_RADIUS * 2.0 / 3.0) colored_circles = ngl.Group(label='colored circles') for position, color in zip(positions, _CIRCLES_COLORS): render = ngl.Render(circle, prog) render.update_frag_resources(color=ngl.UniformVec4(value=color)) render = ngl.Translate(render, position) colored_circles.add_children(render) return colored_circles, circle, prog, positions
def compute_animation(cfg): cfg.duration = 5 cfg.aspect_ratio = (1, 1) local_size = 2 vertices_data = array.array('f', [ -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, 0.0, ]) 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), anim=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.UniformVec4(value=COLORS['sgreen'])) return ngl.Group(children=(compute, render))
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', [ 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, ])) 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_uniforms(color=ngl.UniformVec4(value=COLORS['orange'])) return render
def urchin(cfg, npoints=25): '''Urchin with animated vertices''' cfg.duration = 5 cfg.aspect_ratio = (1, 1) random.seed(0) def get_vertices(n, radius_func, offset=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 = .1, .9 inner_rfunc = lambda: n inner_vertices = get_vertices(npoints, inner_rfunc) vdata = [] for i in range(k): outer_rfunc = lambda: random.uniform(n, m) outer_vertices = get_vertices(npoints, outer_rfunc, offset=.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.UniformVec4(value=(.9, .1, .3, 1))) return render
def ret_func(cfg, nb_points=100, zoom=1, offset_start=0, offset_end=1, draw_in=True, draw_out=True, draw_in_out=True, draw_out_in=True): g = ngl.Group() cfg.aspect_ratio = (1, 1) frag_data = cfg.get_frag('color') program = ngl.Program(fragment=frag_data) for idx, ext in enumerate(versions): interp = name if ext is not None: interp += '_' + ext if not eval('draw_' + ext): continue anim = ngl.AnimatedFloat([ ngl.AnimKeyFrameFloat(-1, -1), ngl.AnimKeyFrameFloat(1, 1, interp, easing_start_offset=offset_start, easing_end_offset=offset_end) ]) vertices_data = array.array('f') for i in range(nb_points + 1): x = (i / float(nb_points) * 2 - 1) y = anim.evaluate(x * 1 / zoom) * zoom vertices_data.extend([x, y, 0]) vertices = ngl.BufferVec3(data=vertices_data) geometry = ngl.Geometry(vertices, topology='line_strip') render = ngl.Render(geometry, program) render.update_uniforms(color=ngl.UniformVec4(_colors[idx])) g.add_children(render) return g
def compute_animation(cfg): cfg.duration = 5 cfg.aspect_ratio = (1, 1) local_size = 2 shader_version = '310 es' if cfg.backend == 'gles' else '430' shader_data = dict( version=shader_version, local_size=local_size, ) compute_shader = _ANIMATION_COMPUTE % shader_data vertex_shader = _ANIMATION_VERT % shader_data fragment_shader = _ANIMATION_FRAG % shader_data vertices_data = array.array('f', [ -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.5, 0.5, 0.0, -0.5, 0.5, 0.0, ]) nb_vertices = 4 input_vertices = ngl.BufferVec3(data=vertices_data) output_vertices = ngl.BufferVec3(data=vertices_data) input_block = ngl.Block(fields=[input_vertices], layout='std140') output_block = ngl.Block(fields=[output_vertices], layout='std430') rotate_animkf = [ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360)] rotate = ngl.Rotate(ngl.Identity(), axis=(0, 0, 1), anim=ngl.AnimatedFloat(rotate_animkf)) transform = ngl.UniformMat4(transform=rotate) program = ngl.ComputeProgram(compute_shader) compute = ngl.Compute(nb_vertices / (local_size ** 2), 1, 1, program) compute.update_uniforms(transform=transform) compute.update_blocks(input_block=input_block, output_block=output_block) quad_buffer = ngl.BufferVec3(block=output_block, block_field=0) geometry = ngl.Geometry(quad_buffer, topology='triangle_fan') program = ngl.Program(vertex=vertex_shader, fragment=fragment_shader) render = ngl.Render(geometry, program) render.update_uniforms(color=ngl.UniformVec4(value=COLORS['sgreen'])) return ngl.Group(children=(compute, render))
def fibo(cfg, n=8): '''Fibonacci with a recursive tree (nodes inherit transforms)''' cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) p = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) fib = [0, 1, 1] for i in range(2, n): fib.append(fib[i] + fib[i - 1]) fib = fib[::-1] shift = 1 / 3. # XXX: what's the exact math here? shape_scale = 1. / ((2. - shift) * sum(fib)) orig = (-shift, -shift, 0) g = None root = None for i, x in enumerate(fib[:-1]): w = x * shape_scale gray = 1. - i / float(n) color = [gray, gray, gray, 1] q = ngl.Quad(orig, (w, 0, 0), (0, w, 0)) render = ngl.Render(q, p) render.update_frag_resources(color=ngl.UniformVec4(value=color)) new_g = ngl.Group() animkf = [ ngl.AnimKeyFrameFloat(0, 90), ngl.AnimKeyFrameFloat(cfg.duration / 2, -90, 'exp_in_out'), ngl.AnimKeyFrameFloat(cfg.duration, 90, 'exp_in_out') ] rot = ngl.Rotate(new_g, anchor=orig, anim=ngl.AnimatedFloat(animkf)) if g: g.add_children(rot) else: root = rot g = new_g new_g.add_children(render) orig = (orig[0] + w, orig[1] + w, 0) return root
def animated_circles(cfg): '''Simple cyclic circles animation''' group = ngl.Group() cfg.duration = 5. cfg.aspect_ratio = (1, 1) radius = 0.2 n = 10 step = 360. / n shape = ngl.Circle(radius=radius, npoints=128) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(shape, prog) render.update_uniforms(color=ngl.UniformVec4([1.0] * 4)) for i in range(n): mid_time = cfg.duration / 2.0 start_time = mid_time / (i + 2) end_time = cfg.duration - start_time scale_animkf = [ ngl.AnimKeyFrameVec3(start_time, (0, 0, 0)), ngl.AnimKeyFrameVec3(mid_time, (1.0, 1.0, 1.0), 'exp_out'), ngl.AnimKeyFrameVec3(end_time, (0, 0, 0), 'exp_in'), ] angle = i * step rotate_animkf = [ ngl.AnimKeyFrameFloat(start_time, 0), ngl.AnimKeyFrameFloat(mid_time, angle, 'exp_out'), ngl.AnimKeyFrameFloat(end_time, 0, 'exp_in'), ] tnode = render tnode = ngl.Scale(tnode, anim=ngl.AnimatedVec3(scale_animkf)) tnode = ngl.Translate(tnode, vector=(1 - radius, 0, 0)) tnode = ngl.Rotate(tnode, anim=ngl.AnimatedFloat(rotate_animkf)) group.add_children(tnode) return group
def texture_clear_and_scissor(cfg): quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) color = ngl.UniformVec4(COLORS['white']) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(quad, program) render.update_uniforms(color=color) graphic_config = ngl.GraphicConfig(render, scissor_test=True, scissor=(0, 0, 0, 0)) texture = ngl.Texture2D(width=64, height=64) rtt = ngl.RenderToTexture(ngl.Identity(), [texture], clear_color=COLORS['orange']) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) render = ngl.Render(quad, program) render.update_textures(tex0=texture) return ngl.Group(children=(graphic_config, rtt, render))
def texture_scissor(cfg): cfg.aspect_ratio = (1, 1) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) color = ngl.UniformVec4(COLORS['orange']) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(quad, program) render.update_uniforms(color=color) graphic_config = ngl.GraphicConfig(render, scissor_test=True, scissor=(32, 32, 32, 32)) texture = ngl.Texture2D(width=64, height=64) rtt = ngl.RenderToTexture(graphic_config, [texture]) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) render = ngl.Render(quad, program) render.update_textures(tex0=texture) return ngl.Group(children=(rtt, render))
def shape_morphing(cfg, n=6): cfg.duration = 5.0 random.seed(0) vertices_tl = _get_morphing_coordinates(n, -1, 0) vertices_tr = _get_morphing_coordinates(n, 0, 0) vertices_bl = _get_morphing_coordinates(n, -1,-1) vertices_br = _get_morphing_coordinates(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_fan') p = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(geom, p) render.update_frag_resources(color=ngl.UniformVec4(COLORS['cyan'])) return render
def animated_square(cfg, color=(1, 0.66, 0, 1), rotate=True, scale=True, translate=True): '''Animated Translate/Scale/Rotate on a square''' cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) sz = 1 / 3. q = ngl.Quad((-sz / 2, -sz / 2, 0), (sz, 0, 0), (0, sz, 0)) p = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) node = ngl.Render(q, p) ucolor = ngl.UniformVec4(value=color) node.update_uniforms(color=ucolor) coords = [(-1, 1), (1, 1), (1, -1), (-1, -1), (-1, 1)] if rotate: animkf = (ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360)) node = ngl.Rotate(node, anim=ngl.AnimatedFloat(animkf)) if scale: animkf = (ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration / 2, (2, 2, 2)), ngl.AnimKeyFrameVec3(cfg.duration, (1, 1, 1))) node = ngl.Scale(node, anim=ngl.AnimatedVec3(animkf)) if translate: animkf = [] tscale = 1. / float(len(coords) - 1) * cfg.duration for i, xy in enumerate(coords): pos = (xy[0] * .5, xy[1] * .5, 0) t = i * tscale animkf.append(ngl.AnimKeyFrameVec3(t, pos)) node = ngl.Translate(node, anim=ngl.AnimatedVec3(animkf)) return node
def buffer_dove(cfg, bgcolor1=(.6, 0, 0, 1), bgcolor2=(.8, .8, 0, 1), bilinear_filtering=True): '''Blending of a Render using a Buffer as data source''' cfg.duration = 3. # Credits: https://icons8.com/icon/40514/dove icon_filename = op.join(op.dirname(__file__), 'data', 'icons8-dove.raw') cfg.files.append(icon_filename) w, h = (96, 96) cfg.aspect_ratio = (w, h) img_buf = ngl.BufferUBVec4(filename=icon_filename, label='icon raw buffer') img_tex = ngl.Texture2D(data_src=img_buf, width=w, height=h) if bilinear_filtering: img_tex.set_mag_filter('linear') quad = ngl.Quad((-.5, -.5, 0.1), (1, 0, 0), (0, 1, 0)) prog = ngl.Program() render = ngl.Render(quad, prog, label='dove') render.update_textures(tex0=img_tex) render = ngl.GraphicConfig(render, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one') prog_bg = ngl.Program(fragment=cfg.get_frag('color')) shape_bg = ngl.Circle(radius=.6, npoints=256) render_bg = ngl.Render(shape_bg, prog_bg, label='background') color_animkf = [ngl.AnimKeyFrameVec4(0, bgcolor1), ngl.AnimKeyFrameVec4(cfg.duration/2.0, bgcolor2), ngl.AnimKeyFrameVec4(cfg.duration, bgcolor1)] ucolor = ngl.UniformVec4(anim=ngl.AnimatedVec4(color_animkf)) render_bg.update_uniforms(color=ucolor) return ngl.Group(children=(render_bg, render))
def data_noise_wiggle(cfg): cfg.aspect_ratio = (1, 1) cfg.duration = 3 vert = ''' void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * ngl_position; ngl_out_pos += vec4(wiggle, 0.0, 0.0); } ''' frag = ''' void main() { ngl_out_color = color; } ''' 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.UniformVec4(value=COLORS['white'])) return render
def _get_live_shared_uniform_function(layout=None): data = [COLORS['red'], COLORS['blue']] color = ngl.UniformVec4(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
def _render_shape(cfg, geometry, color): prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(geometry, prog) render.update_uniforms(color=ngl.UniformVec4(value=color)) return render
def _get_easing_node(cfg, easing, curve_zoom, color_program, nb_points=128): text_vratio = 1 / 8. graph_hpad_ratio = 1 / 16. area_size = 2.0 width, height = area_size, area_size text_height = text_vratio * height pad_height = graph_hpad_ratio * height # Colors hue = random.uniform(0, 0.6) color = list(colorsys.hls_to_rgb(hue, 0.6, 1.0)) + [1] ucolor = ngl.UniformVec4(value=color) graph_bg_ucolor = ngl.UniformVec4(value=(.15, .15, .15, 1)) normed_graph_bg_ucolor = ngl.UniformVec4(value=(0, 0, 0, 1)) line_ucolor = ngl.UniformVec4(value=(1, 1, 1, .4)) # Text legend text = ngl.Text(text=easing, fg_color=color, padding=3, bg_color=(0, 0, 0, 1), box_corner=(-width / 2., height / 2. - 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, color_program, corner=(-graph_size / 2, -(graph_size + text_height) / 2, 0), color=graph_bg_ucolor) # Normed area of the graph normed_graph_size = graph_size * curve_zoom normed_graph_block = _block(normed_graph_size, normed_graph_size, color_program, corner=(-normed_graph_size / 2, -(normed_graph_size + text_height) / 2, 0), color=normed_graph_bg_ucolor) # 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.) y = curve_scale_factor * (v * height - height / 2.) y -= text_height / 2. 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_uniforms(color=ucolor) # Value cursor y = 2 / 3. * pad_height x = y * math.sqrt(3) cursor_geometry = ngl.Triangle((-x, y, 0), (0, 0, 0), (-x, -y, 0)) cursor = ngl.Render(cursor_geometry, color_program, label='%s cursor' % easing) cursor.update_uniforms(color=ucolor) # 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, label='%s value line' % easing) hline.update_uniforms(color=line_ucolor) # Value animation (cursor + h-line) value_x = -graph_size / 2. value_y = (-text_height - normed_graph_size) / 2. 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, anim=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, label='%s time line' % easing) vline.update_uniforms(color=line_ucolor) # Time animation (v-line only) time_x = -normed_graph_size / 2. time_y = (-text_height - graph_size) / 2. 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, anim=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
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): # Seed only defines the random for the position of the fields