locked
Best way to load animated and non animated images? RRS feed

  • Question

  • What is the best way to do the following?

     

     Load images for animations 
    • Using a spritesheet and an image brush to fill a rectangle
    • Using a spritesheet and a clipping region on the spritesheet
    • Using separate .png files
    • Other, please explain
     Load non-animated images 
    •  Using a spritesheet and a clipping region on the spritesheet
    •  Using separate .png files
    • Other, please explain
      How does GPU acceleration affect the techniques above?  Should all my images be powers of 2?

     

    Sunday, November 22, 2009 1:31 PM

Answers

  • One method is to load up the entire image then use a writeable bitmap to cut up all the images into smaller images then bung them where you need them, or like alot of people do load up your image and just create a clipping sub element of the image that is a rectangle and just set the clipping to the coords of the sprite in the map...

    I think powers of 2 are best but i dont think there is much of a performance penalty if its not (although i may be wrong)...

    I never liked the idea of loading a large image then just clipping it, as i felt it was just wasteful... if you had a 256x256 image and you had 10 sprites using it you would have assigned that image/texture 10 times, and im sure it each has its own copy of the image, which seems to be a large memory hog... ALTHOUGH saying that im sure with BitmapCaching on you can boost performance as it just stores it once in memory that way then...

    I went with a kinda weird implementation where i pre-slice up all my images and embed them within XML files and load them in that way, so i only need to do 1 WebClient request to load it all up then just convert it from serialized data to an image then it all just works, although if you didnt bung it all in one file and loaded LOTS of smaller sprites up you may find it a bit inefficient using lots of smaller WebClient requests...

    Sorry there is no code contained, but there is plenty of information on how to do clipping with tilesets out there, much fewer resources on using different methods... not sure which method SL3/4 favours for overall performance and memory usage...

    Monday, November 23, 2009 3:27 AM
  • It is going to depend on exactly how you need your sprites to behave.

    The most nasty issue you'll need to consider is that Silverlight does not provide hardware acceleration for clipping regions which are not at right angles.  This means that if you want to rotate a clipped sprite sheet at an angle other than 0, 90, 180, or 270, your hardware acceleration breaks -- CPU usage will spike and frame rate will tank.

    If you're not rotating the sprite sheet outside of right angles, then sheet + clipping region is probably the most optimal method on frame rates (but not the best for memory).  Also Silverlight hates very large images which can cause clipping region and culling artifacts.  Power of 2s is not required, but I wouldn't risk using anything else just in case.

    There are also some sweet bugs in Silverlight 3 with clipping regions that are a headache to deal with. Part of the unlisted features upgrade from version 2 to 3... You'll get bizarre flickering and clipping behaviors trying to apply transformations.  It just sucks.

    I wasted hundreds of hours figuring out optimal animation methods in Silverlight 3 with the least amount of headaches.

    Best method that I've found: Individual .PNGs with BitmapCache, stack them up, use Image.Opacity property to flip through them in order as Opacity is hardware accelerated.  Make sure you're using Scale/Rotate/Translate to move your elements and not any other method like SetValue on Canvas.TopProperty.

    I also re-use the Image elements.  Once they're added to my main canvas, they never get taken off.  Just Opacity set to zero and picked up again when I need an Image element.

    You may need to adjust method based on exact requirements, but this has been pretty effective for me. I've built some very complex particle engines and game visuals that have thousands of elements on the screen without frame rate drops.

     

    Monday, November 23, 2009 3:15 PM

All replies

  • One method is to load up the entire image then use a writeable bitmap to cut up all the images into smaller images then bung them where you need them, or like alot of people do load up your image and just create a clipping sub element of the image that is a rectangle and just set the clipping to the coords of the sprite in the map...

    I think powers of 2 are best but i dont think there is much of a performance penalty if its not (although i may be wrong)...

    I never liked the idea of loading a large image then just clipping it, as i felt it was just wasteful... if you had a 256x256 image and you had 10 sprites using it you would have assigned that image/texture 10 times, and im sure it each has its own copy of the image, which seems to be a large memory hog... ALTHOUGH saying that im sure with BitmapCaching on you can boost performance as it just stores it once in memory that way then...

    I went with a kinda weird implementation where i pre-slice up all my images and embed them within XML files and load them in that way, so i only need to do 1 WebClient request to load it all up then just convert it from serialized data to an image then it all just works, although if you didnt bung it all in one file and loaded LOTS of smaller sprites up you may find it a bit inefficient using lots of smaller WebClient requests...

    Sorry there is no code contained, but there is plenty of information on how to do clipping with tilesets out there, much fewer resources on using different methods... not sure which method SL3/4 favours for overall performance and memory usage...

    Monday, November 23, 2009 3:27 AM
  • It is going to depend on exactly how you need your sprites to behave.

    The most nasty issue you'll need to consider is that Silverlight does not provide hardware acceleration for clipping regions which are not at right angles.  This means that if you want to rotate a clipped sprite sheet at an angle other than 0, 90, 180, or 270, your hardware acceleration breaks -- CPU usage will spike and frame rate will tank.

    If you're not rotating the sprite sheet outside of right angles, then sheet + clipping region is probably the most optimal method on frame rates (but not the best for memory).  Also Silverlight hates very large images which can cause clipping region and culling artifacts.  Power of 2s is not required, but I wouldn't risk using anything else just in case.

    There are also some sweet bugs in Silverlight 3 with clipping regions that are a headache to deal with. Part of the unlisted features upgrade from version 2 to 3... You'll get bizarre flickering and clipping behaviors trying to apply transformations.  It just sucks.

    I wasted hundreds of hours figuring out optimal animation methods in Silverlight 3 with the least amount of headaches.

    Best method that I've found: Individual .PNGs with BitmapCache, stack them up, use Image.Opacity property to flip through them in order as Opacity is hardware accelerated.  Make sure you're using Scale/Rotate/Translate to move your elements and not any other method like SetValue on Canvas.TopProperty.

    I also re-use the Image elements.  Once they're added to my main canvas, they never get taken off.  Just Opacity set to zero and picked up again when I need an Image element.

    You may need to adjust method based on exact requirements, but this has been pretty effective for me. I've built some very complex particle engines and game visuals that have thousands of elements on the screen without frame rate drops.

     

    Monday, November 23, 2009 3:15 PM