aboutsummaryrefslogtreecommitdiffstats
path: root/alv-lib
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-08-04 23:00:18 +0000
committers-ol <s+removethis@s-ol.nu>2025-08-04 23:00:18 +0000
commit12153d43224fa2a58cedad4497a5c4020b233cf1 (patch)
tree6edc0c85bd770ecfc9ceecac9fddd0c3b076f021 /alv-lib
parentdocs: small fixes in guide and reference (diff)
downloadalive-12153d43224fa2a58cedad4497a5c4020b233cf1.tar.gz
alive-12153d43224fa2a58cedad4497a5c4020b233cf1.zip
lib/glsl-view: align source names, add stream source
Diffstat (limited to 'alv-lib')
-rw-r--r--alv-lib/glsl-view.moon110
1 files changed, 90 insertions, 20 deletions
diff --git a/alv-lib/glsl-view.moon b/alv-lib/glsl-view.moon
index e0b8678..8b3ec3f 100644
--- a/alv-lib/glsl-view.moon
+++ b/alv-lib/glsl-view.moon
@@ -2,6 +2,10 @@ import Constant, PureOp, Op, template_subst, Input, T, Array, Struct, sig, const
import Message, Bundle, Timetag, add_item from require 'alv-lib._osc'
import dns, udp from require 'socket'
+tryprefix = (prefix, filename) ->
+ return filename unless prefix and filename\match '^%./'
+ prefix .. filename
+
GLSL_TYPES =
num: 'float'
bool: 'bool'
@@ -29,9 +33,9 @@ uniform = Constant.meta
name: 'uniform'
summary: "override uniform binding type."
examples: { '(uniform glsl-type value)' }
- description: "Generates a struct as received by [shader][]:
+ description: "Generates a uniform struct as received by [glsl-view/shader][]:
-`(uniform 'sampler2D' 'image.png')` is equivalent to `{'type' 'sampler2d' 'val' 'image.png'}`."
+`(uniform 'sampler2D' 'sampler-name')` is equivalent to `{'type' 'sampler2D' 'val' 'sampler-name'}`."
value: class extends Op
pattern = sig.str + sig!
@@ -47,46 +51,108 @@ uniform = Constant.meta
tick: =>
@out\set @unwrap_all!
-video = Constant.meta
+video_source = Constant.meta
meta:
name: 'video'
summary: "load a video texture source."
- examples: { '(video [socket] name filename [type])' }
+ examples: { '(video-source [socket] name type filename [format] [args])' }
+ description: "Creates a texture source from a video or image file.
+
+- `name` is a unique name for this texture source.
+- `type` can be one of:
+ - `2D`: `sampler2D` (loads first frame only)
+ - `3D` or `2D_ARRAY`: `sampler3D`/`sampler2DArray` (loads whole video)
+- `filename` is the video file to load. If it starts with `./` it will be
+ resolved relative to the current alv module.
+- `format` optionally specifies the ffmpeg/avformat input format to use.
+- `args` is a struct of optional arguments for the ffmpeg/avformat input format."
value: class extends Op
- pattern = -sig['osc/out'] + const.str + const.str + -const.str
+ pattern = -sig['osc/out'] + const.str + const.str + const.str + -const.str + -const!
setup: (inputs, scope) =>
- { socket, name, filename, type } = pattern\match inputs
+ { socket, name, type, filename, format, args } = pattern\match inputs
@prefix = COPILOT.active_module.file\match'(.*/)[^/]*$'
super
socket: Input.hot socket or scope\get '*oscout*'
name: Input.cold name
+ type: Input.cold type
filename: Input.cold filename
- type: Input.cold type or Constant.str "2D"
+ format: format and Input.cold format
+ args: args and Input.cold args
samplertype = assert GLSL_SAMPLER_TYPES[@inputs.type!]
@setup_out '=', (Struct type: T.str, val: T.str), type: samplertype, val: @inputs.name!
tick: =>
- { :socket, :name, :type, :filename } = @unwrap_all!
+ { :socket, :name, :type, :filename, :format, :args } = @unwrap_all!
with @inputs.socket!
- if @prefix and not (filename\match '^/') or (filename\match '^%w:\\')
- filename = @prefix .. filename
- \send Message.pack { address: "/texture/#{name}/video", types: "ss", "TEXTURE_#{type}", filename }
+ filename = tryprefix @prefix, filename
+ msg = Message.new{ address: "/texture/#{name}/video", types: "ss", "TEXTURE_#{type}", filename }
+ msg\add 's', format if format
+ add_item msg, @inputs.args\type!, args if args
+ \send Message.pack msg.content
-- destroy: =>
-- name = @inputs.name!
-- with @inputs.socket!
-- \send Message.pack { address: "/texture/#{name}/destroy", types: "" }
-tsv_input = Constant.meta
+stream_source = Constant.meta
+ meta:
+ name: 'stream'
+ summary: "load a stream texture source."
+ examples: { '(stream-source [socket] name type uri [format] [args])' }
+ description: "Creates a realtime stream from a capture source.
+
+- `name` is a unique name for this texture source.
+- `type` must be `2D`.
+- `uri` is the ffmpeg URI to load. If it starts with `./` it will be resolved relative to the current alv module.
+- `format` optionally specifies the ffmpeg/avformat input format to use.
+- `args` is a struct of optional arguments for the ffmpeg/avformat input format.
+
+ (stream-source 'webcam' '2D' '/dev/video0')
+ (stream-source 'testpt' '2D' 'testsrc=size=1280x720:rate=30' 'lavfi')"
+
+ value: class extends Op
+ pattern = -sig['osc/out'] + const.str + const.str + const.str + -const.str + -const!
+ setup: (inputs, scope) =>
+ { socket, name, type, filename, format, args } = pattern\match inputs
+
+ @prefix = COPILOT.active_module.file\match'(.*/)[^/]*$'
+
+ super
+ socket: Input.hot socket or scope\get '*oscout*'
+ name: Input.cold name
+ type: Input.cold type
+ filename: Input.cold filename
+ format: format and Input.cold format
+ args: args and Input.cold args
+
+ samplertype = assert GLSL_SAMPLER_TYPES[@inputs.type!]
+ @setup_out '=', (Struct type: T.str, val: T.str), type: samplertype, val: @inputs.name!
+
+ tick: =>
+ { :socket, :name, :type, :filename, :format, :args } = @unwrap_all!
+
+ with @inputs.socket!
+ filename = tryprefix @prefix, filename
+ msg = Message.new{ address: "/texture/#{name}/stream", types: "ss", "TEXTURE_#{type}", filename }
+ msg\add 's', format if format
+ add_item msg, @inputs.args\type!, args if args
+ \send Message.pack msg.content
+
+tsv_source = Constant.meta
meta:
- name: 'tsv-input'
+ name: 'tsv-source'
summary: "load a texture-share-vk texture source."
- examples: { '(texture [socket] name [type])' }
+ examples: { '(tsv-source [socket] name [type])' }
+ description: "Creates a texture source from a texture-share-vk texture.
+
+- `name` is a unique name for this texture source.
+- `type` defaults to `2D`."
value: class extends Op
pattern = -sig['osc/out'] + const.str + -const.str
@@ -111,12 +177,13 @@ shader_ = Constant.meta
meta:
name: 'shader'
summary: "compile a GLSL shader with uniforms."
- examples: { '#shader"code…"' }
- description: "Syncs code and parameters with glsl-view via OSC.
+ examples: { '$shader"code…"' }
+ description: "A template string formatter for [glsl-view/draw][] that returns a shader struct~.
- `code…` is a template string that can contain `~-stream` template substitutions that are used as follows:
- `str`: substituted directly as GLSL
- - `{type: str val: …}`: reference to uniform of type `type` (instead of infered as follows)
+ - 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`"
@@ -211,8 +278,11 @@ Constant.meta
summary: "glsl-view integration via OSC."
value:
- :video
- 'tsv-input': tsv_input
- :texture
+ :uniform
+
+ 'video-source': video_source
+ 'stream-source': stream_source
+ 'tsv-source': tsv_source
+
shader: shader_
:draw