diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-09-14 13:55:26 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-09-14 15:39:20 +0000 |
| commit | 4e1bab057ffb010076ae3948b93028ca5e22c3b2 (patch) | |
| tree | 62355972fcb70b6f03a3badce7cda41ed32438aa | |
| parent | lib/glsl-view: use tag for texture, uniform names (diff) | |
| download | alive-4e1bab057ffb010076ae3948b93028ca5e22c3b2.tar.gz alive-4e1bab057ffb010076ae3948b93028ca5e22c3b2.zip | |
lib/glsl-view: assemble uniform preamble in send
| -rw-r--r-- | alv-lib/glsl-view.moon | 74 | ||||
| -rw-r--r-- | examples/glsl-view/nesting.alv | 24 |
2 files changed, 59 insertions, 39 deletions
diff --git a/alv-lib/glsl-view.moon b/alv-lib/glsl-view.moon index d3c8e75..bc783ed 100644 --- a/alv-lib/glsl-view.moon +++ b/alv-lib/glsl-view.moon @@ -1,4 +1,4 @@ -import Constant, PureOp, Op, template_subst, Input, T, Array, Struct, sig, evt, const, any from require 'alv.base' +import Error, Constant, PureOp, Op, template_subst, Input, T, Array, Struct, sig, evt, const, any from require 'alv.base' import Message, Bundle, Timetag, add_item from require 'alv-lib._osc' import dns, udp from require 'socket' @@ -30,28 +30,30 @@ GLSL_SAMPLER_TYPES = Uniform = Struct type: T.str, val: T.str +get_typestr = (type) -> + typestr = GLSL_TYPES[tostring type] + assert typestr, Error 'type', "can't wrap #{type} in uniform" + uniform = Constant.meta meta: name: 'uniform' summary: "override uniform binding type." - examples: { '(uniform glsl-type value)' } - description: "Generates a uniform struct as received by [glsl-view/shader][]: - -`(uniform 'sampler2D' 'sampler-name')` is equivalent to `{'type' 'sampler2D' 'val' 'sampler-name'}`." - - value: class extends Op - pattern = sig.str + sig! - setup: (inputs, scope) => - { type, val } = pattern\match inputs - - super - type: Input.hot type - val: Input.hot val + examples: { '(uniform [glsl-type] value)' } + description: "Label an alive value with a GLSL type: +`(uniform 'sampler2D' 'sampler-name')` is equivalent to `{'type' 'sampler2D' 'val' 'sampler-name'}`. - @setup_out '~', Struct type: T.str, val: @inputs.val\type! +When absent, `glsl-type` is inferred based on the type of `value`: +- `num`, `bool`: `uniform float/bool` +- `num[I]`, `bool[I]`: `uniform vecI/bvecI` +- `num[I][J]`: `uniform matIxJ`" + value: class extends PureOp + pattern: -sig.str + sig! + type: (inputs) => Struct type: T.str, val: inputs[2]\type! tick: => - @out\set @unwrap_all! + { type, val } = @unwrap_all! + type or= get_typestr @inputs[2]\type! + @out\set :type, :val video_source = Constant.meta meta: @@ -227,10 +229,8 @@ shader_ = Constant.meta - `code…` is a template string that can contain `~-stream` template substitutions that are used as follows: - `str`: substituted directly as GLSL - another shader struct~: substituted as GLSL, with uniforms lifted - - `{type: str val: …}`: reference to uniform of GLSL-type `type` (instead of inferred as follows) - - `num`, `bool`: reference to `uniform float/bool` - - `num[I]`, `bool[I]`: reference to `uniform vecI/bvecI` - - `num[I][J]`: reference to `uniform matIxJ`" + - `{type: str val: …}`: reference to uniform of GLSL-type `type` + - other values are implicitly converted as by [glsl-view/uniform][]" value: class extends PureOp pattern: const! + sig!^0 @@ -246,26 +246,23 @@ shader_ = Constant.meta else if type.__class == Struct and type.types['shader'] for name, typ in pairs type.types['uniforms'].types uniforms[name] = typ - continue else if type.__class == Struct - assert type.types['type'] == T.str, "struct substituton needs type key" - type = type.types['val'], "struct substituton needs val key" + assert type.types['type'] == T.str, Error 'type', "struct substituton needs type key" + else + type = Struct type: T.str, val: type - uniforms[@name i] = type + uniforms[@name i] = type - uniforms = Struct uniforms - Struct shader: T.str, :uniforms + Struct shader: T.str, uniforms: Struct uniforms tick: => uniforms = {} - preamble = { '#version 330 core' } pieces = for i, input in ipairs @inputs[2] name, input = (@name i), input val, type = input!, input\type! - typestr = GLSL_TYPES[tostring type] if type == T.str val elseif type.__class == Struct and type.types['shader'] @@ -273,20 +270,14 @@ shader_ = Constant.meta uniforms[k] = v val.shader else - if type.__class == Struct - typestr = val.type - val, type = val.val, val.type + if type.__class != Struct + val = :val, type: get_typestr type - assert typestr, "unsupported type #{type}" - table.insert preamble, "uniform #{typestr} #{name};" uniforms[name] = val name shader = template_subst @inputs[1]!, pieces - table.insert preamble, shader - shader = table.concat preamble, '\n' - @out\set :shader, :uniforms draw = Constant.meta @@ -314,13 +305,18 @@ draw = Constant.meta { :socket, :shader } = @unwrap_all! with Bundle.new Timetag.new! - \add content: { address: '/shader', types: 's', shader.shader } + chunks = { '#version 330 core\n' } + for key, val in pairs shader.uniforms + table.insert chunks, "uniform #{val.type} #{key};" + table.insert chunks, shader.shader + + \add content: { address: '/shader', types: 's', table.concat chunks, '\n' } types = @inputs.shader\type!\get 'uniforms' for key, val in pairs shader.uniforms - type = types\get key + type = types\get(key)\get 'val' msg = Message.new "/uniform/#{key}" - add_item msg, type, val + add_item msg, type, val.val \add msg socket\send Bundle.pack .content diff --git a/examples/glsl-view/nesting.alv b/examples/glsl-view/nesting.alv new file mode 100644 index 0000000..8c76695 --- /dev/null +++ b/examples/glsl-view/nesting.alv @@ -0,0 +1,24 @@ +([1]import* glsl-view time string) +([2]import osc) + +([4]def *oscout* ([3]osc/connect 'localhost' 9000)) + +([10]defn testpat [w h uv] + ([9]do + ([7]def source ([6]stream-source '2D' ([5]str 'testsrc=size=' w 'x' h ':rate=30') 'lavfi')) + + $[8]shader"texture($source , round($uv * vec2($w , $h)) / vec2($w , $h)).rgb")) + +([14]draw + $[13]shader" +in vec2 uv; +out vec4 color; + +void main() { + vec3 hi = $([11]testpat 1280 720 "uv"); + vec3 lo = $([17]testpat 16 9 "uv"); + + color.rgb = mix(hi, lo, $([12]lfo 1)); + + color.a = 1.0; +}") |
