I just encountered a rather strange bug. I’ll document it here, but it might be a little time before I can post replicating code as my example is quite complicated.
I have a program with two meshes. One has a shader attached to it, the other doesn’t. The second (without the shader) has a texture. When I draw them then only the mesh with a shader appears.
Experimenting leads to the following. Let’s call the meshes a
and b
.
-
a
has shader, b
has texture => a
drawn, b
not.
-
a
has shader, b
does not have texture (but has colour) => a
drawn, b
drawn.
-
a
does not have shader, b
has texture => a
drawn, b
drawn
-
a
has shader, b
has default shader and texture => a
drawn, b
drawn
-
a
has shader but is not drawn, b
has texture => a
not drawn, b
drawn
It also appears that the order of drawing of a
and b
is immaterial. I think I see a “flash” whereby b
is drawn initially and then disappears on subsequent draws.
So my guess is that when a
is drawn then a shader is actually installed for b
as well and this shader does not render the texture.
I’ve gotten round it by explicitly giving b
a shader (case 4). I’ll try to pare down my program to a MWE that shows the bug.
I’ve seen some similar weirdness although never actually stopped to nail it down before. I also sometimes get weird not the texture I expected issues sometimes where you’ll get the made in codea watermark from video recording suddenly appearing as the mesh texture rather than what you thought you set.
I think this is fairly minimal. As shown, both meshes display. Instating the line a.shader = s
then only the a
rectangle shows. Further instating the line b.shader = s
then both rectangles show again.
One thing to note: if I use addRect
to add the rectangle to the a
mesh then this behaviour doesn’t happen: both meshes display correctly. (I should say that this is not a feasible solution in my actual program.)
function setup()
a = mesh()
local o = vec2(WIDTH/2,HEIGHT/2)
a.vertices = {
o,
o + vec2(0,-100),
o + vec2(100,-100),
o,
o + vec2(100,0),
o + vec2(100,-100)
}
local s = shader()
s.vertexProgram = vertexProgram
s.fragmentProgram = afragmentProgram
--a.shader = s
a:setColors(color(127,198,127,255))
b = mesh()
s = shader()
s.vertexProgram = vertexProgram
s.fragmentProgram = bfragmentProgram
--b.shader = s
b.texture = "Cargo Bot:Codea Icon"
b:addRect(WIDTH/2,HEIGHT/2+200,200,200)
b:setColors(255,255,0,255)
end
function draw()
background(0, 0, 0, 255)
a:draw()
b:draw()
end
function touched(touch)
end
vertexProgram = [[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
vColor = color;
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]]
afragmentProgram = [[
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
lowp vec4 col = vColor;
gl_FragColor = col;
}
]]
bfragmentProgram = [[
precision highp float;
uniform lowp sampler2D texture;
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
lowp vec4 col = texture2D( texture, vTexCoord );
col *= vColor;
gl_FragColor = col;
}
]]