Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Large circle/ellipse renders slowly

edited February 2012 in Questions Posts: 65

Hi All!

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.




  • SimeonSimeon Admin Mod
    Posts: 5,718

    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.

  • edited February 2012 Posts: 65

    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!

  • Posts: 35

    Hi Simeon. I would be glad to see the circle ( or ellipse) mesh code. Thanks.

  • Posts: 53

    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.

  • Posts: 1,595

    The circle mesh code is the ellipse shader, which uses quite a bit of math when drawing, I use a circle texture on a mesh to speed things up

  • Posts: 521

    Here is a link to the old circle shader from the time when Codea still had an open source runtime. So it might be something similar.

    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)
    m = mesh
    m.vertices = triangulate(vs)
  • dave1707dave1707 Mod
    Posts: 9,730

    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
Sign In or Register to comment.