Tint Problem

I have an issue with tint. I have a transition function that takes a function, draws it, then sprites it with a tweening tint. I’d post code, but I’m planning on putting it in on the App Store. It works for every single function except this one (also the one I’m using for blurring) it has a lot of references to other functions which are stored in a states tables, sets a lot of contexts (lol), and draws a lot of meshes with shaders. When I try and tint the sprite made from it, nothing happens. My collectgarbage(“count”) returns 500 ish. Any idea of any issue with the tint function, or would I be better off to simply make it a mesh and make a simple blur shader. Thanks!

post some code?

@Ignatz I Managed to make a little demo. Gauranteed it’ll be some stupid mistake on my part :wink:


--# Main
-- Mesh Image Tint

-- Use this function to perform your initial setup
function setup()
states={c=Store(), transition=Transition("c", "c3"),c3 = End()}
state="transition"
states["transition"]:Start()
end

-- This function gets called once every frame
function draw()
states[state]:draw() 
end


--# Store

Store = class()

function Store:init()
self.coins = readLocalData("Coins", 0)
self:createImage()
   --[[ 
--Experimental Blurred Background
self.downScale1=image(WIDTH,HEIGHT)
self.downScale2=image(WIDTH/2,HEIGHT/2)
--self.upScale=image(WIDTH, HEIGHT)
self.m=mesh()
--self.m:addRect(WIDTH/4, WIDTH/4, WIDTH/2, WIDTH/2)
self.m.vertices={vec2(0,0),vec2(WIDTH,0),vec2(0,HEIGHT),vec2(0,HEIGHT),vec2(WIDTH,0),vec2(WIDTH,HEIGHT)}
self.m.texCoords={vec2(0,0),vec2(1,0),vec2(0,1),vec2(0,1),vec2(1,0),vec2(1,1)}
self.m.shader=shader("Documents:Slow Shader")
--self.m.shader.blurRadius=vec2(0.001,0.001)
parameter.boolean("us", true)
  ]]
    
--HIGH SPEED DOWN SCALING SHADER ER ER
self.image1 = image(WIDTH,HEIGHT)
self.image2 = image(WIDTH/2,HEIGHT/2)
self.image3 = image(WIDTH/2,HEIGHT/2)
self.m = mesh()
self.m2 = mesh()
self.m.shader = shader(Gaussian.vs, Gaussian.fs)
self.m2.shader = shader(Gaussian.vs,Gaussian.fs)
self.m:addRect(WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2)
self.m2:addRect(WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2)
self.m.shader.radius = 4
self.m2.shader.radius = 4
self.m.shader.dir=vec2(1,0)
self.m2.shader.dir=vec2(0,1)
self.m.shader.resolution=WIDTH
self.m2.shader.resolution=HEIGHT
--self.m.shader.blurRadius=vec2(0.004,0)
--self.m2.shader.blurRadius=vec2(0,0.004)
end

function Store:draw()
--[[background(0, 0, 0, 255)
if us == true then
self.m.shader=shader("Documents:Slow Shader")
else 
self.m.shader=nil   
end
--Experimental Blurred Background   
setContext(self.downScale1) 
states["menu"]:draw() 
setContext()
setContext(self.downScale2)
sprite(self.downScale1, WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2)   
setContext()
self.m.texture=self.downScale2
 
self.m:draw()
]]
--states["menu"]:draw()
--sprite(self.downScale2, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)   
    
--NEW SHADER ER ER   
setContext(self.image1) 
fill(0, 86, 255, 255)
ellipse(WIDTH/2,HEIGHT/2,500,500)
setContext()
self.m.texture=self.image1
setContext(self.image2)
self.m:draw()
setContext()
self.m2.texture=self.image2
setContext(self.image3)
background(0, 0, 0, 255)
self.m2:draw()
setContext()
sprite(self.image3, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
sprite(self.image, WIDTH/2, HEIGHT/2)
end

function Store:touched(touch)
if touch.x > WIDTH/3*2 then
states["transition"]:Start()
state ="transition"   
end
end
function Store:createImage()
self.image=image(WIDTH, HEIGHT)
pushStyle()
setContext(self.image)
strokeWidth(math.ceil(WIDTH/350))
stroke(255, 255, 255, 255)
line(WIDTH/3*2, 0, WIDTH/3*2, HEIGHT)
fontSize(WIDTH/8)
font("HelveticaNeue-UltraLight")
text("Start", WIDTH/6*5, HEIGHT/2)
setContext()    
popStyle()
end

Gaussian = {vs =  [[ 
uniform mat4 modelViewProjection;
uniform vec2 blurRadius;
attribute vec4 position;
attribute vec2 texCoord;

varying vec2 vBlurCoords[5];

void main()
{
    gl_Position = modelViewProjection * position;
     vBlurCoords[0] = texCoord;
     vBlurCoords[1] = texCoord + blurRadius * 1.407333;
     vBlurCoords[2] = texCoord - blurRadius * 1.407333;
    vBlurCoords[3] = texCoord + blurRadius * 3.294215;
    vBlurCoords[4] = texCoord - blurRadius * 3.294215;
}

]],

--optimised fragment shader
fs = [[
precision mediump float;

uniform lowp sampler2D texture;

varying vec2 vBlurCoords[5];

void main()
{
  //  gl_FragColor = vec4(0.0);

    gl_FragColor = texture2D(texture, vBlurCoords[ 0]) * 0.304005; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 1])* 0.204164; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 2])* 0.204164; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 3])* 0.093913; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 4])* 0.093913; 

}]]}
--# Transition
Transition = class()

function Transition:init(state1, state2)
self.state, self.state2 = state1, state2
self.tint = color(255, 255, 255, 255)
self.size = vec2(WIDTH, HEIGHT)
self.view = image(WIDTH, HEIGHT)
end

function Transition:Start()
tween(0.5, self.tint, {r=0,g=0,b=0,a=0}, {},  function() states["transition"].step2() end)  
--speed=2
end

function Transition:step2()
speed=1
states["transition"].state=states["transition"].state2
states["transition"].tint = color(255, 255, 255, 255)
states["transition"].size = vec2(0,0)
tween(0.7, states["transition"].size, {x=WIDTH, y=HEIGHT}, {},function() states["transition"]:step3() end)
end

function Transition:step3()
state=self.state
end

function Transition:draw()
print (self.state, self.size, self.tint)
background(0, 0, 0, 255)
setContext(self.view)
states[self.state]:draw()    
setContext()
tint(255,255,255,self.tint.a)
sprite(self.view,WIDTH/2,HEIGHT/2,self.size:unpack())
noTint()
end

function Transition:touched(touch)
    -- Codea does not automatically call this method
end

--# End
End = class()

function End:init(x)
    -- you can accept and set parameters here
    self.x = x
end

function End:draw()
background(12, 255, 0, 255)
end

function End:touched(touch)
    -- Codea does not automatically call this method
end

Sorry for having such messy code, I haven’t really cleaned this up much yet

are you nesting one tween inside another?

@Ignatz I have a tween with a call back function which starts another tween, if you consider that nesting

The reason why this is confusing me so much is because the store class is written to an image, so why should this one image behave differently then a image created from any different class.

Just wondering, does this look like an issue with my code or an issue with codea?

@Mr_Ninja I don’t want to sound stupid, but what am I looking for. I see a blue circle, the word start, a white line, and a green square that starts small and fills the screen. What should I be seeing.

@Mr_Ninja - you will get quicker responses and suggestions, if you can post enough detail that we can understand the problem in a couple of minutes, including what is supposed to happen - and the relevant code layout and what you think may be causing it.

I’m sorry I wasn’t clear. My issue is, when I have a sprite which is tinted, when the sprite is from this one class, my store class, it doesn’t tint. heres some code with some more comments. I have a fake demo class to show you what it should look like, and the store class with the problem in it. To switch between them , use the parameter button. I’m sorry if this isn’t clear, I’m not sure how to fully explain it, please ask if you don’t know (or pm me). Here’s the code with the comments and what it should look like/shouldn’t parameter.


--# Demo
Demo = class()

function Demo:init(x)

end

function Demo:draw()
background(0, 0, 0, 255)
fill(0, 52, 255, 255)
ellipse(WIDTH/2,HEIGHT/2, 100)
end

function Demo:touched(touch)
    -- Codea does not automatically call this method
end

--# Main
-- Mesh Image Tint

-- Use this function to perform your initial setup
function setup()
--initalizes a table with instances to all classes
states={c=Store(), transition=Transition("c"),c3 = Demo()}
--starts transition class. this class creates an image with the setnarguments every frame, then tints and sprites it. under these specific cercumstances, it doesnt blur.
state="transition"
states["transition"]:Start()
parameter.boolean("showIssue", true, function() change() end)
end

-- This function gets called once every frame
function draw()
--draws current state
states[state]:draw() 
end
--function to change between classes
function change()
if showIssue == true then 
print("as you can see, when the transition class draws the store class, it doesnt tint")   
states["transition"]=Transition("c")   
states["transition"]:Start()
else
print("Here is just a circle image, as tou can see it tints correctly")
states["transition"]=Transition("c3")
states["transition"]:Start()
end
end

--# Store

Store = class()

function Store:init()
--just initializing variables and setting up meshes
self.coins = readLocalData("Coins", 0)
self.image1 = image(WIDTH,HEIGHT)
self.image2 = image(WIDTH/2,HEIGHT/2)
self.image3 = image(WIDTH/2,HEIGHT/2)
self.m = mesh()
self.m2 = mesh()
self.m.shader = shader(Gaussian.vs, Gaussian.fs)
self.m2.shader = shader(Gaussian.vs,Gaussian.fs)
self.m:addRect(WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2)
self.m2:addRect(WIDTH/4, HEIGHT/4, WIDTH/2, HEIGHT/2)
self.m.shader.radius = 4
self.m2.shader.radius = 4
self.m.shader.dir=vec2(1,0)
self.m2.shader.dir=vec2(0,1)
self.m.shader.resolution=WIDTH
self.m2.shader.resolution=HEIGHT
end

function Store:draw()
--draws an image to a mesh, then upscales it when spriting image3 
setContext(self.image1) 
fill(0, 86, 255, 255)
ellipse(WIDTH/2,HEIGHT/2,500,500)
setContext()
self.m.texture=self.image1
setContext(self.image2)
self.m:draw()
setContext()
self.m2.texture=self.image2
setContext(self.image3)
background(0, 0, 0, 255)
self.m2:draw()
setContext()
sprite(self.image3, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
end

--yojimbos gaussian blur shader


Gaussian = {vs =  [[ 
uniform mat4 modelViewProjection;
uniform vec2 blurRadius;
attribute vec4 position;
attribute vec2 texCoord;

varying vec2 vBlurCoords[5];

void main()
{
    gl_Position = modelViewProjection * position;
     vBlurCoords[0] = texCoord;
     vBlurCoords[1] = texCoord + blurRadius * 1.407333;
     vBlurCoords[2] = texCoord - blurRadius * 1.407333;
    vBlurCoords[3] = texCoord + blurRadius * 3.294215;
    vBlurCoords[4] = texCoord - blurRadius * 3.294215;
}

]],

--optimised fragment shader
fs = [[
precision mediump float;

uniform lowp sampler2D texture;

varying vec2 vBlurCoords[5];

void main()
{
  //  gl_FragColor = vec4(0.0);

    gl_FragColor = texture2D(texture, vBlurCoords[ 0]) * 0.304005; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 1])* 0.204164; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 2])* 0.204164; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 3])* 0.093913; 
    gl_FragColor += texture2D(texture, vBlurCoords[ 4])* 0.093913; 

}]]}
--# Transition
Transition = class()

function Transition:init(state1)
self.state = state1
self.tint = color(255, 255, 255, 255)
self.size = vec2(WIDTH, HEIGHT)
self.view = image(WIDTH, HEIGHT)
end

function Transition:Start()
tween(2, self.tint, {r=0,g=0,b=0,a=0}, {},  function() states["transition"].step3() end)  
--speed=2
end


function Transition:step3()
end

function Transition:draw()
--draws current state to an image, tints and draws it
--uncomment print line to see tint is changing
--print (self.tint)
background(0, 0, 0, 255)
setContext(self.view)
states[self.state]:draw()    
setContext()
tint(255,255,255,self.tint.a)
sprite(self.view,WIDTH/2,HEIGHT/2,self.size:unpack())
noTint()
end

function Transition:touched(touch)
    -- Codea does not automatically call this method
end

--# End
End = class()

function End:init(x)
    -- you can accept and set parameters here
    self.x = x
end

function End:draw()
background(12, 255, 0, 255)
end

function End:touched(touch)
    -- Codea does not automatically call this method
end

The most obvious problem I can see is that in Transition, you call setContext, then in Store, you call it again. You can’t nest setContext calls!

I think what you need to do is something like this

--split Store:draw into two parts
function Store:update()
   --CODE AS FOR Store:draw, but don't draw the final image
return

function Store:draw() --now do the drawing
    sprite(self.image3, WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
end

function Transition:draw()
   background(0, 0, 0, 255)
   states[self.state]:update() --NEW
   setContext(self.view)
   states[self.state]:draw()    
   setContext()
   tint(255,255,255,self.tint.a)
   sprite(self.view,WIDTH/2,HEIGHT/2,self.size:unpack())
   noTint()
end

Ohhhh, you’re right. Thank you! If I explicitly call the images and messes, that wil work, so that’s what I’ll do. Thanks @Ignatz! :slight_smile:

@Mr_Ninja - see my suggested fix above

That’ll work perfect. You truly are a genius:)

an extra pair of eyes always helps :-B