def depth_stencil_depth(_): group = ngl.Group() count = 4 for i in range(count): depth = (i + 1) / count corner = (-1 + (count - 1 - i) * 2 / count, -1, depth) render = _render_quad(corner=corner, color=(depth, depth, depth)) graphicconfig = ngl.GraphicConfig( render, depth_test=True, depth_func="lequal", ) group.add_children(graphicconfig) for i, depth in enumerate((0.4, 0.6)): corner = (-1, -0.5 + 0.25 * i, depth) height = (0, 1 - 0.25 * i * 2, 0) render = _render_quad(corner=corner, height=height, color=COLORS.red, opacity=0.5) graphicconfig = ngl.GraphicConfig( render, depth_test=True, depth_func="less", depth_write_mask=False, ) group.add_children(graphicconfig) return group
def depth_stencil_stencil(_): group = ngl.Group() count = 4 for i in range(count): render = _render_quad(corner=(-1 + (i * 2) / count, -1, 0), color=COLORS.black) graphicconfig = ngl.GraphicConfig( render, color_write_mask="", stencil_test=True, stencil_write_mask=0xFF, stencil_func="always", stencil_ref=1, stencil_read_mask=0xFF, stencil_fail="incr", stencil_depth_fail="incr", stencil_depth_pass="******", ) group.add_children(graphicconfig) render = _render_quad(color=COLORS.white) graphicconfig = ngl.GraphicConfig( render, stencil_test=True, stencil_write_mask=0x0, stencil_func="equal", stencil_ref=1, stencil_read_mask=0x1, stencil_fail="keep", stencil_depth_fail="keep", stencil_depth_pass="******", ) group.add_children(graphicconfig) return group
def _get_rtt_scene(cfg, features='depth', texture_ds_format=None, samples=0, mipmap_filter='none', sample_depth=False): cfg.duration = 10 cfg.aspect_ratio = (1, 1) cube = _get_cube() program = ngl.Program(vertex=_RENDER_CUBE_VERT, fragment=_RENDER_CUBE_FRAG) program.update_vert_out_vars(var_normal=ngl.IOVec3()) render = ngl.Render(cube, program) render = ngl.Scale(render, (0.5, 0.5, 0.5)) for i in range(3): rot_animkf = ngl.AnimatedFloat([ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1)) ]) axis = [int(i == x) for x in range(3)] render = ngl.Rotate(render, axis=axis, anim=rot_animkf) config = ngl.GraphicConfig(render, depth_test=True) camera = ngl.Camera( config, eye=(0.0, 0.0, 3.0), center=(0.0, 0.0, 0.0), up=(0.0, 1.0, 0.0), perspective=(45.0, cfg.aspect_ratio_float), clipping=(1.0, 10.0), ) size = 1024 texture_depth = None if texture_ds_format: texture_depth = ngl.Texture2D(width=size, height=size, format=texture_ds_format) texture = ngl.Texture2D( width=size, height=size, min_filter='linear', mipmap_filter=mipmap_filter, ) rtt = ngl.RenderToTexture( camera, [texture], features=features, depth_texture=texture_depth, samples=samples, clear_color=(0, 0, 0, 1), ) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) if sample_depth: program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=_RENDER_DEPTH) 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_depth) else: 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 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 _shape_geometry_rtt(cfg, depth=False, samples=0): w, h = 640, 480 scene = _shape_geometry(cfg, set_normals=True) if depth: scene = ngl.GraphicConfig(scene, depth_test=True) texture = ngl.Texture2D() texture.set_width(w) texture.set_height(h) rtt = ngl.RenderToTexture(scene) rtt.add_color_textures(texture) if depth: texture = ngl.Texture2D() texture.set_format('d16_unorm') texture.set_width(w) texture.set_height(h) rtt.set_depth_texture(texture) else: rtt.set_clear_color(*COLORS['cgreen']) if samples: rtt.set_samples(samples) 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')) render = ngl.Render(quad, program) render.update_textures(tex0=texture) return ngl.Group(children=(rtt, render))
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 animated_camera(cfg, rotate=True): '''Animated camera around a scene''' g = ngl.Group() q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) node = ngl.Render(q, program) node.update_frag_resources(tex0=t) g.add_children(node) translate = ngl.Translate(node, vector=(-0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(-0.6, -0.5, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, -0.5, -1)) g.add_children(translate) 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(10, (0.0, 0.0, 3.0), 'exp_out') ] node = ngl.Translate(ngl.Identity(), anim=ngl.AnimatedVec3(tr_animkf)) if rotate: rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out') ] node = ngl.Rotate(node, axis=(0, 1, 0), anim=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(node) fov_animkf = [ ngl.AnimKeyFrameFloat(0.5, 60.0), ngl.AnimKeyFrameFloat(cfg.duration, 45.0, 'exp_out') ] camera.set_fov_anim(ngl.AnimatedFloat(fov_animkf)) return camera
def cube(cfg, display_depth_buffer=False): ''' Cube with a common media Texture but a different color tainting on each side. Also includes a depth map visualization. ''' cube = ngl.Group(label='cube') frag_data = cfg.get_frag('tex-tint') program = ngl.Program(fragment=frag_data) texture = ngl.Texture2D(data_src=ngl.Media(cfg.medias[0].filename)) children = [_get_cube_side(texture, program, qi[0], qi[1], qi[2], qi[3]) for qi in _get_cube_quads()] cube.add_children(*children) for i in range(3): rot_animkf = ngl.AnimatedFloat([ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1))]) axis = [int(i == x) for x in range(3)] cube = ngl.Rotate(cube, axis=axis, anim=rot_animkf) config = ngl.GraphicConfig(cube, depth_test=True) camera = ngl.Camera(config) 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_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(1.0, 10.0) if not display_depth_buffer: return camera else: group = ngl.Group() depth_texture = ngl.Texture2D() depth_texture.set_format('d16_unorm') depth_texture.set_width(640) depth_texture.set_height(480) texture = ngl.Texture2D() texture.set_width(640) texture.set_height(480) rtt = ngl.RenderToTexture(camera) rtt.add_color_textures(texture) rtt.set_depth_texture(depth_texture) quad = ngl.Quad((-1.0, -1.0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program() render = ngl.Render(quad, program) render.update_textures(tex0=texture) group.add_children(rtt, render) quad = ngl.Quad((0.0, 0.0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program() render = ngl.Render(quad, program) render.update_textures(tex0=depth_texture) group.add_children(rtt, render) return group
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 _get_userlive_select_func(): # We point on the same underlying render to test the different render paths render = ngl.RenderColor(COLORS.white, opacity=0.5, geometry=ngl.Quad()) below = ngl.Translate(render, vector=(0.5 - 2 / 3, 0.5 - 1 / 3, 0)) above = ngl.Translate(render, vector=(0.5 - 1 / 3, 0.5 - 2 / 3, 0)) # Additive blending (for premultiplied values): lighten gc0 = ngl.GraphicConfig( above, blend=True, blend_src_factor="one", blend_dst_factor="one", blend_src_factor_a="one", blend_dst_factor_a="one", ) # Multiply blending (for premultiplied values): darken gc1 = ngl.GraphicConfig( above, blend=True, blend_src_factor="zero", blend_dst_factor="src_color", blend_src_factor_a="zero", blend_dst_factor_a="src_alpha", ) # Select has 3 branches: simple over blending, additive blending, multiply # blending select = ngl.UserSelect(branches=(above, gc0, gc1)) def keyframes_callback(t_id): # 4 states: the for the 3 blending branches and one extra for nothing # (branch ID overflow). We remain on the each state for 2 frames. select.set_branch((t_id // 2) % 4) @test_fingerprint(nb_keyframes=8, keyframes_callback=keyframes_callback, tolerance=1, exercise_serialization=False) @scene(branch=scene.Range([0, 3])) def scene_func(cfg, branch=0): cfg.aspect_ratio = (1, 1) select.set_branch(branch) return ngl.Group(children=(below, select)) return scene_func
def _get_blending_scene_with_args(cfg, colored_circles, circle, prog, positions, bname, bcolor, **bparams): g = ngl.Group(label=bname) if bcolor is not None: blend_bg = _get_background_circles(circle, prog, positions, bcolor) blend_bg.set_label('background for {}'.format(bname)) g.add_children(blend_bg) blended_circles = ngl.GraphicConfig(colored_circles, blend=True, **bparams) g.add_children(blended_circles) return g
def shape_diamond_colormask(_): color_write_masks = ("r+g+b+a", "r+g+a", "g+b+a", "r+b+a") geometry = ngl.Circle(npoints=5) render = ngl.RenderColor(COLORS.white, geometry=geometry) scenes = [ ngl.GraphicConfig(render, color_write_mask=cwm) for cwm in color_write_masks ] return autogrid_simple(scenes)
def stl(cfg, stl=None, scale=0.8): """Load and display a sphere generated with OpenSCAD""" if stl is None: # generated with: echo 'sphere($fn=15);'>sphere.scad; openscad sphere.scad -o sphere.stl stl = op.join(op.dirname(__file__), "data", "sphere.stl") normals_data = array.array("f") vertices_data = array.array("f") solid_label = None normal = None with open(stl) as fp: for line in fp.readlines(): line = line.strip() if line.startswith("solid"): solid_label = line.split(None, 1)[1] elif line.startswith("facet normal"): _, _, normal = line.split(None, 2) normal = [float(f) for f in normal.split()] elif normal and line.startswith("vertex"): _, vertex = line.split(None, 1) vertex = [float(f) for f in vertex.split()] normals_data.extend(normal) vertices_data.extend(vertex) vertices = ngl.BufferVec3(data=vertices_data) normals = ngl.BufferVec3(data=normals_data) g = ngl.Geometry(vertices=vertices, normals=normals) p = ngl.Program(vertex=cfg.get_vert("colored-normals"), fragment=cfg.get_frag("colored-normals")) p.update_vert_out_vars(var_normal=ngl.IOVec3(), var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) solid = ngl.Render(g, p, label=solid_label) solid = ngl.GraphicConfig(solid, depth_test=True) solid = ngl.Scale(solid, [scale] * 3) for i in range(3): rot_animkf = ngl.AnimatedFloat([ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1)) ]) axis = [int(i == x) for x in range(3)] solid = ngl.Rotate(solid, axis=axis, angle=rot_animkf) camera = ngl.Camera(solid) camera.set_eye(2.0, 2.0, 2.0) 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(1.0, 10.0) return camera
def compare(cfg, scene0, scene1, xsplit): """ Compare two scenes by splitting them vertically. The scene generated by this function relies on the stencil buffer, and thus can not work properly if one of the compared scenes uses it. """ # Fill the stencil buffer with 1's on the left side, and 0's on the right scene_mask = ngl.RenderColor() scene_mask = ngl.Scale(scene_mask, factors=(xsplit, 1, 1), anchor=(-1, 0, 0)) scene_mask = ngl.GraphicConfig( scene_mask, color_write_mask= "", # no need to write the color themselves, only the stencil stencil_test=True, stencil_ref=1, stencil_read_mask=0, stencil_write_mask=0xFF, stencil_fail="replace", stencil_depth_fail="replace", stencil_depth_pass="******", ) # Draw the 1st scene where the stencil is equal to 1 (left) scene0 = ngl.GraphicConfig(scene0, stencil_func="equal") # Draw the 2nd scene where the stencil is not equal to 1 (right) scene1 = ngl.GraphicConfig(scene1, stencil_func="notequal") stencil_test = ngl.GraphicConfig( ngl.Group(children=(scene0, scene1)), stencil_test=True, stencil_ref=1, stencil_read_mask=0xFF, stencil_write_mask=0, stencil_fail="keep", stencil_depth_fail="keep", stencil_depth_pass="******", ) return ngl.Group(children=(scene_mask, stencil_test))
def animated_camera(cfg, rotate=True): """Animated camera around a scene""" g = ngl.Group() q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) node = ngl.RenderTexture(t, geometry=q) g.add_children(node) translate = ngl.Translate(node, vector=(-0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(-0.6, -0.5, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, -0.5, -1)) g.add_children(translate) 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_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(10, (0.0, 0.0, 3.0), "exp_out") ] node = ngl.Translate(ngl.Identity(), vector=ngl.AnimatedVec3(tr_animkf)) if rotate: rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out") ] node = ngl.Rotate(node, axis=(0, 1, 0), angle=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(node) perspective_animkf = [ ngl.AnimKeyFrameVec2(0.5, (60.0, cfg.aspect_ratio_float)), ngl.AnimKeyFrameVec2(cfg.duration, (45.0, cfg.aspect_ratio_float), "exp_out"), ] camera.set_perspective(ngl.AnimatedVec2(perspective_animkf)) return camera
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 texture_scissor(cfg): cfg.aspect_ratio = (1, 1) render = ngl.RenderColor(COLORS.orange) 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], clear_color=(0, 0, 0, 1)) render = ngl.RenderTexture(texture) return ngl.Group(children=(rtt, render))
def _get_shape_scene(cfg, shape, cull_mode): cfg.aspect_ratio = (1, 1) geometry_cls = dict( triangle=ngl.Triangle, quad=ngl.Quad, circle=ngl.Circle, ) geometry = geometry_cls[shape]() node = _render_shape(geometry, COLORS.sgreen) return ngl.GraphicConfig(node, cull_mode=cull_mode)
def transform_animated_camera(cfg): cfg.duration = 5.0 g = ngl.Group() elems = ( # fmt: off (COLORS.red, None), (COLORS.yellow, (-0.6, 0.8, -1)), (COLORS.green, (0.6, 0.8, -1)), (COLORS.cyan, (-0.6, -0.5, -1)), (COLORS.magenta, (0.6, -0.5, -1)), # fmt: on ) quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) for color, vector in elems: node = ngl.RenderColor(color, geometry=quad) 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_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(), vector=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), angle=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(eye_transform) perspective_animkf = [ ngl.AnimKeyFrameVec2(0.5, (60.0, cfg.aspect_ratio_float)), ngl.AnimKeyFrameVec2(cfg.duration, (45.0, cfg.aspect_ratio_float)), ] camera.set_perspective(ngl.AnimatedVec2(perspective_animkf)) return camera
def texture_clear_and_scissor(cfg): render = ngl.RenderColor(COLORS.white) graphic_config = ngl.GraphicConfig(render, scissor_test=True, scissor=(0, 0, 0, 0), color_write_mask="") texture = ngl.Texture2D(width=64, height=64) rtt = ngl.RenderToTexture(ngl.Identity(), [texture], clear_color=list(COLORS.orange) + [1]) render = ngl.RenderTexture(texture) return ngl.Group(children=(graphic_config, rtt, render))
def text(cfg, demo_str='Hello World!\n\nThis is a multi-line\ntext demonstration.', time_unit=0.05): '''Demonstrate the text node features (colors, scale, alignment, fitting, ...)''' random.seed(0) group = ngl.Group() cfg.duration = time_unit * 2 * len(demo_str) nb_chars = len(demo_str) for i in range(nb_chars): ascii_text = ngl.Text(demo_str[:i + 1], aspect_ratio=cfg.aspect_ratio, bg_color=(0.15, 0.15, 0.15, 1), font_scale=1 / 2.) start = i * time_unit text_range = [ngl.TimeRangeModeNoop(0), ngl.TimeRangeModeCont(start)] if i != nb_chars - 1: end = (i + 1) * time_unit text_range.append(ngl.TimeRangeModeNoop(end)) text_range_filter = ngl.TimeRangeFilter(ascii_text, ranges=text_range) group.add_children(text_range_filter) for valign in ('top', 'center', 'bottom'): for halign in ('left', 'center', 'right'): if (valign, halign) == ('center', 'center'): continue fg_color = list(colorsys.hls_to_rgb(random.uniform(0, 1), 0.5, 1.0)) + [1] aligned_text = ngl.Text('%s-%s' % (valign, halign), valign=valign, halign=halign, aspect_ratio=cfg.aspect_ratio, fg_color=fg_color, bg_color=(0, 0, 0, 0), font_scale=1 / 5.) group.add_children(aligned_text) 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 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)) 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, label='dove') render.update_frag_resources(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(vertex=cfg.get_vert('color'), 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.AnimatedVec4(color_animkf) render_bg.update_frag_resources(color=ucolor) return ngl.Group(children=(render_bg, render))
def filter_gamma_correct(cfg, linear=True): """This test operates a gamma correct blending (the blending happens in linear space)""" # Hue colors rotated clockwise dst = ngl.RenderGradient4( color_tl=COLORS.rose, color_tr=COLORS.blue, color_br=COLORS.sgreen, color_bl=COLORS.yellow, ) # Hue colors rotated counter-clockwise started with another color src = ngl.RenderGradient4( color_tl=COLORS.orange, color_tr=COLORS.magenta, color_br=COLORS.azure, color_bl=COLORS.green, ) # Screen blending so that working in linear space makes a significant # difference blend = ngl.GraphicConfig( ngl.Group(children=(dst, src)), blend=True, blend_src_factor="one", blend_dst_factor="one_minus_src_color", blend_src_factor_a="one", blend_dst_factor_a="zero", ) # Intermediate RTT so that we can gamma correct the result tex = ngl.Texture2D(width=320, height=240) rtt = ngl.RenderToTexture(blend, color_textures=[tex]) render = ngl.RenderTexture(tex) if linear: # The result of the combination is linear dst.add_filters(ngl.FilterSRGB2Linear()) src.add_filters(ngl.FilterSRGB2Linear()) # ...and we compress it back to sRGB render.add_filters(ngl.FilterLinear2sRGB()) return ngl.Group(children=(rtt, render))
def obj(cfg, n=0.5, model=None): """Load and display a cube object (generated with Blender)""" if model is None: model = op.join(op.dirname(__file__), "data", "model.obj") with open(model) as fp: vertices_data, uvs_data, normals_data = _load_model(fp) vertices = ngl.BufferVec3(data=vertices_data) texcoords = ngl.BufferVec2(data=uvs_data) normals = ngl.BufferVec3(data=normals_data) q = ngl.Geometry(vertices, texcoords, normals) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert("tex-tint-normals"), fragment=cfg.get_frag("tex-tint-normals")) p.update_vert_out_vars(var_normal=ngl.IOVec3(), var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) render = ngl.Render(q, p) render.update_frag_resources(tex0=t) render = ngl.GraphicConfig(render, depth_test=True) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * 2) ] rot = ngl.Rotate(render, label="roty", axis=(0, 1, 0), angle=ngl.AnimatedFloat(animkf)) camera = ngl.Camera(rot) camera.set_eye(2.0, 2.0, 2.0) 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(1.0, 10.0) return camera
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 time_remapping(cfg): ''' Time remapping in the following order: - nothing displayed for a while (but media prefetch happening in background) - first frame displayed for a while - normal playback - last frame displayed for a while (even though the media is closed) - nothing again until the end ''' m0 = cfg.medias[0] media_seek = 10 noop_duration = 2 prefetch_duration = 2 freeze_duration = 3 playback_duration = 5 range_start = noop_duration + prefetch_duration play_start = range_start + freeze_duration play_stop = play_start + playback_duration range_stop = play_stop + freeze_duration duration = range_stop + noop_duration cfg.duration = duration cfg.aspect_ratio = (m0.width, m0.height) media_animkf = [ ngl.AnimKeyFrameFloat(play_start, media_seek), ngl.AnimKeyFrameFloat(play_stop, media_seek + playback_duration), ] q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf)) m.set_sxplayer_min_level('verbose') t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) r = ngl.Render(q, p) r.update_frag_resources(tex0=t) time_ranges = [ ngl.TimeRangeModeNoop(0), ngl.TimeRangeModeCont(range_start), ngl.TimeRangeModeNoop(range_stop), ] rf = ngl.TimeRangeFilter(r, ranges=time_ranges, prefetch_time=prefetch_duration) base_string = 'media time: %2g to %2g\nscene time: %2g to %2g\ntime range: %2g to %2g' % ( media_seek, media_seek + playback_duration, play_start, play_stop, range_start, range_stop) text = ngl.Text(base_string, box_height=(0, 0.3, 0), box_corner=(-1, 1 - 0.3, 0), aspect_ratio=cfg.aspect_ratio, halign='left') group = ngl.Group() group.add_children(rf, text) steps = ( ('default color, nothing yet', 0, noop_duration), ('default color, media prefetched', noop_duration, range_start), ('first frame', range_start, play_start), ('normal playback', play_start, play_stop), ('last frame', play_stop, range_stop), ('default color, media released', range_stop, duration), ) for i, (description, start_time, end_time) in enumerate(steps): text = ngl.Text('%g to %g: %s' % (start_time, end_time, description), aspect_ratio=cfg.aspect_ratio, box_height=(0, 0.2, 0)) text_tr = ( ngl.TimeRangeModeNoop(0), ngl.TimeRangeModeCont(start_time), ngl.TimeRangeModeNoop(end_time), ) text_rf = ngl.TimeRangeFilter(text, ranges=text_tr, label='text-step-%d' % i) group.add_children(text_rf) 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 particules(cfg, particules=32): '''Particules demo using compute shaders and instancing''' random.seed(0) shader_version = '310 es' if cfg.backend == 'gles' else '430' shader_header = '#version %s\n' % shader_version compute_shader = shader_header + cfg.get_comp('particules') vertex_shader = shader_header + cfg.get_vert('particules') fragment_shader = shader_header + cfg.get_frag('particules') cfg.duration = 6 x = 64 p = x * particules positions = array.array('f') velocities = array.array('f') for i in range(p): positions.extend([ random.uniform(-1.0, 1.0), random.uniform(0.0, 1.0), 0.0, ]) velocities.extend([ random.uniform(-0.01, 0.01), random.uniform(-0.05, 0.05), ]) ipositions = ngl.Block(fields=[ngl.BufferVec3(data=positions)], layout='std430') ivelocities = ngl.Block(fields=[ngl.BufferVec2(data=velocities)], layout='std430') opositions = ngl.Block(fields=[ngl.BufferVec3(count=p)], 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) c = ngl.Compute(x, particules, 1, cp) c.update_uniforms( time=utime, duration=uduration, ) c.update_blocks( ipositions_buffer=ipositions, ivelocities_buffer=ivelocities, opositions_buffer=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, ) r = ngl.Render(quad, p, nb_instances=particules) r.update_uniforms(color=ngl.UniformVec4(value=(0, .6, .8, .9))) r.update_blocks(positions_buffer=opositions) r = ngl.GraphicConfig(r, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one') g = ngl.Group() g.add_children(c, r) return ngl.Camera(g)
def blending_and_stencil(cfg): '''Scene using blending and stencil graphic features''' cfg.duration = 5 random.seed(0) fragment = cfg.get_frag('color') program = ngl.Program(fragment=fragment) circle = ngl.Circle(npoints=256) cloud_color = ngl.UniformVec4(value=(1, 1, 1, 0.4)) main_group = ngl.Group() quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, program, label='sky') render.update_uniforms(color=ngl.UniformVec4(value=(0.2, 0.6, 1, 1))) 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.Render(circle, program, label='sun') render.update_uniforms(color=ngl.UniformVec4(value=(1, 0.8, 0, 1))) 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) render.update_uniforms(color=cloud_color) factor = random.random() * 0.4 + center[2] keyframe = cfg.duration * (random.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, anim=ngl.AnimatedVec3(animkf)) translate = ngl.Translate(scale, vector=(center[0], center[1], 0)) cloud_group.add_children(translate) config = ngl.GraphicConfig(cloud_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', 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
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(fragment=cfg.get_frag('mountain')) 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_textures(tex0=random_tex) render.update_uniforms(dim=ngl.UniformInt(random_dim)) render.update_uniforms(nb_layers=ngl.UniformInt(nb_layers)) render.update_uniforms(time=utime) render.update_uniforms(lacunarity=ngl.UniformFloat(2.0)) render.update_uniforms(gain=ngl.UniformFloat(0.5)) render.update_uniforms(mcolor=ngl.UniformVec4(mcolor)) render.update_uniforms(yoffset=uyoffset) render.update_uniforms(hscale=ngl.UniformFloat(hscale)) mountains.append(render) prog = ngl.Program(fragment=cfg.get_frag('color')) sky = ngl.Render(quad, prog) sky.update_uniforms(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