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
--# 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!
@Mr_Ninja - see my suggested fix above
That’ll work perfect. You truly are a genius:)
an extra pair of eyes always helps :-B