How do I attach my Slider.values to my m.shader.uniforms???

I am on the precipice of something very cool and exciting for me, I figured out Regex enough to parse through all the uniforms of any supplied shader, created a universal GLSL class and am on the last critical element of the puzzle before this comes together as a beta.

So my current snag that I have been at for a few days now off and on, is that I cant seem to figure out how to make a connection from the slider class I made for controlling uniform floats, (and works fine in a bunch of my other programs when I connect the vales directly through each literal “m.shader.uniformName = slider.val” manually,
but the whole point of what I am doing now is automating and removing the absurd amount of tedium I am facing in trying to experiment fluidly with fragment shaders passing images around for processing in a node based visual network.

to boil down the question:
here is my regex string find for the uniforms:


sliders = {}
-------------- uniforms ----------------
function shaderall:parseUniforms()
    local NUM = 0
    local pattern = 'uniform%s(%a.-)%s(%a.-);'   
    for TYPE, NAME in string.gmatch(self.m.shader.fragmentProgram, pattern) do
        NUM = NUM + 1
        print(NUM, TYPE, NAME)
        self:addUniform(NUM, TYPE, NAME)      
    end
end
function shaderall:addUniform(NUM, TYPE, NAME)  
    if TYPE == 'float' then --------------------------------
        sliders[NAME] = Slider(ww, hh+50*NUM, NAME)   
        sliders[NAME]:link(self.m.shader[NAME])         ---- CURRENTLY LINK SIMPLY RETURNS THE SLIDERVAL-----
        self.m.shader[NAME] = sliders[NAME]:value()           ---- THIS IS WHERE IM STUCK ----- 
                                                                                    -------LOOKS LIKE IT PASSES THE INITIAL VALUE 
                                                                                       ---------BUT NOT ANY CHANGES TO IT


_ and so on for vec2s sampler2Ds etc… supplying them with different widgets etc… and then I just need to connect my folder lister and make a sort of visual chaining method… but my point being most of what I need and want is not far out of grasp yet this eludes me and I have a feeling it is heavily due to something that I actually LOVE about lua, the flexibility of table obect and auto type conversion…

my best guess and what I am trying now is that I maybe need to make the slider value changes “link” to the uniform so that the updated values get passed to the self.m.shader[NAME] uniform values whenever they are updated… as it appears to get the initialized value of 0.5 from the slider in my test but when I change the slider it doesn’t update the uniform…

but this goes against what I thought I understood about the way lua deals with “referencing” tables and variables… so maybe I misunderstood, but I know why this wouldn’t work in cpp, becuase I certainly would need to send any change of value to the other variable manually… or use pointers, which is what I got the impression lua made; a sort of pointer reference when a table value passed in an = it was like making a pointer rather than copying the literal value.
in most of the scenarios I am presenting that wouldn’t they be pointing to the same memory space? or did I misread or misremember my lua manual read from the other day.

At any rate… it doesn’t seem like it should be hard and seems like a fundimental thing that is part of any complex code scenario, yet ive been searching the forum for hours and nothing is helping me get there??

if its worth anything, here are a bunch of lines of things Ive been tryign that did not work out (at least yet)

        --table.insert(self.uniforms, NAME)
        -- self.m.shader[NUM] = NAME
        --parameter.number(NAME,0.0,1.0,0.5)
       -- namer = string.format(NAME) --(self.m.shader[NAME])
       -- parameter.number(self.m.shader[NAME],0.0,1.0,0.5)    
       -- self.m.shader[NAME] = parameter.number(NAME,0.0,1.0,0.5)   -- 0.25
        

and what am I doing wrong in my [CODE] forum post formatting?

To post code correctly, put 3 ~'s on a line before and after the code. You can edit your post and add them.

Oh cool I like that, I haven’t seen anything other than the before
is there supposed to be a button to do that in these handfull of icons at the top of the editor cause I looked at them all and I dont see one

Am I misunderstanding the way = works in lua? im gonna go check the manual again

@AxiomCrux Unfortunately you can’t bind a parameter to an arbitrary lua value. Parameters require a name (string) which will be the global variable used to store the parameter. You can also add a callback function that is called whenever the parameter is updated:

function setup()
  myShader = shader(...)
  -- this will create a global variable called UniformName
  parameter.number("UniformName", min, max, value, function(v)
    myShader.UniformName = v
  end
end

Oh interesting… so any time v is updated it would return the new value, wow thats powerful stuff. loving lua… just started learning last week and kinda blown away
good work @John Ill try this now and let you know if it works :smile: D thanks!!

Ok I realized I still have a question as I went to try. does this require the codea parameter.number to work? and is that still something that works outside of experimentation and debugging? I have only used them for little quick sliders on the console bar before. Is there more I can read up on the nature of parameter outside the built in help?

@John I am trying to figure out something more fundamental that is going to be helpful overall, and I feel the notion of adding global parameter numbers is ok in the short term but will be a big problem very soon.

The thread that seems most relevant so far is this one about getting and setting values:
https://codea.io/talk/discussion/6158/getter

I needed to dynamically create entries to “m.shader.-----” where the ---- is my uniform name. I believe I have done this using “self.m.shader[NAME] = -----” in my code from the original post. This appears to work, but since that line of code with the uniform name is extracted from the shaders actual code, and the m.shader seems to be more complex userdata beyond a simple table I can’t figure out how to:

  1. pass the equivalent of the memory address (pointer style) of self.m.shader[NAME] to my slider class so I can make it update that uniform’s value in its touch function

  2. when I pass self.m.shader, it says it is userdata, which makes sense, I suppose it might be helpful to understand the structure of it as what seems to be messing with me is that I can’t work with it as a table of uniforms. Is there a way I can learn more about the shader userdata?

And/or create callback function that isn’t tied to parameter.number

It seems like you really want something like a binding concept which, as far as I know, doesn’t exist in Lua or is bundled with Codea, but you could probably make your own simplified implementation by doing something like:

b = { target = self.m.shader, parameter = "uniform-name" }

You could also build a function that makes updating the value of a bound property a little nicer:

function updateBoundValue(binding, newValue)
   binding.target[binding.parameter] = newValue
end

Then have your slider class reference a “binding” and call updateBoundValue() whenever the slider changes which would make it easy to change the binding to any other shader/uniform combination.

function Slider:valueChanged(newValue)
  updateBoundValue(self.binding, newValue)
end

Maybe that’d work?

You could of course make this fancier and define a Binding class and such, too.

Binding = class()

function Binding:init(target, property)
  self.target = target
  self.property = property
end

function Binding:set(newValue)
  self.target[self.property] = newValue
end

function Binding:get()
  return self.target[self.property]
end

@BigZaphod Thank you, that seems on track with what I am going for, but the only thing that is creating a challenge is the way self.m.shader and self.m.shader.— for each uniform is set up. If I pass self.m.shader to another function, it passes userdata of the code for the shader, rather than a table that I can access each uniform. If I make a generated self.m.shader[NAME] for the uniform and pass that, it passes the value I have set for that uniform and I can’t seem to figure out how to get the equivalent of a pointer address to bind…

but otherwise I like where your head is at, exactly what Im going for but can’t seem to find the missing “link”

reading the lua manual back and forth is taking quite a while.

I think I figured it out, appears to be working. I pass self.m.shader and NAME to my Slider init funciton which get stored as self.dest and self.key in the slider, and in my touch update function for the slider I have self.dest[self.key] = self.val
Appears to work so far!! woot!

Wow this is coming along swimmingly now!
I am reading a fair bit on class inheritance techniques in the lua doc and codea forum, good stuff. meta, __index… Lua is really nifty.
I also am reading Cider and Soda code and learning a ton.
I can see a bit on how to do callbacks and structuring hirarchy in Cider…
Is there a way I can post video directly on this forum or would I need to upload through youtube etc? I want to show the work in progress as Im pretty stoked about it at the moment!

oh and @BigZaphod I did in fact end up using basically your proposed solution. I made :

-- pass in self.m.shader to dest and NAME of uniform to key >>>

function slider:bindUniform(dest,key)
   self.dest=dest
   self.key = key
end

-- and then in the touch function for slider I do:
   self.dest[self.key] = self.val

BOOM

Sounds like you’re having fun! Keep it up!

A YouTube video link is probably the best way to go - I don’t think this forum supports video natively.