@spacemonkey
The test below shows OpenGL does anti alias images.
I create a white circle in a square, otherwise transparent image, and put it into 2 meshes which I draw next to each other, onto a red background.
However the second mesh has a shader that discards transparent pixels.
Finally I draw a yellow rectangle just behind both circle images.
The left hand circle retains an opaque red background because OpenGL thinks transparent cells are solid and doesn’t bother drawing the yellow rectangle behind them.
The right hand circle has no background any more, so the yellow rectangle is drawn behind it, but what is striking is the red edge on the circle, showing that as OpenGL drew the circle on the red background, it anti aliased the edge, and this edge remained when the yellow rectangle was drawn behind.
http://instagram.com/p/Z8HTMnBHQK/
Having seen what OpenGL does to solid images, I noticed that my tree images tend to have partly transparent edges, which just encourages OpenGL even more (if that is possible!) to blend them with the current background at time of drawing.
So I’m not sure there’s any alternative to z order sorting.
Code follows
--# Main
function setup()
--make white ball on transparent background
img=image(150,150)
setContext(img)
fill(255,255,255,255)
ellipse(75,75,75)
setContext()
--create 2 identical meshes
m1=mesh()
m1.texture=img
u=m1:addRect(0,0,img.width,img.height)
m1:setRectTex(u,0,0,1,1)
m1:setColors(color(255))
--give the second one a shader that discards transparent pixels
m2=mesh()
m2.texture=img
u=m2:addRect(0,0,img.width,img.height)
m2:setRectTex(u,0,0,1,1)
m2:setColors(color(255))
m2.shader = shader(TransparentShader.vertexShader, TransparentShader.fragmentShader)
--create a yellow image to go behind our shaded image to see if Codea anti aliased it
img3=image(500,500)
setContext(img3)
fill(255, 255, 0)
rect(1,1,500,500)
setContext()
m3=mesh()
m3.texture=img3
u=m3:addRect(0,0,img3.width,img3.height)
m3:setRectTex(u,0,0,1,1)
m3:setColors(color(255,255,0))
end
-- This function gets called once every frame
function draw()
background(255,0,0)
perspective()
camera(0,20,200,0,0,0)
pushMatrix()
translate(-65,0,-120)
m1:draw()
popMatrix()
pushMatrix()
translate(65,0,-120)
m2:draw()
popMatrix()
pushMatrix()
translate(-65,0,-125)
m3:draw()
popMatrix()
end
--# Shader
TransparentShader = {
vertexShader = [[
//
// A basic vertex shader
//
//This is the current model * view * projection matrix
// Codea sets it automatically
uniform mat4 modelViewProjection;
//This is the current mesh vertex position, color and tex coord
// Set automatically
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
//This is an output variable that will be passed to the fragment shader
varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
//Pass the mesh color to the fragment shader
vColor = color;
vTexCoord = texCoord;
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]],
fragmentShader = [[
//
// A basic fragment shader
//
//Default precision qualifier
precision highp float;
//This represents the current texture on the mesh
uniform lowp sampler2D texture;
//The interpolated vertex color for this fragment
varying lowp vec4 vColor;
//The interpolated texture coordinate for this fragment
varying highp vec2 vTexCoord;
void main()
{
lowp vec4 col = texture2D(texture, vTexCoord);
if(col.a<0.05) discard;
else gl_FragColor = col * vColor;
}
]]}