def _get_live_trf_function(spec, field_id, layout): fields = match_fields(spec, field_id) assert len(fields) == 1 field = fields[0] livechange_funcs = field['livechange'] def keyframes_callback(t_id): livechange_funcs[t_id]() @test_cuepoints(points=get_data_debug_positions(spec, field_id), nb_keyframes=len(livechange_funcs), keyframes_callback=keyframes_callback, tolerance=1, exercise_serialization=False, debug_positions=False) @scene(seed=scene.Range(range=[0, 100]), debug_positions=scene.Bool(), color_tint=scene.Bool(), trf_step=scene.Range(range=[0, len(livechange_funcs)])) def scene_func(cfg, seed=0, debug_positions=True, color_tint=False, trf_step=0): s = _live_scene(cfg, spec, field_id, seed, layout, debug_positions, color_tint) for i in range(trf_step): keyframes_callback(i) return s return scene_func
def _get_live_function(spec, field_id, layout): fields = match_fields(spec, field_id) assert len(fields) == 1 field = fields[0] data_src = field['livechange'] def keyframes_callback(t_id): if t_id: v = data_src[t_id - 1] field['node'].set_value(*v) @test_cuepoints(points=get_data_debug_positions(spec, field_id), nb_keyframes=len(data_src) + 1, keyframes_callback=keyframes_callback, tolerance=1, exercise_serialization=False, debug_positions=False) @scene(seed=scene.Range(range=[0, 100]), debug_positions=scene.Bool(), color_tint=scene.Bool()) def scene_func(cfg, seed=0, debug_positions=True, color_tint=False): return _live_scene(cfg, spec, field_id, seed, layout, debug_positions, color_tint) return scene_func
def _get_data_function(field_id, layout): nb_keyframes = 5 if 'animated' in field_id else 1 spec = _get_data_spec(layout) @test_cuepoints(points=get_data_debug_positions(spec, field_id), nb_keyframes=nb_keyframes, tolerance=1, debug_positions=False) @scene(seed=scene.Range(range=[0, 100]), debug_positions=scene.Bool(), color_tint=scene.Bool()) def scene_func(cfg, seed=0, debug_positions=True, color_tint=False): return _data_scene(cfg, spec, field_id, seed, layout, debug_positions, color_tint) return scene_func
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_data_function(spec, category, field_type, layout): nb_keyframes = 5 if "animated" in category else 1 fields = match_fields(spec, category, field_type) @test_cuepoints( points=get_data_debug_positions(fields), nb_keyframes=nb_keyframes, tolerance=1, debug_positions=False, ) @scene(seed=scene.Range(range=[0, 100]), debug_positions=scene.Bool(), color_tint=scene.Bool()) def scene_func(cfg, seed=0, debug_positions=True, color_tint=False): cfg.duration = ANIM_DURATION return get_field_scene(cfg, spec, category, field_type, seed, debug_positions, layout, color_tint) return scene_func
import pynodegl as ngl from pynodegl_utils.misc import scene @scene(overlap_time=scene.Range(range=[0, 5], unit_base=10), dim=scene.Range(range=[1, 10])) def queued_medias(cfg, overlap_time=1., dim=3): '''Queue of medias, mainly used as a demonstration for the prefetch/release mechanism''' qw = qh = 2. / dim nb_videos = dim * dim tqs = [] p = ngl.Program() for y in range(dim): for x in range(dim): video_id = y * dim + x start = video_id * cfg.duration / nb_videos animkf = [ngl.AnimKeyFrameFloat(start, 0)] m = ngl.Media(cfg.medias[video_id % len(cfg.medias)].filename, time_anim=ngl.AnimatedTime(animkf)) m.set_label('media #%d' % video_id) corner = (-1. + x * qw, 1. - (y + 1) * qh, 0) q = ngl.Quad(corner, (qw, 0, 0), (0, qh, 0)) t = ngl.Texture2D(data_src=m) render = ngl.Render(q, p) render.set_label('render #%d' % video_id) render.update_textures(tex0=t) rf = ngl.TimeRangeFilter(render) if start:
fragment=cfg.get_frag('texture')) p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(q, p) render.update_frag_resources(tex0=t) if progress_bar: p.set_fragment(cfg.get_frag('progress-bar')) media_duration = ngl.UniformFloat(m0.duration) ar = ngl.UniformFloat(cfg.aspect_ratio_float) render.update_frag_resources(media_duration=media_duration, ar=ar) return render @scene(speed=scene.Range(range=[0.01, 2], unit_base=1000)) def playback_speed(cfg, speed=1.0): '''Adjust media playback speed using animation keyframes''' m0 = cfg.medias[0] media_duration = m0.duration initial_seek = min(media_duration, 5) rush_duration = media_duration - initial_seek cfg.duration = rush_duration / speed cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) time_animkf = [ ngl.AnimKeyFrameFloat(0, initial_seek), ngl.AnimKeyFrameFloat(cfg.duration, media_duration) ] m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(time_animkf))
def _get_cropboard_function(set_indices=False): @test_fingerprint(nb_keyframes=10, tolerance=1) @scene(dim_clr=scene.Range(range=[1, 50]), dim_cut=scene.Range(range=[1, 50])) def cropboard(cfg, dim_clr=3, dim_cut=9): cfg.duration = 5. + 1. random.seed(0) get_rand = lambda: array.array( 'f', [random.random() for i in range(dim_clr**2 * 3)]) nb_kf = 2 buffers = [get_rand() for i in range(nb_kf)] random_animkf = [] time_scale = cfg.duration / float(nb_kf) for i, buf in enumerate(buffers + [buffers[0]]): random_animkf.append(ngl.AnimKeyFrameBuffer(i * time_scale, buf)) random_buffer = ngl.AnimatedBufferVec3(keyframes=random_animkf) random_tex = ngl.Texture2D(data_src=random_buffer, width=dim_clr, height=dim_clr) kw = kh = 1. / dim_cut qw = qh = 2. / dim_cut p = ngl.Program(vertex=cfg.get_vert('cropboard'), fragment=cfg.get_frag('texture')) uv_offset_buffer = array.array('f') translate_a_buffer = array.array('f') translate_b_buffer = array.array('f') if set_indices: indices = array.array('H', [0, 2, 1, 3]) indices_buffer = ngl.BufferUShort(data=indices) vertices = array.array('f', [ 0, 0, 0, qw, qh, 0, qw, 0, 0, 0, qh, 0, ]) uvcoords = array.array('f', [ 0, 1.0, kw, 1.0 - kh, kw, 1.0, 0, 1.0 - kh, ]) vertices_buffer = ngl.BufferVec3(data=vertices) uvcoords_buffer = ngl.BufferVec2(data=uvcoords) q = ngl.Geometry(topology='triangle_fan', vertices=vertices_buffer, uvcoords=uvcoords_buffer, indices=indices_buffer) else: q = ngl.Quad(corner=(0, 0, 0), width=(qw, 0, 0), height=(0, qh, 0), uv_corner=(0, 0), uv_width=(kw, 0), uv_height=(0, kh)) for y in range(dim_cut): for x in range(dim_cut): uv_offset = [x * kw, (y + 1.) * kh - 1.] src = [random.uniform(-2, 2), random.uniform(-2, 2)] dst = [x * qw - 1., 1. - (y + 1.) * qh] uv_offset_buffer.extend(uv_offset) translate_a_buffer.extend(src) translate_b_buffer.extend(dst) utime_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration - 1., 1) ] utime = ngl.AnimatedFloat(utime_animkf) render = ngl.Render(q, p, nb_instances=dim_cut**2) render.update_textures(tex0=random_tex) render.update_uniforms(time=utime) render.update_instance_attributes( uv_offset=ngl.BufferVec2(data=uv_offset_buffer), translate_a=ngl.BufferVec2(data=translate_a_buffer), translate_b=ngl.BufferVec2(data=translate_b_buffer), ) return render return cropboard
label='roty', axis=(0, 1, 0), anim=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 @scene(stl=scene.File(filter='STL files (*.stl)'), scale=scene.Range(range=[0.01, 10], unit_base=100)) def stl(cfg, stl=None, scale=.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()
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 @scene(dim=scene.Range(range=[1, 100])) def animated_buffer(cfg, dim=50): '''Transform a random buffer content using animations''' cfg.duration = 5. random.seed(0) get_rand = lambda: array.array( 'f', [random.random() for i in range(dim**2 * 3)]) nb_kf = int(cfg.duration) buffers = [get_rand() for i in range(nb_kf)] random_animkf = [] time_scale = cfg.duration / float(nb_kf) for i, buf in enumerate(buffers + [buffers[0]]): random_animkf.append(ngl.AnimKeyFrameBuffer(i * time_scale, buf)) random_buffer = ngl.AnimatedBufferVec3(keyframes=random_animkf) random_tex = ngl.Texture2D(data_src=random_buffer, width=dim, height=dim)
def _render_buffer(cfg, w, h): n = w * h data = array.array('B', [i * 255 // n for i in range(n)]) buf = ngl.BufferUByte(data=data) texture = ngl.Texture2D(width=w, height=h, data_src=buf) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=_RENDER_BUFFER_FRAG) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(ngl.Quad(), program) render.update_frag_resources(tex0=texture) return render @test_fingerprint() @scene(w=scene.Range(range=[1, 128]), h=scene.Range(range=[1, 128])) def texture_data(cfg, w=4, h=5): cfg.aspect_ratio = (1, 1) return _render_buffer(cfg, w, h) @test_fingerprint() @scene(dim=scene.Range(range=[1, 100])) def texture_data_animated(cfg, dim=8): cfg.duration = 3.0 random.seed(0) nb_kf = int(cfg.duration) buffers = [get_random_color_buffer(dim) for i in range(nb_kf)] random_animkf = [] time_scale = cfg.duration / float(nb_kf) for i, buf in enumerate(buffers + [buffers[0]]):
# from pynodegl_utils.misc import scene from pynodegl_utils.toolbox.colors import COLORS import pynodegl as ngl @scene( txt=scene.Text(), fg_color=scene.Color(), bg_color=scene.Color(), box_corner=scene.Vector(n=3, minv=(-1, -1, -1), maxv=(1, 1, 1)), box_width=scene.Vector(n=3, minv=(-10, -10, -10), maxv=(10, 10, 10)), box_height=scene.Vector(n=3, minv=(-10, -10, -10), maxv=(10, 10, 10)), padding=scene.Range(range=[0, 100]), font_scale=scene.Range(range=[0, 15], unit_base=100), valign=scene.List(choices=("top", "center", "bottom")), halign=scene.List(choices=("left", "center", "right")), ) def text( cfg, txt="the quick brown fox\njumps over the lazy dog", fg_color=COLORS.cgreen, bg_color=(0.3, 0.3, 0.3), box_corner=(-1 + 0.25, -1 + 0.25, 0), box_width=(1.5, 0, 0), box_height=(0, 1.5, 0), padding=2, font_scale=1.3, valign="center",
def _get_cropboard_function(set_indices=False): @test_fingerprint(nb_keyframes=10, tolerance=1) @scene(dim_clr=scene.Range(range=[1, 50]), dim_cut=scene.Range(range=[1, 50])) def cropboard(cfg, dim_clr=3, dim_cut=9): cfg.duration = 5.0 + 1.0 nb_kf = 2 buffers = [ get_random_color_buffer(cfg.rng, dim_clr) for _ in range(nb_kf) ] random_animkf = [] time_scale = cfg.duration / float(nb_kf) for i, buf in enumerate(buffers + [buffers[0]]): random_animkf.append(ngl.AnimKeyFrameBuffer(i * time_scale, buf)) random_buffer = ngl.AnimatedBufferVec4(keyframes=random_animkf) random_tex = ngl.Texture2D(data_src=random_buffer, width=dim_clr, height=dim_clr) kw = kh = 1.0 / dim_cut qw = qh = 2.0 / dim_cut p = ngl.Program(vertex=cfg.get_vert("cropboard"), fragment=cfg.get_frag("texture")) p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2()) uv_offset_buffer = array.array("f") translate_a_buffer = array.array("f") translate_b_buffer = array.array("f") if set_indices: indices = array.array("H", [0, 2, 1, 1, 3, 0]) indices_buffer = ngl.BufferUShort(data=indices) vertices = array.array( "f", [ # fmt: off 0, 0, 0, qw, qh, 0, qw, 0, 0, 0, qh, 0, # fmt: on ], ) uvcoords = array.array( "f", [ # fmt: off 0, 1.0, kw, 1.0 - kh, kw, 1.0, 0, 1.0 - kh, # fmt: on ], ) vertices_buffer = ngl.BufferVec3(data=vertices) uvcoords_buffer = ngl.BufferVec2(data=uvcoords) q = ngl.Geometry(vertices=vertices_buffer, uvcoords=uvcoords_buffer, indices=indices_buffer) else: q = ngl.Quad( corner=(0, 0, 0), width=(qw, 0, 0), height=(0, qh, 0), uv_corner=(0, 0), uv_width=(kw, 0), uv_height=(0, kh), ) for y in range(dim_cut): for x in range(dim_cut): uv_offset = [x * kw, (y + 1.0) * kh - 1.0] src = [cfg.rng.uniform(-2, 2), cfg.rng.uniform(-2, 2)] dst = [x * qw - 1.0, 1.0 - (y + 1.0) * qh] uv_offset_buffer.extend(uv_offset) translate_a_buffer.extend(src) translate_b_buffer.extend(dst) utime_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration - 1.0, 1) ] utime = ngl.AnimatedFloat(utime_animkf) render = ngl.Render(q, p, nb_instances=dim_cut**2) render.update_frag_resources(tex0=random_tex) render.update_vert_resources(time=utime) render.update_instance_attributes( uv_offset=ngl.BufferVec2(data=uv_offset_buffer), translate_a=ngl.BufferVec2(data=translate_a_buffer), translate_b=ngl.BufferVec2(data=translate_b_buffer), ) return render return cropboard
import pynodegl as ngl from pynodegl_utils.misc import scene @scene(uv_corner_x=scene.Range(range=[0, 1], unit_base=100), uv_corner_y=scene.Range(range=[0, 1], unit_base=100), uv_width=scene.Range(range=[0, 1], unit_base=100), uv_height=scene.Range(range=[0, 1], unit_base=100), progress_bar=scene.Bool()) def centered_media(cfg, uv_corner_x=0, uv_corner_y=0, uv_width=1, uv_height=1, progress_bar=True): '''A simple centered media with an optional progress bar in the shader''' m0 = cfg.medias[0] cfg.duration = m0.duration cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0), (uv_corner_x, uv_corner_y), (uv_width, 0), (0, uv_height)) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) p = ngl.Program() render = ngl.Render(q, p) render.update_textures(tex0=t) if progress_bar: p.set_fragment(cfg.get_frag('progress-bar'))
text_node = ngl.Text('#%02d %s' % (field['pos'], field['name']), box_corner=(ax, ay + field_hpos * field_h, 0), box_width=(aw / 2., 0, 0), box_height=(0, field_h, 0), fg_color=list(field['color']) + [1], halign='left', aspect_ratio=cfg.aspect_ratio) text_group.add_children(text_node) quad = ngl.Quad((ax + aw / 2., ay, 0), (aw / 2., 0, 0), (0, ah - title_h, 0)) render = get_render(cfg, quad, fields, block_definition, color_definition, block_fields, color_fields, layout) return ngl.Group(children=(title_node, text_group, render)) @scene(seed=scene.Range(range=[0, 100]), layout=scene.List(choices=LAYOUTS), color_tint=scene.Bool()) def debug_block(cfg, seed=0, layout=LAYOUTS[0], color_tint=True): cfg.duration = ANIM_DURATION cfg.aspect_ratio = (1, 1) spec = _get_data_spec(layout) fields_info, block_fields, color_fields, block_definition, color_definition = get_random_block_info(spec, seed, layout, color_tint=color_tint) fields_single = [f for f in fields_info if f['category'] == 'single'] fields_array = [f for f in fields_info if f['category'] == 'array'] fields_animated = [f for f in fields_info if f['category'].startswith('animated')] field_specs = ( (fields_single, (-1/3., -1, 2/3., 2.), 'Single fields'),
ngl.AnimKeyFrameVec4(0, square_color), ngl.AnimKeyFrameVec4(cfg.duration / 2., circle_color, interp), ngl.AnimKeyFrameVec4(cfg.duration, square_color, interp), ] ucolor = ngl.AnimatedVec4(color_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=ucolor) return render @scene(npoints=scene.Range(range=[3, 100])) 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])
import os.path as op import array import colorsys import math import random import pynodegl as ngl from pynodegl_utils.misc import scene @scene(xsplit=scene.Range(range=[0, 1], unit_base=100), trilinear=scene.Bool()) def lut3d(cfg, xsplit=.3, trilinear=True): '''Lookup Table 3D using a Texture3D''' level = 6 level2 = level**2 # Generated with `ffmpeg -f lavfi -i haldclutsrc=6,curves=vintage -f # rawvideo -frames:v 1 lut3d.raw` lut3d_filename = op.join(op.dirname(__file__), 'data', 'lut3d.raw') cfg.files.append(lut3d_filename) lut3d_buf = ngl.BufferUBVec3(filename=lut3d_filename) lut3d_tex = ngl.Texture3D(data_src=lut3d_buf, width=level2, height=level2, depth=level2) if trilinear: lut3d_tex.set_min_filter('linear') lut3d_tex.set_mag_filter('linear') m0 = cfg.medias[0] cfg.duration = m0.duration cfg.aspect_ratio = (m0.width, m0.height) video = ngl.Media(m0.filename)
} """) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) media = ngl.Media(m0.filename) texture = ngl.Texture2D(data_src=media) program = ngl.Program(vertex=vert, fragment=frag) program.update_vert_out_vars(uv=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture, duration=ngl.UniformFloat(cfg.duration)) return render @test_fingerprint(width=1024, height=1024, nb_keyframes=30, tolerance=1) @scene(overlap_time=scene.Range(range=[0, 10], unit_base=10), dim=scene.Range(range=[1, 10])) def media_queue(cfg, overlap_time=7.0, dim=3): cfg.duration = 10 cfg.aspect_ratio = (1, 1) nb_medias = dim * dim medias = [ m.filename for m in cfg.medias if m.filename.endswith(("mp4", "jpg")) ] queued_medias = [] ag = AutoGrid(range(nb_medias)) for video_id, _, col, pos in ag: start = video_id * cfg.duration / nb_medias
(0.2, 0.8, 0.0), ) # fmt: on keyframes = ( ngl.PathKeyMove(to=points[0]), ngl.PathKeyBezier3(control1=controls[0], control2=controls[1], to=points[1]), ) path = ngl.Path(keyframes) return _path_scene(cfg, path, points, controls, easing=easing) @scene(tension=scene.Range(range=[0.01, 2], unit_base=100)) def catmull(cfg, tension=0.5): cfg.duration = 3 # fmt: off points = ( (-0.62, -0.30, 0.0), (-0.36, 0.40, 0.0), (0.04, -0.27, 0.0), (0.36, 0.28, 0.0), (0.65, -0.04, 0.0), ) controls = ( (-0.84, 0.07, 0.0), (0.84, 0.04, 0.0), ) # fmt: on
} """) program = ngl.Program(vertex=vert, fragment=frag) program.update_vert_out_vars( color=ngl.IOVec4(precision_out="high", precision_in="low")) geometry = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0)) scene = ngl.Render(geometry, program) return scene def _render_shape(geometry, color): return ngl.RenderColor(color, geometry=geometry) @test_fingerprint() @scene(sz=scene.Range(range=[0.1, 2], unit_base=100), color=scene.Color()) def shape_triangle(cfg, sz=1, color=COLORS.orange): cfg.aspect_ratio = (1, 1) p0, p1, p2 = equilateral_triangle_coords(sz) geometry = ngl.Triangle(p0, p1, p2) return _render_shape(geometry, color) @test_fingerprint(samples=4) @scene(sz=scene.Range(range=[0.1, 2], unit_base=100), color=scene.Color()) def shape_triangle_msaa(cfg, sz=1, color=COLORS.orange): cfg.aspect_ratio = (1, 1) p0, p1, p2 = equilateral_triangle_coords(sz) geometry = ngl.Triangle(p0, p1, p2) return _render_shape(geometry, color)
cfg.aspect_ratio = (1, 1) cfg.duration = 2.0 shape = _transform_shape(cfg) anim = [ ngl.AnimKeyFrameVec3(0, (0, 0, 0)), ngl.AnimKeyFrameVec3(cfg.duration / 2.0, angles), ngl.AnimKeyFrameVec3(cfg.duration, (0, 0, 0)), ] return ngl.Skew(shape, angles=ngl.AnimatedVec3(anim), axis=axis, anchor=anchor) @test_fingerprint() @scene(angle=scene.Range(range=[0, 360], unit_base=10)) def transform_rotate(cfg, angle=123.4): cfg.aspect_ratio = (1, 1) shape = _transform_shape(cfg) return ngl.Rotate(shape, angle) @test_fingerprint() @scene(angle=scene.Range(range=[0, 360], unit_base=10), anchor=scene.Vector(n=3, minv=(-1, -1, -1), maxv=(1, 1, 1))) def transform_rotate_anchor(cfg, angle=123.4, anchor=(0.15, 0.35, 0.7)): cfg.aspect_ratio = (1, 1) shape = _transform_shape(cfg) return ngl.Rotate(shape, angle, anchor=anchor)
# The main overlay root = _get_random_layer(cfg, rng, t0, t1, enable_computes) group = ngl.Group(children=textures + [root]) camera = ngl.Camera(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_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(1.0, 10.0) return ngl.Group(children=(bg, camera)) @scene(seed=scene.Range(range=[0, 1000]), enable_computes=scene.Bool()) def benchmark_test(cfg, seed=82, enable_computes=True): """Function to be used for manual testing""" return _get_scene(cfg, seed, enable_computes) @test_fingerprint(width=1920, height=1080, nb_keyframes=120, tolerance=3) @scene() def benchmark_fingerprint_with_compute(cfg): return _get_scene(cfg, seed=0, enable_computes=True) @test_fingerprint(width=1920, height=1080, nb_keyframes=120, tolerance=3) @scene() def benchmark_fingerprint_without_compute(cfg): return _get_scene(cfg, seed=1, enable_computes=False)
from pynodegl_utils.toolbox.colors import COLORS from pynodegl_utils.toolbox.colors import get_random_color_buffer from pynodegl_utils.tests.cmp_fingerprint import test_fingerprint from pynodegl_utils.toolbox.shapes import equilateral_triangle_coords from pynodegl_utils.toolbox.grid import autogrid_simple 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_frag_resources(color=ngl.UniformVec4(value=color)) return render @test_fingerprint() @scene(sz=scene.Range(range=[0.1, 2], unit_base=100), color=scene.Color()) def shape_triangle(cfg, sz=1, color=COLORS['orange']): cfg.aspect_ratio = (1, 1) p0, p1, p2 = equilateral_triangle_coords(sz) geometry = ngl.Triangle(p0, p1, p2) return _render_shape(cfg, geometry, color) @test_fingerprint(samples=4) @scene(sz=scene.Range(range=[0.1, 2], unit_base=100), color=scene.Color()) def shape_triangle_msaa(cfg, sz=1, color=COLORS['orange']): cfg.aspect_ratio = (1, 1) p0, p1, p2 = equilateral_triangle_coords(sz) geometry = ngl.Triangle(p0, p1, p2)