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)
def animated_uniform(cfg): '''Uniform mat4 animated with a transform chain''' m0 = cfg.medias[0] cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('matrix-transform')) ts = ngl.Render(q, p) ts.update_textures(tex0=t) scale_animkf = [ ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), 'quartic_out') ] s = ngl.Scale(ngl.Identity(), anim=ngl.AnimatedVec3(scale_animkf)) rotate_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out') ] r = ngl.Rotate(s, axis=(0, 0, 1), anim=ngl.AnimatedFloat(rotate_animkf)) u = ngl.UniformMat4(transform=r) ts.update_uniforms(matrix=u) return ts
def animated_uniform(cfg): """Uniform mat4 animated with a transform chain""" m0 = cfg.medias[0] cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert("texture"), fragment=cfg.get_frag("matrix-transform")) p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) ts = ngl.Render(q, p) ts.update_frag_resources(tex0=t) scale_animkf = [ ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), "quartic_out"), ] s = ngl.Scale(ngl.Identity(), factors=ngl.AnimatedVec3(scale_animkf)) rotate_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out") ] r = ngl.Rotate(s, axis=(0, 0, 1), angle=ngl.AnimatedFloat(rotate_animkf)) u = ngl.UniformMat4(transform=r) ts.update_frag_resources(matrix=u) return ts
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 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 _get_live_trf_spec(layout): t0 = ngl.Identity() t1 = ngl.Transform(t0) t2 = ngl.Translate(t1) t3 = ngl.Rotate(t2) t4 = ngl.Scale(t3) t5 = ngl.RotateQuat(t4) return [ dict( name='m4', type='mat4', category='single', func=lambda data: ngl.UniformMat4(data, transform=t5), livechange=( lambda: t1.set_matrix( # trf_step=1 0.1, 0.2, 0.0, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.0, 0.5, 0.0, 0.8, 0.7, 0.0, 0.6, ), lambda: t2.set_vector(0.2, 0.7, -0.4), # trf_step=2 lambda: t3.set_angle(123.4), # trf_step=3 lambda: t4.set_factors(0.7, 1.4, 0.2), # trf_step=4 lambda: t5.set_quat(0, 0, -0.474, 0.880), # trf_step=5 lambda: t5.set_quat(0, 0, 0, 1), lambda: t4.set_factors(1, 1, 1), lambda: t3.set_angle(0), lambda: t2.set_vector(0, 0, 0), lambda: t1.set_matrix( 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.0, 0.0, 0.0, 1.0, )), ), ]
def api_livectls(): # Build a scene and extract its live controls rng = random.Random(0) scene = ngl.Group( children=( ngl.UniformBool(live_id="b"), ngl.UniformFloat(live_id="f"), ngl.UniformIVec3(live_id="iv3"), ngl.UserSwitch( ngl.Group( children=( ngl.UniformMat4(live_id="m4"), ngl.UniformColor(live_id="clr"), ngl.UniformQuat(as_mat4=True, live_id="rot"), ) ), live_id="switch", ), ngl.Text(live_id="txt"), ) ) livectls = ngl.get_livectls(scene) assert len(livectls) == 8 # Attach scene and run a dummy draw to make sure it's valid ctx = ngl.Context() ret = ctx.configure(offscreen=1, width=16, height=16, backend=_backend) assert ret == 0 assert ctx.set_scene(scene) == 0 assert ctx.draw(0) == 0 # Apply live changes on nodes previously tracked by get_livectls() values = dict( b=True, f=rng.uniform(-1, 1), iv3=[rng.randint(-100, 100) for i in range(3)], switch=False, m4=[rng.uniform(-1, 1) for i in range(16)], clr=(0.9, 0.3, 0.8), rot=(0.1, -0.2, 0.5, -0.3), txt="test string", ) for live_id, value in values.items(): node = livectls[live_id]["node"] node_type = livectls[live_id]["node_type"] assert node_type == node.__class__.__name__ if node_type == "UserSwitch": node.set_enabled(value) elif node_type == "Text": node.set_text(value) elif hasattr(value, "__iter__"): node.set_value(*value) else: node.set_value(value) # Detach scene from context and grab all live controls again assert ctx.set_scene(None) == 0 livectls = ngl.get_livectls(scene) # Inspect nodes to check if they were properly altered by the live changes for live_id, expected_value in values.items(): value = livectls[live_id]["val"] node_type = livectls[live_id]["node_type"] if node_type == "Text": assert value == expected_value, (value, expected_value) elif hasattr(value, "__iter__"): assert all(math.isclose(v, e, rel_tol=1e-6) for v, e in zip(value, expected_value)) else: assert math.isclose(value, expected_value, rel_tol=1e-6)
def _get_live_trf_spec(): t0 = ngl.Identity() t1 = ngl.Transform(t0) t2 = ngl.Translate(t1) t3 = ngl.Rotate(t2) t4 = ngl.Scale(t3) t5 = ngl.RotateQuat(t4) t6 = ngl.Skew(t5) return [ dict( name="m4", type="mat4", category="single", func=lambda data: ngl.UniformMat4(data, transform=t6), livechange=( # fmt: off lambda: t1.set_matrix( # trf_step=1 0.1, 0.2, 0.0, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.0, 0.5, 0.0, 0.8, 0.7, 0.0, 0.6, ), lambda: t2.set_vector(0.2, 0.7, -0.4), # trf_step=2 lambda: t3.set_angle(123.4), # trf_step=3 lambda: t4.set_factors(0.7, 1.4, 0.2), # trf_step=4 lambda: t5.set_quat(0, 0, -0.474, 0.880), # trf_step=5 lambda: t6.set_angles(0, 50, -145), # trf_step=6 lambda: t6.set_angles(0, 0, 0), lambda: t5.set_quat(0, 0, 0, 1), lambda: t4.set_factors(1, 1, 1), lambda: t3.set_angle(0), lambda: t2.set_vector(0, 0, 0), lambda: t1.set_matrix( 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.0, 0.0, 0.0, 1.0, ) # fmt: on ), ), ]
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), ) 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 '')