aboutsummaryrefslogtreecommitdiffstats
path: root/alv-lib/glsl.moon
blob: 3f973ae7193ea4aea7a765d1ce5e94171a10569a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import Constant, Op, Builtin, Input, T, Struct, const, any from require 'alv.base'
import new_message, add_item from require 'alv-lib._osc'
import dns, udp from require 'socket'

glsl_type = (type) ->
  switch type
    when T.num then 'float'
    when T.str then 'sampler3D'
    when T.bool then 'bool'
    else
      error "unknown primitive type"

resubst = (str, fn) ->
  str = str\gsub '##', '#'
  str\gsub '#{(%d+)}', fn

shader = Constant.meta
  meta:
    name: 'gate'
    summary: "gate from note-on and note-off messages."
    examples: { '(midi/gate [port] note [chan])' }

  value: class extends Op
    pattern = const.str + any!^0

    setup: (inputs, scope) =>
      { code, params } = pattern\match inputs

      super [Input.hot param for param in *params]

      uniforms = {}
      inputs = {}

      for i, input in ipairs @inputs
        table.insert uniforms, "uniform #{glsl_type input\type!} alv_param_#{i};"

      code = code.result!
      code = resubst code, (i) -> "alv_param_#{i}"

      table.insert uniforms, code
      code = table.concat uniforms, '\n'

      print code

      @state or= with sock = udp!
        \setpeername '127.0.0.1', 9000

      msg = new_message "/-/shader"
      add_item msg, T.str, code
      @state\send msg.pack msg.content

    tick: (setup) =>
      for i, input in ipairs @inputs
        if setup or input\dirty!
          msg = new_message "/alv_param_#{i}"
          print "/alv_param_#{i}", input!
          add_item msg, input\type!, input!
          @state\send msg.pack msg.content

Constant.meta
  meta:
    name: 'glsl-view'
    summary: "glsl-view integration via OSC."

  value:
    :shader