Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

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

edited July 3 in Questions Posts: 108

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

Comments

  • Posts: 108

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

  • dave1707dave1707 Mod
    edited July 3 Posts: 6,331

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

  • Posts: 108

    Oh cool I like that, I haven't seen anything other than the [CODE] [/CODE] 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

  • Posts: 108

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

  • JohnJohn Admin Mod
    Posts: 456

    @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
    
  • Posts: 108

    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!!

  • Posts: 108

    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?

  • edited July 5 Posts: 108

    @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?

  • Posts: 108

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

  • Posts: 35

    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
    
  • Posts: 108

    @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.

  • Posts: 108

    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!

  • Posts: 108

    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!

  • Posts: 108

    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

  • Posts: 35

    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.

Sign In or Register to comment.