def test_ctx_ownership(): viewer = ngl.Viewer() viewer2 = ngl.Viewer() assert viewer.configure(offscreen=1, width=16, height=16) == 0 assert viewer2.configure(offscreen=1, width=16, height=16) == 0 scene = ngl.Render(ngl.Quad()) viewer.set_scene(scene) viewer.draw(0) assert viewer2.set_scene(scene) != 0 viewer2.draw(0) del viewer del viewer2
def _get_scene( self, file0, file1, diff_mode=False, split=(0.5, 0.5), vertical_split=True, show_r=True, show_g=True, show_b=True, show_a=True, premultiplied=False, threshold=0.001, ): vert = pkgutil.get_data("pynodegl_utils.diff.shaders", "diff.vert") frag = pkgutil.get_data("pynodegl_utils.diff.shaders", "diff.frag") quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) prog = ngl.Program(vertex=vert, fragment=frag) prog.update_vert_out_vars( uv=ngl.IOVec2(), tex0_coord=ngl.IOVec2(), tex1_coord=ngl.IOVec2(), ) scene = ngl.Render(quad, prog) scene.update_frag_resources( tex0=ngl.Texture2D(data_src=ngl.Media(file0)), tex1=ngl.Texture2D(data_src=ngl.Media(file1)), split=ngl.UniformVec2(split, live_id="split"), diff_mode=ngl.UniformBool(diff_mode, live_id="diff_mode"), vertical_split=ngl.UniformBool(vertical_split, live_id="vertical_split"), show_r=ngl.UniformBool(show_r, live_id="show_r"), show_g=ngl.UniformBool(show_g, live_id="show_g"), show_b=ngl.UniformBool(show_b, live_id="show_b"), show_a=ngl.UniformBool(show_a, live_id="show_a"), premultiplied=ngl.UniformBool(premultiplied, live_id="premultiplied"), threshold=ngl.UniformFloat(threshold, live_id="threshold", live_max=0.1), ) scene.update_vert_resources( reframing_scale=ngl.UniformFloat( self._reframing_scale, live_id="reframing_scale", live_min=self._MIN_SCALE, live_max=self._MAX_SCALE, ), reframing_off=ngl.UniformVec2( self._reframing_off, live_id="reframing_off", live_min=(-self._MAX_SCALE, -self._MAX_SCALE), live_max=(self._MAX_SCALE, self._MAX_SCALE), ), ) return scene
def cropboard(cfg, dim=15): """Divided media using instancing draw and UV coords offsetting from a buffer""" m0 = cfg.medias[0] cfg.duration = 10 cfg.aspect_ratio = (m0.width, m0.height) kw = kh = 1.0 / dim qw = qh = 2.0 / dim p = ngl.Program(vertex=cfg.get_vert("cropboard"), fragment=cfg.get_frag("texture")) p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) uv_offset_buffer = array.array("f") translate_a_buffer = array.array("f") translate_b_buffer = array.array("f") 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): for x in range(dim): 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 * 2 / 3.0, 1, "exp_out") ] utime = ngl.AnimatedFloat(utime_animkf) render = ngl.Render(q, p, nb_instances=dim**2) render.update_frag_resources(tex0=t) 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
def _get_data_streamed_buffer_vec4_scene(cfg, scale, show_dbg_points): duration = _N cfg.duration = duration * scale cfg.aspect_ratio = (1, 1) size, data_size, = _N, _N * _N time_anim = None if scale != 1: kfs = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, duration), ] time_anim = ngl.AnimatedTime(kfs) pts_data = array.array('l') for i in range(duration): offset = 10000 if i == 0 else 0 pts_data.extend([i * 1000000 + offset]) vec4_data = array.array('f') for i in range(duration): for j in range(data_size): v = i / float(duration) + j / float(data_size * duration) vec4_data.extend([v, v, v, v]) pts_buffer = ngl.BufferInt64(data=pts_data) vec4_buffer = ngl.BufferVec4(data=vec4_data) streamed_buffer = ngl.StreamedBufferVec4(data_size, pts_buffer, vec4_buffer, time_anim=time_anim, label='data') streamed_block = ngl.Block(layout='std140', label='streamed_block', fields=(streamed_buffer, )) shader_params = dict(data_size=data_size, size=size) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program( vertex=_RENDER_STREAMEDBUFFER_VERT, fragment=_RENDER_STREAMEDBUFFER_FRAG % shader_params, ) program.update_vert_out_vars(var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(streamed=streamed_block) group = ngl.Group(children=(render, )) if show_dbg_points: cuepoints = _get_data_streamed_buffer_cuepoints() group.add_children(get_debug_points(cfg, cuepoints)) return group
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 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 rtt_load_attachment_nested(cfg): scene = _rtt_load_attachment(cfg) texture = ngl.Texture2D(width=16, height=16) rtt = ngl.RenderToTexture(scene, [texture]) 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()) foreground = ngl.Render(quad, program) foreground.update_frag_resources(tex0=texture) return ngl.Group(children=(rtt, foreground))
def api_hud(width=234, height=123): viewer = ngl.Viewer() assert viewer.configure(offscreen=1, width=width, height=height, backend=_backend) == 0 quad = ngl.Quad() render = ngl.Render(quad) scene = ngl.HUD(render) viewer.set_scene(scene) for i in range(60 * 3): viewer.draw(i / 60.) del viewer
def api_capture_buffer_lifetime(width=1024, height=1024): capture_buffer = bytearray(width * height * 4) viewer = ngl.Viewer() assert viewer.configure(offscreen=1, width=width, height=height, backend=_backend, capture_buffer=capture_buffer) == 0 del capture_buffer scene = ngl.Render(ngl.Quad()) viewer.set_scene(scene) viewer.draw(0) del viewer
def cropboard(cfg, dim=15): '''Divided media using instancing draw and UV coords offsetting from a buffer''' m0 = cfg.medias[0] random.seed(0) cfg.duration = 10 cfg.aspect_ratio = (m0.width, m0.height) kw = kh = 1. / dim qw = qh = 2. / dim p = ngl.Program(vertex=cfg.get_vert('cropboard'), fragment=cfg.get_frag('texture')) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) uv_offset_buffer = array.array('f') translate_a_buffer = array.array('f') translate_b_buffer = array.array('f') 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): for x in range(dim): 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 * 2 / 3., 1, 'exp_out') ] utime = ngl.AnimatedFloat(utime_animkf) render = ngl.Render(q, p, nb_instances=dim**2) render.update_textures(tex0=t) 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
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)) t = ngl.Texture2D(data_src=m) return ngl.RenderTexture(t, geometry=q)
def _rtt_load_attachment(): background = ngl.RenderColor(COLORS.white) render = ngl.RenderColor(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)) foreground = ngl.RenderTexture(texture, geometry=quad) return ngl.Group(children=(background, rtt, rtt_noop, foreground))
def api_ctx_ownership_subgraph(): for shared in (True, False): viewer = ngl.Viewer() viewer2 = ngl.Viewer() assert viewer.configure(offscreen=1, width=16, height=16, backend=_backend) == 0 assert viewer2.configure(offscreen=1, width=16, height=16, backend=_backend) == 0 quad = ngl.Quad() render1 = ngl.Render(quad) if not shared: quad = ngl.Quad() render2 = ngl.Render(quad) scene = ngl.Group([render1, render2]) viewer.set_scene(render2) viewer.draw(0) assert viewer2.set_scene(scene) != 0 viewer2.draw(0) del viewer del viewer2
def api_ctx_ownership_subgraph(): for shared in (True, False): ctx = ngl.Context() ctx2 = ngl.Context() assert ctx.configure(offscreen=1, width=16, height=16, backend=_backend) == 0 assert ctx2.configure(offscreen=1, width=16, height=16, backend=_backend) == 0 quad = ngl.Quad() render1 = _get_scene(quad) if not shared: quad = ngl.Quad() render2 = _get_scene(quad) scene = ngl.Group([render1, render2]) assert ctx.set_scene(render2) == 0 assert ctx.draw(0) == 0 assert ctx2.set_scene(scene) != 0 assert ctx2.draw(0) == 0 # XXX: drawing with no scene is allowed? del ctx del ctx2
def data_integer_iovars(cfg): cfg.aspect_ratio = (1, 1) vert = '''void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * ngl_position; var_color_u32 = color_u32; } ''' frag = '''void main() { ngl_out_color = vec4(var_color_u32) / 255.; }''' program = ngl.Program(vertex=vert, fragment=frag) program.update_vert_out_vars(var_color_u32=ngl.IOIVec4()) geometry = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0)) render = ngl.Render(geometry, program) render.update_vert_resources(color_u32=ngl.UniformIVec4(value=(0x50, 0x80, 0xa0, 0xff))) return render
def parallel_playback(cfg, fast=True, segment_time=2.): ''' Parallel media playback, flipping between the two sources. The fast version makes sure the textures continue to be updated even though they are not displayed. On the other hand, the slow version will update the textures only when needed to be displayed, causing potential seek in the underlying media, and thus undesired delays. ''' q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) p = ngl.Program() m1 = ngl.Media(cfg.medias[0].filename, label='media #1') m2 = ngl.Media(cfg.medias[0].filename, label='media #2') t1 = ngl.Texture2D(data_src=m1, label='texture #1') t2 = ngl.Texture2D(data_src=m2, label='texture #2') render1 = ngl.Render(q, p, label='render #1') render1.update_textures(tex0=t1) render2 = ngl.Render(q, p, label='render #2') render2.update_textures(tex0=t2) rf1 = ngl.TimeRangeFilter(render1) rf2 = ngl.TimeRangeFilter(render2) t = 0 rr1 = [] rr2 = [] while t < cfg.duration: rr1.append(ngl.TimeRangeModeCont(t)) rr1.append(ngl.TimeRangeModeNoop(t + segment_time)) rr2.append(ngl.TimeRangeModeNoop(t)) rr2.append(ngl.TimeRangeModeCont(t + segment_time)) t += 2 * segment_time rf1.add_ranges(*rr1) rf2.add_ranges(*rr2) g = ngl.Group() g.add_children(rf1, rf2) if fast: g.add_children(t1, t2) return g
def _get_random_geometry(rng): circle = lambda rng: ngl.Circle( radius=rng.uniform(1 / 4, 3 / 4), npoints=rng.randint(5, 25), ) quad = lambda rng: ngl.Quad( corner=_get_random_position(rng), width=(rng.uniform(-0.5, 0.5), rng.uniform(-0.5, 0.5), 0), height=(rng.uniform(-0.5, 0.5), rng.uniform(-0.5, 0.5), 0), ) triangle = lambda rng: ngl.Triangle( edge0=_get_random_position(rng), edge1=_get_random_position(rng), edge2=_get_random_position(rng), ) shape_func = rng.choice((circle, quad, triangle)) return shape_func(rng)
def _get_texture_cubemap_from_mrt_scene(cfg, samples=0): program = ngl.Program(vertex=_RENDER_TO_CUBEMAP_VERT, fragment=_RENDER_TO_CUBEMAP_FRAG, nb_frag_output=6) program.update_vert_out_vars(var_uvcoord=ngl.IOVec3()) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, program) cube = ngl.TextureCube(size=64, min_filter="linear", mag_filter="linear") rtt = ngl.RenderToTexture(render, [cube], samples=samples) program = ngl.Program(vertex=_RENDER_CUBEMAP_VERT, fragment=_RENDER_CUBEMAP_FRAG) program.update_vert_out_vars(var_uvcoord=ngl.IOVec3()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=cube) return ngl.Group(children=(rtt, render))
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 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 = 1 prefetch_duration = 2 freeze_duration = 1 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.AnimatedFloat(media_animkf)) t = ngl.Texture2D(data_src=m) r = ngl.Render(q) r.update_textures(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) return rf
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 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 playback_speed(cfg, speed=1.0): '''Adjust media playback speed using animation keyframes''' m0 = cfg.medias[0] media_duration = m0.duration initial_seek = 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.AnimatedFloat(time_animkf)) t = ngl.Texture2D(data_src=m) p = ngl.Program() render = ngl.Render(q, p) render.update_textures(tex0=t) return render
def flat_remap(cfg): cfg.medias = [Media('ngl-media-test.nut')] m0 = cfg.medias[0] cfg.duration = m0.duration cfg.aspect_ratio = (m0.width, m0.height) media_animkf = [ ngl.AnimKeyFrameFloat(-0.4, 1.833), ngl.AnimKeyFrameFloat(cfg.duration, 1.833), ] q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf)) t = ngl.Texture2D(data_src=m) render = ngl.Render(q) render.update_frag_resources(tex0=t) 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_frag_resources(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_time_scene(cfg): 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)) 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) return rf
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]]): 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, height=dim) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) prog = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) prog.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, prog) render.update_frag_resources(tex0=random_tex) return render
def texture_cubemap(cfg): n = 64 p = n * n cb_data = array.array('B', (255, 0, 0, 255) * p + (0, 255, 0, 255) * p + (0, 0, 255, 255) * p + (255, 255, 0, 255) * p + (0, 255, 255, 255) * p + (255, 0, 255, 255) * p) cb_buffer = ngl.BufferUBVec4(data=cb_data) cube = ngl.TextureCube(size=n, min_filter="linear", mag_filter="linear", data_src=cb_buffer) program = ngl.Program(vertex=_RENDER_CUBEMAP_VERT, fragment=_RENDER_CUBEMAP_FRAG) program.update_vert_out_vars(var_uvcoord=ngl.IOVec3()) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, program) render.update_frag_resources(tex0=cube) return render
def _live_scene(cfg, spec, field_id, seed, layout, debug_positions, color_tint): cfg.duration = 0 cfg.aspect_ratio = (1, 1) fields_info, block_fields, color_fields, block_definition, color_definition = get_random_block_info( spec, seed, layout, color_tint=color_tint) fields = match_fields(fields_info, field_id) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = get_render(cfg, quad, fields, block_definition, color_definition, block_fields, color_fields, layout, debug_positions=debug_positions) return render
def _data_vertex_and_fragment_blocks(cfg, layout): """ This test ensures that the block bindings are properly set by pgcraft when UBOs or SSBOs are bound to different stages. """ cfg.aspect_ratio = (1, 1) src = ngl.Block( fields=[ ngl.UniformVec3(value=COLORS.red, label="color"), ngl.UniformFloat(value=0.5, label="opacity"), ], layout="std140", ) dst = ngl.Block( fields=[ ngl.UniformVec3(value=COLORS.white, label="color"), ], layout=layout, ) vert = textwrap.dedent("""\ void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0); var_src = vec4(src.color, 1.0) * src.opacity; } """) frag = textwrap.dedent("""\ void main() { vec3 color = var_src.rgb + (1.0 - var_src.a) * dst.color; ngl_out_color = vec4(color, 1.0); } """) program = ngl.Program(vertex=vert, fragment=frag) program.update_vert_out_vars(var_src=ngl.IOVec4(), ) geometry = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0)) render = ngl.Render(geometry, program) render.update_vert_resources(src=src) render.update_frag_resources(dst=dst) return render