I’ve been using Codea for a little while now, mostly on the train or the front veranda, and loving it. It’s really helping me find the time to tackle those little side projects that always pop up.
Anyway, I’m a little way through my first game. It involves rendering a circle in the middle of the screen representing a sun, which grows as the level progresses, in direct proportion with the player’s proximity to impending doom. I’m finding that once the circle reaches roughly half the height of the iPad display (in landscape) the frame rate dips noticeably. Is this known behaviour, and is there any optimisation I can do to increase the rendering speed of that circle? I have tried setting noSmooth() but it doesn’t seem to have any affect on ellipses which seems in line with the documentation.
Circles use the most complex shader, and are the most expensive pixels to render. So drawing a large circle requires the shader be evaluated for each pixel. This will be much slower on iPad 1, which has significantly less fill rate than iPad 2.
Here’s bit of a hack to render a circle into an image and then use that instead. It should be faster, but your circle is limited to a fixed resolution.
function circleImage( size )
local i = image(size,size)
setContext(i)
pushStyle()
noStroke()
fill(255) -- fill white, we can tint() the image
ellipse( size/2, size/2, size )
popStyle()
setContext()
return i
end
function setup()
circleImg = circleImage( 512 )
end
function draw()
background(20,20,40)
tint( 255,255, 0 ) -- make the image yellow
sprite( circleImg, WIDTH/2, HEIGHT/2 )
end
An even faster alternative is to make a circle from a triangle fan using the mesh() class. I can post sample code for that, if the above doesn’t work for you.
Thanks Simeon. I incorporated your image code and it renders consistently now. I’m glad you used tinting as well, otherwise I might not have realised I could keep my “flickering random shades of yellow” effect :). Later I’ll probably try using a mesh instead of a plain ellipse to give my sun some detail. Cheers!
Yes, I’m interested in the circle mesh code as well. I would have thought that a mesh for a circle would be very expensive, but I think I might have a skewed impression of meshes.
or create a mesh with the convenient triangulate function:
local steps, radius, vs = 100, 100, {}
for i=1,steps do
local a = i/steps * math.pi * 2
table.insert(vs, vec2(math.cos(a), math.sin(a)) * radius)
end
m = mesh
m.vertices = triangulate(vs)
Here’s an example using the above code. The circle could be a solid color, but I wanted to show how the circle is made up of the different triangular meshes. I have a random color to show the different meshes. You can change the number of edges by sliding your finger up or down the screen. The more edges, the smoother the circle.
displayMode(FULLSCREEN)
function setup()
radius=math.min(WIDTH,HEIGHT)/2
dy=10
h=0
m=mesh()
setup1()
end
function setup1()
count=0
tot=0
vs={}
steps=math.floor(dy)
if steps~=h then
h=steps
for i=1,steps do
a = i/steps * math.pi * 2
table.insert(vs, vec2(math.cos(a), math.sin(a)) * radius)
end
m.vertices = triangulate(vs)
m:setColors(255,255,255)
for z=1,#m.vertices,3 do
r=math.random(255)
g=math.random(255)
b=math.random(255)
m:color(z,r,g,b)
m:color(z+1,r,g,b)
m:color(z+2,r,g,b)
end
end
end
function draw()
background(40, 40, 50)
fill(255)
tot=tot+DeltaTime
count=count+1
text("Show edges 3 to 100",100,HEIGHT-100)
text("Outside edges "..steps,100,HEIGHT-150)
text("vertices "..#m.vertices,100,HEIGHT-200)
text("Meshes "..#m.vertices/3,100,HEIGHT-250)
translate(WIDTH/2,HEIGHT/2)
m.draw(m)
translate()
end
function touched(t)
if t.state==BEGAN or t.state==MOVING then
dy=dy+(t.deltaY/25)
if dy<3 then
dy=3
elseif dy>100 then
dy=100
end
setup1()
end
end