Howdy, Stranger!

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

How does sprite() load images?

edited April 2012 in General Posts: 25

This has been playing on my "programmer's brain" for a bit: when we call sprite("sprite:name",0,0) when is the sprite loaded? I'm guessing it doesn't re-load an image every frame... it must keep a reference? Is it more efficient for us to load an image, and pass that to the sprite() call, or is this handled magically?

Thanks!

Tagged:

Comments

  • DylanDylan Admin Mod
    Posts: 121

    It stores it in a cache which is cleared when memory starts to get low.

  • Posts: 25

    The reason I ask is that I'm setting up an animation system (flip-book style) that works something like this:

    runAnim = Animation({"MyPack:RunFrame1", "MyPack:RunFrame2", "MyPack:RunFrame3"}, speed)
    

    Then the animation cycles through drawing the frames in the draw method:

    sprite(self.currFrame, x, y)
    

    Can you see any problems with doing it this way? I just feel like lazy-loading things is, well, actually, I don't know why I feel uneasy about it so I thought I'd ask ;)

  • SimeonSimeon Admin Mod
    Posts: 4,958

    It should be okay. I believe another user (@VoiceOfTreason?) did this for his zombie game. If the sprites are small they should load quite fast. And once they are cached there is no additional loading.

  • edited April 2012 Posts: 196

    Hey there,

    I'be been playing around with animated sprites using imported sprite sheets.

    I noticed that when updating my frames (i'm using mesh class but as you will see below, behavior is the same), drawing the art on an image using set context, then using mesh.texture = image is much much much faster than using mesh.texture = string (string being something like "MyPack:RunFrame1").

    For example, on my iPad 1, drawing 1000 animated sprites that rotate towards and follow my finger:
    Using mesh.texture = image, i get around 12fps.
    Using mesh.texture = string i get less than 1 fps.

    Using just the sprite(string) function, doing this runs at around 2fps

    function draw()
       for i=1, 1000 do
          sprite("RPG:fireball_1")
       end
    end
    

    Using sprite(image) function, this runs at around 25fps

    function setup()
       img = image(64,64)
       setContext(img)
       sprite("RPG:fireball_1")
    end
    
    function draw()
       for i=1, 1000 do
          sprite(img)
       end
    end
    

    In my program, both methods look like they get cached in memory (start a bit slower on initial art display then it goes faster ones all frames ran once), but using string as texture source seems to generate image in the background or something like that, everytime it's called.

    edit- I reckon it's faster to use a sprite sheet of size 512x512 (individual art size being 64x64) and specifying new mesh.textCoords on frameswitch, than using 64 sprites of size 64x64 and then switching the mesh.texture. Unfortunately that's all I have for now, will try to regroup them into an atlas when I have the time.
    Im curious though... Does displaying only a fraction of a 512x512 have the same speed as displaying it fully ?

    Cheers,

    Xavier

  • SimeonSimeon Admin Mod
    Posts: 4,958

    Switching using mesh.texCoords should be faster than changing mesh.texture. (Unless it's computationally difficult to change texCoords — though it shouldn't be.)

    Thanks for the mini-benchmark on the sprite string performance. I will have to see what the bottleneck is. Probably the texture look-up.

  • Posts: 159

    For my Space Invaders example, I did it very simply and just did (essentially):

    sprite(self.images[self.currentFrame])
    self.currentFrame = self.currentFrame + 1
    

    And performance was fine even with lots of sprites on screen. I imagine the ideal way to do this though would be a mesh using a spritesheet image and changing texCoords - that way, OpenGL doesn't have to keep switching textures.

  • edited March 2014 Posts: 16

    Hi !

    When the image is loaded, is it loaded entirely or just according to the size we want ?

    What I'm asking is if

    for i=1,100 do
     sprite(myImg,0,0,50,50) 
    end
    

    has the same speed with a 50x50 image and with a 500x500 image ? I tried to compare them but I wasn't able to notice any difference, and it surprised me !

    Also, is

    sprite(myImg,0,0,r,r)
    r=r+1
    

    reloading the image each time ?

  • IgnatzIgnatz Mod
    Posts: 5,396

    @RyZum - as far as I know, if you have loaded a sprite into a variable with readImage then it only gets loaded that once, and stays in memory thereafter.

  • Posts: 16

    Thanks !

    In my project, I only need to draw many small images on the screen (50x50), but I only have 500x500 images. So my question is : do I have to convert the images manually before (with an external program), or will codea handle it if I only use the function

    sprite(my500x500Img,x,y,50,50)
    
  • IgnatzIgnatz Mod
    edited March 2014 Posts: 5,396

    @RyZum - you could "resize" them by creating a small image in memory and drawing your big image onto it, like so

    img=image(50,50)
    setContext(img) --draw onto our image
    sprite("Documents:LargeImage",25,25,50) --draw and resize large image to 50 pixels
    setContext() --stop drawing on our image
    --now img is a 50x50 replica of the original
    
  • Posts: 16

    Thanks a lot !

Sign In or Register to comment.