def queued_medias(cfg, overlap_time=1., dim=3): '''Queue of medias, mainly used as a demonstration for the prefetch/release mechanism''' nb_videos = dim * dim tqs = [] q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) ag = AutoGrid(range(nb_videos)) for video_id, _, col, pos in ag: 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) 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()) render = ngl.Render(q, program) render.set_label('render #%d' % video_id) render.update_frag_resources(tex0=t) render = ag.place_node(render, (col, pos)) rf = ngl.TimeRangeFilter(render) if start: rf.add_ranges(ngl.TimeRangeModeNoop(0)) rf.add_ranges(ngl.TimeRangeModeCont(start), ngl.TimeRangeModeNoop(start + cfg.duration/nb_videos + overlap_time)) tqs.append(rf) return ngl.Group(children=tqs)
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,format=rgba # -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.BufferUBVec4(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) video_tex = ngl.Texture2D(data_src=video) prog = ngl.Program(fragment=cfg.get_frag('lut3d'), vertex=cfg.get_vert('lut3d')) prog.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, prog) render.update_frag_resources(tex0=video_tex, lut3d=lut3d_tex) render.update_frag_resources(xsplit=ngl.UniformFloat(value=xsplit)) return render
def quaternion(cfg): '''Animated quaternion used to rotate a plane''' cfg.duration = 10. step = cfg.duration / 5. x = math.sqrt(0.5) quat_animkf = [ ngl.AnimKeyFrameQuat(0 * step, (0, 0, 0, 1)), ngl.AnimKeyFrameQuat(1 * step, (0, 0, -x, x)), ngl.AnimKeyFrameQuat(2 * step, (0, 1, 0, 0)), ngl.AnimKeyFrameQuat(3 * step, (1, 0, 0, 0)), ngl.AnimKeyFrameQuat(4 * step, (x, 0, 0, x)), ngl.AnimKeyFrameQuat(5 * step, (0, 0, 0, 1)), ] quat = ngl.AnimatedQuat(quat_animkf, as_mat4=True) q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert('uniform-mat4'), fragment=cfg.get_frag('texture')) 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.update_vert_resources(transformation_matrix=quat) camera = ngl.Camera(render) camera.set_eye(0.0, 0.0, 4.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 _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 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 centered_media(cfg, uv_corner=(0, 0), uv_width=(1, 0), uv_height=(0, 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, uv_width, uv_height) m = ngl.Media(m0.filename) 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()) 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
def lut3d(cfg, xsplit=0.3, trilinear=True): """Lookup Table 3D using a Texture3D""" level = 6 level2 = level**2 # Generated with `ffmpeg -f lavfi -i haldclutsrc=6,curves=vintage,format=rgba # -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.BufferUBVec4(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) video_tex = ngl.Texture2D(data_src=video) scene_tex = ngl.RenderTexture(video_tex) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) prog_lut = ngl.Program(fragment=cfg.get_frag("lut3d"), vertex=cfg.get_vert("lut3d")) prog_lut.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) scene_lut = ngl.Render(quad, prog_lut) scene_lut.update_frag_resources(tex0=video_tex, lut3d=lut3d_tex) return compare(cfg, scene_tex, scene_lut, xsplit)
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('auto_depth') 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')) 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 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 simple_transition(cfg, transition_start=2, transition_duration=4): """Fading transition between two medias""" cfg.duration = transition_start * 2 + transition_duration vertex = cfg.get_vert("dual-tex") fragment = cfg.get_frag("tex-mix") q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) p1_2 = ngl.Program(vertex=vertex, fragment=fragment) p1_2.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_tex1_coord=ngl.IOVec2()) m1 = ngl.Media(cfg.medias[0].filename, label="media #1") m2 = ngl.Media(cfg.medias[1 % len(cfg.medias)].filename, label="media #2") animkf_m2 = [ ngl.AnimKeyFrameFloat(transition_start, 0), ngl.AnimKeyFrameFloat(transition_start + cfg.duration, cfg.duration), ] m2.set_time_anim(ngl.AnimatedTime(animkf_m2)) t1 = ngl.Texture2D(data_src=m1, label="texture #1") t2 = ngl.Texture2D(data_src=m2, label="texture #2") render1 = ngl.RenderTexture(t1, label="render #1") render2 = ngl.RenderTexture(t2, label="render #2") delta_animkf = [ ngl.AnimKeyFrameFloat(transition_start, 1.0), ngl.AnimKeyFrameFloat(transition_start + transition_duration, 0.0), ] delta = ngl.AnimatedFloat(delta_animkf) render1_2 = ngl.Render(q, p1_2, label="transition") render1_2.update_frag_resources(tex0=t1, tex1=t2) render1_2.update_frag_resources(delta=delta) rr1 = [] rr2 = [] rr1_2 = [] rr1.append(ngl.TimeRangeModeNoop(transition_start)) rr2.append(ngl.TimeRangeModeNoop(0)) rr2.append(ngl.TimeRangeModeCont(transition_start + transition_duration)) rr1_2.append(ngl.TimeRangeModeNoop(0)) rr1_2.append(ngl.TimeRangeModeCont(transition_start)) rr1_2.append(ngl.TimeRangeModeNoop(transition_start + transition_duration)) rf1 = ngl.TimeRangeFilter(render1, ranges=rr1) rf2 = ngl.TimeRangeFilter(render2, ranges=rr2) rf1_2 = ngl.TimeRangeFilter(render1_2, ranges=rr1_2) g = ngl.Group() g.add_children(rf1, rf1_2, rf2) return g
def histogram(cfg): """Histogram using compute shaders""" m0 = cfg.medias[0] cfg.duration = m0.duration cfg.aspect_ratio = (m0.width, m0.height) g = ngl.Group() m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) h = ngl.Block(label="histogram_block", layout="std430") h.add_fields( ngl.BufferUInt(256, label="r"), ngl.BufferUInt(256, label="g"), ngl.BufferUInt(256, label="b"), ngl.UniformUInt(label="maximum"), ) r = ngl.RenderTexture(t) proxy_size = 128 proxy = ngl.Texture2D(width=proxy_size, height=proxy_size) rtt = ngl.RenderToTexture(r) rtt.add_color_textures(proxy) g.add_children(rtt) compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-clear"), workgroup_size=(1, 1, 1)) compute_program.update_properties(hist=ngl.ResourceProps(writable=True)) compute = ngl.Compute(workgroup_count=(256, 1, 1), program=compute_program, label="histogram-clear") compute.update_resources(hist=h) g.add_children(compute) local_size = 8 group_size = proxy_size / local_size compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-exec"), workgroup_size=(local_size, local_size, 1)) compute = ngl.Compute(workgroup_count=(group_size, group_size, 1), program=compute_program, label="histogram-exec") compute.update_resources(hist=h, source=proxy) compute_program.update_properties(hist=ngl.ResourceProps(writable=True)) compute_program.update_properties(source=ngl.ResourceProps(as_image=True)) g.add_children(compute) q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) p = ngl.Program(vertex=cfg.get_vert("histogram-display"), fragment=cfg.get_frag("histogram-display")) p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) render = ngl.Render(q, p) render.update_frag_resources(tex0=t, hist=h) g.add_children(render) return g
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") assert vert is not None and frag is not None quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) prog = ngl.Program(vertex=vert.decode(), fragment=frag.decode()) 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 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 _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
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')) 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.) * 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_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 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 easings(cfg, easing_id="*"): """Display all the easings (primitive for animation / motion design) at once""" cfg.duration = 2.0 vert_data = cfg.get_vert("color") frag_data = cfg.get_frag("color") color_program = ngl.Program(vertex=vert_data, fragment=frag_data, label="color") color_program.update_vert_out_vars(var_uvcoord=ngl.IOVec2()) full_block = _block(2, 2, (0.3, 0.3, 0.3)) 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) cfg.rng.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 group
def texture_mipmap(cfg, show_dbg_points=False): cfg.aspect_ratio = (1, 1) cuepoints = _get_texture_mipmap_cuepoints() black = (0, 0, 0, 255) white = (255, 255, 255, 255) p = _N // 2 cb_data = array.array( 'B', ((black + white) * p + (white + black) * p) * p, ) cb_buffer = ngl.BufferUBVec4(data=cb_data) texture = ngl.Texture2D( width=_N, height=_N, min_filter='nearest', mipmap_filter='linear', data_src=cb_buffer, ) program = ngl.Program(vertex=_RENDER_TEXTURE_LOD_VERT, fragment=_RENDER_TEXTURE_LOD_FRAG) program.update_vert_out_vars(var_uvcoord=ngl.IOVec2()) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture) group = ngl.Group(children=(render, )) if show_dbg_points: group.add_children(get_debug_points(cfg, cuepoints)) return group
def media_exposed_time(cfg): m0 = cfg.medias[0] cfg.duration = m0.duration cfg.aspect_ratio = (m0.width, m0.height) vert = textwrap.dedent( """\ void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0); uv = ngl_uvcoord; } """ ) frag = textwrap.dedent( """\ void main() { ngl_out_color = vec4(vec3(step(0.0, tex0_ts/duration - uv.x)), 1.0); } """ ) 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
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 _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 get_render(cfg, quad, fields, block_definition, color_definition, block_fields, color_fields, layout, debug_positions=False): func_calls = [] func_definitions = [] for i, field in enumerate(fields): field_len = field.get('len') func_calls.append('get_color_{}(w, h, 0.0, {:f} * h)'.format( field['name'], i)) func_definitions.append( _get_display_glsl_func(layout, field['name'], field['type'], field_len=field_len)) frag_data = dict( func_definitions='\n'.join(func_definitions), func_calls=' + '.join(func_calls), ) fragment = _FIELDS_FRAG % frag_data vertex = _FIELDS_VERT program = ngl.Program(vertex=vertex, fragment=fragment) program.update_vert_out_vars(var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) if isinstance(color_fields, dict): assert isinstance(block_fields, dict) field_names = {f['name'] for f in fields} d = {} d.update(('color_' + n, u) for (n, u) in color_fields.items() if n in field_names) d.update(('field_' + n, u) for (n, u) in block_fields.items() if n in field_names) render.update_frag_resources(**d) else: render.update_frag_resources(fields=block_fields, colors=color_fields) render.update_frag_resources(nb_fields=ngl.UniformInt(len(fields))) if debug_positions: debug_points = _get_debug_positions_from_fields(fields) dbg_circles = get_debug_points(cfg, debug_points, text_size=(.2, .1)) g = ngl.Group(children=(render, dbg_circles)) return g return 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 _get_compositing_scene(cfg, op, show_label=False): cfg.aspect_ratio = (1, 1) cfg.duration = 6 # We can not use a circle geometry because the whole areas must be # rasterized for the compositing to work, so instead we build 2 overlapping # quad into which we draw colored circles, offsetted with an animation. # Alternatively, we could use a RTT. quad = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0)) prog = ngl.Program(vertex=_VERTEX, fragment=_FRAGMENT) prog.update_vert_out_vars(uv=ngl.IOVec2()) A_off_kf = ( ngl.AnimKeyFrameVec2(0, (-1 / 3, 0)), ngl.AnimKeyFrameVec2(cfg.duration / 2, (1 / 3, 0)), ngl.AnimKeyFrameVec2(cfg.duration, (-1 / 3, 0)), ) B_off_kf = ( ngl.AnimKeyFrameVec2(0, (1 / 3, 0)), ngl.AnimKeyFrameVec2(cfg.duration / 2, (-1 / 3, 0)), ngl.AnimKeyFrameVec2(cfg.duration, (1 / 3, 0)), ) A_off = ngl.AnimatedVec2(A_off_kf) B_off = ngl.AnimatedVec2(B_off_kf) A = ngl.Render(quad, prog, label="A") A.update_frag_resources(color=ngl.UniformVec3(value=COLORS.azure), off=A_off) B = ngl.Render(quad, prog, label="B", blending=op) B.update_frag_resources(color=ngl.UniformVec3(value=COLORS.orange), off=B_off) bg = ngl.RenderColor(blending="dst_over") # draw A in current FBO, then draw B with the current operator, and # then result goes over the white background ret = ngl.Group(children=(A, B, bg)) if show_label: label_h = 1 / 4 label_pad = 0.1 label = ngl.Text( op, fg_color=COLORS.black, bg_color=(0.8, 0.8, 0.8), bg_opacity=1, box_corner=(label_pad / 2 - 1, 1 - label_h - label_pad / 2, 0), box_width=(2 - label_pad, 0, 0), box_height=(0, label_h, 0), ) ret.add_children(label) return ret
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('q') assert pts_data.itemsize == 8 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 _rtt_load_attachment(cfg): quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) background = ngl.Render(quad, program) background.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['orange'])) texture = ngl.Texture2D(width=16, height=16) rtt = ngl.RenderToTexture(render, [texture]) texture_noop = ngl.Texture2D(width=16, height=16) rtt_noop = ngl.RenderToTexture(render, [texture_noop]) quad = ngl.Quad((0, 0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) foreground = ngl.Render(quad, program) foreground.update_frag_resources(tex0=texture) return ngl.Group(children=(background, rtt, rtt_noop, foreground))
def audiotex(cfg, freq_precision=7, overlay=0.6): '''FFT/Waves audio texture of the audio stream blended on top of the video stream''' media = cfg.medias[0] cfg.duration = media.duration cfg.aspect_ratio = (media.width, media.height) q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) audio_m = ngl.Media(media.filename, audio_tex=1) audio_tex = ngl.Texture2D(data_src=audio_m) video_m = ngl.Media(media.filename) video_tex = ngl.Texture2D(data_src=video_m) p = ngl.Program(vertex=cfg.get_vert('dual-tex'), fragment=cfg.get_frag('audiotex')) p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_tex1_coord=ngl.IOVec2()) render = ngl.Render(q, p) render.update_frag_resources(tex0=audio_tex, tex1=video_tex) render.update_frag_resources(overlay=ngl.UniformFloat(overlay)) render.update_frag_resources(freq_precision=ngl.UniformInt(freq_precision)) return render
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_frag_resources(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')) 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=(graphic_config, rtt, 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) 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()) render = ngl.Render(q, p) render.update_frag_resources(tex0=t) return render