best method for sprite sheet animation in nme/cpp?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

best method for sprite sheet animation in nme/cpp?

Alex Liebert
After a couple months of work, my multiplatform (iphone, android, pc, flash- thanks haXe!) game is gameplay solid and ready to add some graphics.  I was wondering what other people have done implementation wise to render frame-based animations.

There's a thread where this was discussed a bit, and Hugh said copyPixels won't be efficient for this on the iPhone (presumably my most resource tight target) but the thread was a few months old so I don't know what the state of the art is.  It looks like the gm2d repo has some Tilesheet stuff, but it does not seem to be intended for this type of thing.

I'm looking to build a reusable game animation library now to put back out in haxelib so any input on the most efficient methods for frame based animation would be very helpful. (copypixels? flipping visibility? changing bitmapData property of a bitmap to a new image?  And are power of 2/ square sprite sheets going to be  better for opengl/iphone?)

Thanks!

Alex


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Tony Polinelli
I think Tilesheet is intended to be the most efficient for switching in textures (whether for arranging tiles or frames of an animation). So you are going down the right track. There are some examples in the gm2d repo as you know, just not any specifically for animation. I would be interested in seeing your progress as i was going to integrate tilesheets to the tmp animation class (for iphone) but havent had time.

cheers



On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert <[hidden email]> wrote:
After a couple months of work, my multiplatform (iphone, android, pc, flash- thanks haXe!) game is gameplay solid and ready to add some graphics.  I was wondering what other people have done implementation wise to render frame-based animations.

There's a thread where this was discussed a bit, and Hugh said copyPixels won't be efficient for this on the iPhone (presumably my most resource tight target) but the thread was a few months old so I don't know what the state of the art is.  It looks like the gm2d repo has some Tilesheet stuff, but it does not seem to be intended for this type of thing.

I'm looking to build a reusable game animation library now to put back out in haxelib so any input on the most efficient methods for frame based animation would be very helpful. (copypixels? flipping visibility? changing bitmapData property of a bitmap to a new image?  And are power of 2/ square sprite sheets going to be  better for opengl/iphone?)

Thanks!

Alex


--
haXe - an open source web programming language
http://haxe.org



--
Tony Polinelli
http://touchmypixel.com

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

justin_mills
In reply to this post by Alex Liebert
Maybe not relevent to your needs and I have not tried it, but Bit-101
has released an air app to help with creation of sprite sheets

http://www.bit-101.com/blog/?p=2948


Le 31/01/2011 06:17, Alex Liebert a écrit :

> After a couple months of work, my multiplatform (iphone, android, pc,
> flash- thanks haXe!) game is gameplay solid and ready to add some
> graphics.  I was wondering what other people have done implementation
> wise to render frame-based animations.
>
> There's a thread where this was discussed a bit, and Hugh said
> copyPixels won't be efficient for this on the iPhone (presumably my
> most resource tight target) but the thread was a few months old so I
> don't know what the state of the art is.  It looks like the gm2d repo
> has some Tilesheet stuff, but it does not seem to be intended for this
> type of thing.
>
> I'm looking to build a reusable game animation library now to put back
> out in haxelib so any input on the most efficient methods for frame
> based animation would be very helpful. (copypixels? flipping
> visibility? changing bitmapData property of a bitmap to a new image?
>  And are power of 2/ square sprite sheets going to be  better for
> opengl/iphone?)
>
> Thanks!
>
> Alex
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Gamehaxe
In reply to this post by Tony Polinelli
Hi,
There are a couple of considerations when optimising sprite.
On flash, the best way is copyPixels, but in opengl (iphone particularly)
this is about the worst - uploading textures is very expensive.

The gm2d.blit classes are designed to abstract out the best way for each
platform.  You start with a "viewport".  On flash, this is actually a
bitmap.  On opengl, it is basically a glViewport.

(Actually, there is 1 more complication - you add "layers" to the viewport,
and then render to these.  This allows you to have 1 static layer, and
one that is updated regularly).

In your "update" function, you use "addTile" to update the graphics.
In flash, this maps to a copyPixels.  In opengl, this adds an entry to
a list of textured-quads that will get rendered at display time.

This gives a nice API, with a small-ish overhead. Currently it runs about
40fps doing 600 32x32 sprites at retina res on a new ipod, slightly more
on a ipad.  There is probably a little room for improvement, but better
optimisations will come at a algorithm level later in the form of
some smart caching.

The Tilesheet api is very easy to use. You can add BitmapData to the  
Tilesheet
and it will make space for it.  You get a "Tile" in return that specifies
a rectangle on a texture (plus a "hotspot" offset).  If you have vector
data, render it to BitmapData first.  You then add these tiles to a bitmap
layer prior to rendering.

To make an animation, simply use a array of tiles, ad do something like:

layer.addTile( animation[ Std.int(frame) % animation.length], pos.x, pos.y  
);

If you don't like the abstractions, using the  
nme.display.Graphics.drawTiles
is still going to be the fastest way to draw in nme.

Hugh

> I think Tilesheet is intended to be the most efficient for switching in
> textures (whether for arranging tiles or frames of an animation). So you  
> are
> going down the right track. There are some examples in the gm2d repo as  
> you
> know, just not any specifically for animation. I would be interested in
> seeing your progress as i was going to integrate tilesheets to the tmp
> animation class (for iphone) but havent had time.
>
> cheers
>
>
>
> On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert  
> <[hidden email]>wrote:
>
>> After a couple months of work, my multiplatform (iphone, android, pc,
>> flash- thanks haXe!) game is gameplay solid and ready to add some  
>> graphics.
>>  I was wondering what other people have done implementation wise to  
>> render
>> frame-based animations.
>>
>> There's a thread where this was discussed a bit, and Hugh said  
>> copyPixels
>> won't be efficient for this on the iPhone (presumably my most resource  
>> tight
>> target) but the thread was a few months old so I don't know what the  
>> state
>> of the art is.  It looks like the gm2d repo has some Tilesheet stuff,  
>> but it
>> does not seem to be intended for this type of thing.
>>
>> I'm looking to build a reusable game animation library now to put back  
>> out
>> in haxelib so any input on the most efficient methods for frame based
>> animation would be very helpful. (copypixels? flipping visibility?  
>> changing
>> bitmapData property of a bitmap to a new image?  And are power of 2/  
>> square
>> sprite sheets going to be  better for opengl/iphone?)
>>
>> Thanks!
>>
>> Alex
>>
>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org
>>
>
>

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Alex Liebert
Hi Hugh,

Thanks for the explanation!  I'm trying to wrap my head around the nme internals, using gm2d as an example, in order to build a custom interface that best meets my project's needs.

I'm confused on a couple of points- can you tell me if these assertions are correct? (focused on the nme context for now)

1. A spritesheet/ texture is represented by an nme.display.Tilesheet.  You create it with the full spritesheet in bitmapdata form as a parameter.
2. then, you call addTileRect(inRect) for each frame of the spritesheet, where inrect is a rectangle representing the x,y,width,height of the frame within the spritesheet above.  nothing is returned, but it can be assumed that the 'id' is an int incremented from 0-n based on the order in which addTileRect was called.
3. To render, you create a Shape object and call shape.drawTiles(TileSheet,xyID) - where xyid is [TARGET x position of the frame, TARGET y, id of the frame as defined in #2].  The method is called drawTiles but really only draws a single 'frame'/tile from the spritesheet.


Assuming that, a few questions:

1. does nme.display.Stage.invalidate() ever need to be called by hand in this scenario, or will it happen automagically?
2. how can Tilesheets be properly disposed from memory?  Is nulling all references sufficient?
3. how does the approach above jive with a basic translation of flash haxe remapped to nme- specifically, what kind of cost (if any) would be incurred by taking a flash application with a displaylist hierarchy a few layers deep, but replacing all frame animation code with drawTiles calls on to shapes inside individual Sprites?  example:

Stage
  |
Sprite Characters
         |
       / | \
      /  |  \
Sprite Sprite Sprite 

...Where each Sprite at the bottom of the tree contains Graphics objects, into which frames from an nme.Tilesheet are being 'drawTile'd?  

Thanks!

Alex

On Mon, Jan 31, 2011 at 2:53 AM, Hugh Sanderson <[hidden email]> wrote:
Hi,
There are a couple of considerations when optimising sprite.
On flash, the best way is copyPixels, but in opengl (iphone particularly)
this is about the worst - uploading textures is very expensive.

The gm2d.blit classes are designed to abstract out the best way for each
platform.  You start with a "viewport".  On flash, this is actually a
bitmap.  On opengl, it is basically a glViewport.

(Actually, there is 1 more complication - you add "layers" to the viewport,
and then render to these.  This allows you to have 1 static layer, and
one that is updated regularly).

In your "update" function, you use "addTile" to update the graphics.
In flash, this maps to a copyPixels.  In opengl, this adds an entry to
a list of textured-quads that will get rendered at display time.

This gives a nice API, with a small-ish overhead. Currently it runs about
40fps doing 600 32x32 sprites at retina res on a new ipod, slightly more
on a ipad.  There is probably a little room for improvement, but better
optimisations will come at a algorithm level later in the form of
some smart caching.

The Tilesheet api is very easy to use. You can add BitmapData to the Tilesheet
and it will make space for it.  You get a "Tile" in return that specifies
a rectangle on a texture (plus a "hotspot" offset).  If you have vector
data, render it to BitmapData first.  You then add these tiles to a bitmap
layer prior to rendering.

To make an animation, simply use a array of tiles, ad do something like:

layer.addTile( animation[ Std.int(frame) % animation.length], pos.x, pos.y );

If you don't like the abstractions, using the nme.display.Graphics.drawTiles
is still going to be the fastest way to draw in nme.

Hugh


I think Tilesheet is intended to be the most efficient for switching in
textures (whether for arranging tiles or frames of an animation). So you are
going down the right track. There are some examples in the gm2d repo as you
know, just not any specifically for animation. I would be interested in
seeing your progress as i was going to integrate tilesheets to the tmp
animation class (for iphone) but havent had time.

cheers



On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert <[hidden email]>wrote:

After a couple months of work, my multiplatform (iphone, android, pc,
flash- thanks haXe!) game is gameplay solid and ready to add some graphics.
 I was wondering what other people have done implementation wise to render
frame-based animations.

There's a thread where this was discussed a bit, and Hugh said copyPixels
won't be efficient for this on the iPhone (presumably my most resource tight
target) but the thread was a few months old so I don't know what the state
of the art is.  It looks like the gm2d repo has some Tilesheet stuff, but it
does not seem to be intended for this type of thing.

I'm looking to build a reusable game animation library now to put back out
in haxelib so any input on the most efficient methods for frame based
animation would be very helpful. (copypixels? flipping visibility? changing
bitmapData property of a bitmap to a new image?  And are power of 2/ square
sprite sheets going to be  better for opengl/iphone?)

Thanks!

Alex


--
haXe - an open source web programming language
http://haxe.org




--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Gamehaxe
Hi,
I think the easiest way to think of tilesheets is that they are nothing
but a BitmapData (texture) plus a rectangle list.  The rectangles
"live" in the NME C++ code for efficient access, since transferring
the data between haxe and NME can be expensive.
The rectangles can the tracked by ordinal position in haxe as you suggest.

The "drawTiles" can draw multiple tiles - eg you can pass in an array:

[ x1, y1, id1, x2, y2,id2, x3, y3, id3 ..... ] but they must have the same  
"tilesheet".

This is all about efficiency.  Currently, passing an array of doubles
over the CFFI from haxe to NME is about the most efficient way you can
transfer data.  And not swapping textures is encouraged for mobile  
development.

Adding "drawTiles" in a "Graphics" display list is very efficient.
Eg, it is in some ways equivalent to, but more efficient than, doing:
beginBitmapFill(bmp), drawRect() endFill().  You can choose to translate
the tiles with the displayobject.x property if you like.
But you will get more benefit if you group all your tiles into a single
call, rather than have separate "Sprite" objects, since you will have
only 1 matrix, 1 object etc.  This is quite similar to the advantages
you get with you use "copyPixels" to draw your objects in flash.
The gm2d library tries to abstract out the differences between "optimal  
NME"
and "optimal flash" to provide a unified API.
The disadvantage of the "optimized" way of not having separate "Sprites"  
is that
you need to do all the events/hit-test stuff yourself.

Making a tilesheet go out of scope or setting it to null will free it,
just like normal BitmapData.

So this API is designed for maximum efficiency.  It is then up to some
other library (eg, gm2g/yours) to add a layer on top of this to maybe make
it easier to use.


Hugh


> Hi Hugh,
>
> Thanks for the explanation!  I'm trying to wrap my head around the nme
> internals, using gm2d as an example, in order to build a custom interface
> that best meets my project's needs.
>
> I'm confused on a couple of points- can you tell me if these assertions  
> are
> correct? (focused on the nme context for now)
>
> 1. A spritesheet/ texture is represented by an nme.display.Tilesheet.  
> You
> create it with the full spritesheet in bitmapdata form as a parameter.
> 2. then, you call addTileRect(inRect) for each frame of the spritesheet,
> where inrect is a rectangle representing the x,y,width,height of the  
> frame
> within the spritesheet above.  nothing is returned, but it can be assumed
> that the 'id' is an int incremented from 0-n based on the order in which
> addTileRect was called.
> 3. To render, you create a Shape object and call
> shape.drawTiles(TileSheet,xyID) - where xyid is [TARGET x position of the
> frame, TARGET y, id of the frame as defined in #2].  The method is called
> drawTiles but really only draws a single 'frame'/tile from the  
> spritesheet.
>
>
> Assuming that, a few questions:
>
> 1. does nme.display.Stage.invalidate() ever need to be called by hand in
> this scenario, or will it happen automagically?
> 2. how can Tilesheets be properly disposed from memory?  Is nulling all
> references sufficient?
> 3. how does the approach above jive with a basic translation of flash  
> haxe
> remapped to nme- specifically, what kind of cost (if any) would be  
> incurred
> by taking a flash application with a displaylist hierarchy a few layers
> deep, but replacing all frame animation code with drawTiles calls on to
> shapes inside individual Sprites?  example:
>
> Stage
>   |
> Sprite Characters
>          |
>        / | \
>       /  |  \
> Sprite Sprite Sprite
>
> ...Where each Sprite at the bottom of the tree contains Graphics objects,
> into which frames from an nme.Tilesheet are being 'drawTile'd?
>
> Thanks!
>
> Alex
>
> On Mon, Jan 31, 2011 at 2:53 AM, Hugh Sanderson  
> <[hidden email]>wrote:
>
>> Hi,
>> There are a couple of considerations when optimising sprite.
>> On flash, the best way is copyPixels, but in opengl (iphone  
>> particularly)
>> this is about the worst - uploading textures is very expensive.
>>
>> The gm2d.blit classes are designed to abstract out the best way for each
>> platform.  You start with a "viewport".  On flash, this is actually a
>> bitmap.  On opengl, it is basically a glViewport.
>>
>> (Actually, there is 1 more complication - you add "layers" to the  
>> viewport,
>> and then render to these.  This allows you to have 1 static layer, and
>> one that is updated regularly).
>>
>> In your "update" function, you use "addTile" to update the graphics.
>> In flash, this maps to a copyPixels.  In opengl, this adds an entry to
>> a list of textured-quads that will get rendered at display time.
>>
>> This gives a nice API, with a small-ish overhead. Currently it runs  
>> about
>> 40fps doing 600 32x32 sprites at retina res on a new ipod, slightly more
>> on a ipad.  There is probably a little room for improvement, but better
>> optimisations will come at a algorithm level later in the form of
>> some smart caching.
>>
>> The Tilesheet api is very easy to use. You can add BitmapData to the
>> Tilesheet
>> and it will make space for it.  You get a "Tile" in return that  
>> specifies
>> a rectangle on a texture (plus a "hotspot" offset).  If you have vector
>> data, render it to BitmapData first.  You then add these tiles to a  
>> bitmap
>> layer prior to rendering.
>>
>> To make an animation, simply use a array of tiles, ad do something like:
>>
>> layer.addTile( animation[ Std.int(frame) % animation.length], pos.x,  
>> pos.y
>> );
>>
>> If you don't like the abstractions, using the
>> nme.display.Graphics.drawTiles
>> is still going to be the fastest way to draw in nme.
>>
>> Hugh
>>
>>
>>  I think Tilesheet is intended to be the most efficient for switching in
>>> textures (whether for arranging tiles or frames of an animation). So  
>>> you
>>> are
>>> going down the right track. There are some examples in the gm2d repo as
>>> you
>>> know, just not any specifically for animation. I would be interested in
>>> seeing your progress as i was going to integrate tilesheets to the tmp
>>> animation class (for iphone) but havent had time.
>>>
>>> cheers
>>>
>>>
>>>
>>> On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert  
>>> <[hidden email]
>>> >wrote:
>>>
>>>  After a couple months of work, my multiplatform (iphone, android, pc,
>>>> flash- thanks haXe!) game is gameplay solid and ready to add some
>>>> graphics.
>>>>  I was wondering what other people have done implementation wise to
>>>> render
>>>> frame-based animations.
>>>>
>>>> There's a thread where this was discussed a bit, and Hugh said  
>>>> copyPixels
>>>> won't be efficient for this on the iPhone (presumably my most resource
>>>> tight
>>>> target) but the thread was a few months old so I don't know what the
>>>> state
>>>> of the art is.  It looks like the gm2d repo has some Tilesheet stuff,  
>>>> but
>>>> it
>>>> does not seem to be intended for this type of thing.
>>>>
>>>> I'm looking to build a reusable game animation library now to put back
>>>> out
>>>> in haxelib so any input on the most efficient methods for frame based
>>>> animation would be very helpful. (copypixels? flipping visibility?
>>>> changing
>>>> bitmapData property of a bitmap to a new image?  And are power of 2/
>>>> square
>>>> sprite sheets going to be  better for opengl/iphone?)
>>>>
>>>> Thanks!
>>>>
>>>> Alex
>>>>
>>>>
>>>> --
>>>> haXe - an open source web programming language
>>>> http://haxe.org
>>>>
>>>>
>>>
>>>
>> --
>> haXe - an open source web programming language
>> http://haxe.org

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

singmajesty
The best approach I've found in Flash to handle tilesheets is the  
following:

  - Save the image in two files, one matte JPG and one matte "alpha map"  
image
  - Load both images into memory
  - On request, cut frames into their own BitmapData objects, merging the  
alpha
  - Swap the BitmapData object for each Bitmap to create animation

Using two images would not be necessary for mobile development, as it  
primarily is to save bandwidth, not runtime memory. However, I'm curious  
to understand the efficiencies of working with bitmaps in HXCPP. I know  
that you've already explained it, but just so I understand ...

So changing the BitmapData object in HXCPP would not be as efficient, but  
doing a copy from one BitmapData to the other is more efficient?

Swapping the data object is much faster in Flash than copying pixels, but  
this would be "swapping textures" like you've suggested not to do for  
mobile development?

Thanks!



On Sun, 06 Feb 2011 06:23:44 -0800, Hugh Sanderson <[hidden email]>  
wrote:

> Hi,
> I think the easiest way to think of tilesheets is that they are nothing
> but a BitmapData (texture) plus a rectangle list.  The rectangles
> "live" in the NME C++ code for efficient access, since transferring
> the data between haxe and NME can be expensive.
> The rectangles can the tracked by ordinal position in haxe as you  
> suggest.
>
> The "drawTiles" can draw multiple tiles - eg you can pass in an array:
>
> [ x1, y1, id1, x2, y2,id2, x3, y3, id3 ..... ] but they must have the  
> same "tilesheet".
>
> This is all about efficiency.  Currently, passing an array of doubles
> over the CFFI from haxe to NME is about the most efficient way you can
> transfer data.  And not swapping textures is encouraged for mobile  
> development.
>
> Adding "drawTiles" in a "Graphics" display list is very efficient.
> Eg, it is in some ways equivalent to, but more efficient than, doing:
> beginBitmapFill(bmp), drawRect() endFill().  You can choose to translate
> the tiles with the displayobject.x property if you like.
> But you will get more benefit if you group all your tiles into a single
> call, rather than have separate "Sprite" objects, since you will have
> only 1 matrix, 1 object etc.  This is quite similar to the advantages
> you get with you use "copyPixels" to draw your objects in flash.
> The gm2d library tries to abstract out the differences between "optimal  
> NME"
> and "optimal flash" to provide a unified API.
> The disadvantage of the "optimized" way of not having separate "Sprites"  
> is that
> you need to do all the events/hit-test stuff yourself.
>
> Making a tilesheet go out of scope or setting it to null will free it,
> just like normal BitmapData.
>
> So this API is designed for maximum efficiency.  It is then up to some
> other library (eg, gm2g/yours) to add a layer on top of this to maybe  
> make
> it easier to use.
>
>
> Hugh
>
>
>> Hi Hugh,
>>
>> Thanks for the explanation!  I'm trying to wrap my head around the nme
>> internals, using gm2d as an example, in order to build a custom  
>> interface
>> that best meets my project's needs.
>>
>> I'm confused on a couple of points- can you tell me if these assertions  
>> are
>> correct? (focused on the nme context for now)
>>
>> 1. A spritesheet/ texture is represented by an nme.display.Tilesheet.  
>> You
>> create it with the full spritesheet in bitmapdata form as a parameter.
>> 2. then, you call addTileRect(inRect) for each frame of the spritesheet,
>> where inrect is a rectangle representing the x,y,width,height of the  
>> frame
>> within the spritesheet above.  nothing is returned, but it can be  
>> assumed
>> that the 'id' is an int incremented from 0-n based on the order in which
>> addTileRect was called.
>> 3. To render, you create a Shape object and call
>> shape.drawTiles(TileSheet,xyID) - where xyid is [TARGET x position of  
>> the
>> frame, TARGET y, id of the frame as defined in #2].  The method is  
>> called
>> drawTiles but really only draws a single 'frame'/tile from the  
>> spritesheet.
>>
>>
>> Assuming that, a few questions:
>>
>> 1. does nme.display.Stage.invalidate() ever need to be called by hand in
>> this scenario, or will it happen automagically?
>> 2. how can Tilesheets be properly disposed from memory?  Is nulling all
>> references sufficient?
>> 3. how does the approach above jive with a basic translation of flash  
>> haxe
>> remapped to nme- specifically, what kind of cost (if any) would be  
>> incurred
>> by taking a flash application with a displaylist hierarchy a few layers
>> deep, but replacing all frame animation code with drawTiles calls on to
>> shapes inside individual Sprites?  example:
>>
>> Stage
>>   |
>> Sprite Characters
>>          |
>>        / | \
>>       /  |  \
>> Sprite Sprite Sprite
>>
>> ...Where each Sprite at the bottom of the tree contains Graphics  
>> objects,
>> into which frames from an nme.Tilesheet are being 'drawTile'd?
>>
>> Thanks!
>>
>> Alex
>>
>> On Mon, Jan 31, 2011 at 2:53 AM, Hugh Sanderson  
>> <[hidden email]>wrote:
>>
>>> Hi,
>>> There are a couple of considerations when optimising sprite.
>>> On flash, the best way is copyPixels, but in opengl (iphone  
>>> particularly)
>>> this is about the worst - uploading textures is very expensive.
>>>
>>> The gm2d.blit classes are designed to abstract out the best way for  
>>> each
>>> platform.  You start with a "viewport".  On flash, this is actually a
>>> bitmap.  On opengl, it is basically a glViewport.
>>>
>>> (Actually, there is 1 more complication - you add "layers" to the  
>>> viewport,
>>> and then render to these.  This allows you to have 1 static layer, and
>>> one that is updated regularly).
>>>
>>> In your "update" function, you use "addTile" to update the graphics.
>>> In flash, this maps to a copyPixels.  In opengl, this adds an entry to
>>> a list of textured-quads that will get rendered at display time.
>>>
>>> This gives a nice API, with a small-ish overhead. Currently it runs  
>>> about
>>> 40fps doing 600 32x32 sprites at retina res on a new ipod, slightly  
>>> more
>>> on a ipad.  There is probably a little room for improvement, but better
>>> optimisations will come at a algorithm level later in the form of
>>> some smart caching.
>>>
>>> The Tilesheet api is very easy to use. You can add BitmapData to the
>>> Tilesheet
>>> and it will make space for it.  You get a "Tile" in return that  
>>> specifies
>>> a rectangle on a texture (plus a "hotspot" offset).  If you have vector
>>> data, render it to BitmapData first.  You then add these tiles to a  
>>> bitmap
>>> layer prior to rendering.
>>>
>>> To make an animation, simply use a array of tiles, ad do something  
>>> like:
>>>
>>> layer.addTile( animation[ Std.int(frame) % animation.length], pos.x,  
>>> pos.y
>>> );
>>>
>>> If you don't like the abstractions, using the
>>> nme.display.Graphics.drawTiles
>>> is still going to be the fastest way to draw in nme.
>>>
>>> Hugh
>>>
>>>
>>>  I think Tilesheet is intended to be the most efficient for switching  
>>> in
>>>> textures (whether for arranging tiles or frames of an animation). So  
>>>> you
>>>> are
>>>> going down the right track. There are some examples in the gm2d repo  
>>>> as
>>>> you
>>>> know, just not any specifically for animation. I would be interested  
>>>> in
>>>> seeing your progress as i was going to integrate tilesheets to the tmp
>>>> animation class (for iphone) but havent had time.
>>>>
>>>> cheers
>>>>
>>>>
>>>>
>>>> On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert  
>>>> <[hidden email]
>>>> >wrote:
>>>>
>>>>  After a couple months of work, my multiplatform (iphone, android, pc,
>>>>> flash- thanks haXe!) game is gameplay solid and ready to add some
>>>>> graphics.
>>>>>  I was wondering what other people have done implementation wise to
>>>>> render
>>>>> frame-based animations.
>>>>>
>>>>> There's a thread where this was discussed a bit, and Hugh said  
>>>>> copyPixels
>>>>> won't be efficient for this on the iPhone (presumably my most  
>>>>> resource
>>>>> tight
>>>>> target) but the thread was a few months old so I don't know what the
>>>>> state
>>>>> of the art is.  It looks like the gm2d repo has some Tilesheet  
>>>>> stuff, but
>>>>> it
>>>>> does not seem to be intended for this type of thing.
>>>>>
>>>>> I'm looking to build a reusable game animation library now to put  
>>>>> back
>>>>> out
>>>>> in haxelib so any input on the most efficient methods for frame based
>>>>> animation would be very helpful. (copypixels? flipping visibility?
>>>>> changing
>>>>> bitmapData property of a bitmap to a new image?  And are power of 2/
>>>>> square
>>>>> sprite sheets going to be  better for opengl/iphone?)
>>>>>
>>>>> Thanks!
>>>>>
>>>>> Alex
>>>>>
>>>>>
>>>>> --
>>>>> haXe - an open source web programming language
>>>>> http://haxe.org
>>>>>
>>>>>
>>>>
>>>>
>>> --
>>> haXe - an open source web programming language
>>> http://haxe.org

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Alex Liebert
In reply to this post by Gamehaxe
Ahh ok, Thanks Hugh.  I wasn't grokking that I could pass multiple tiles to the drawTiles array param.  

Just finished wiring up the basics, super gratifying to see 100s of sprites animating at 30fps on the iphone!

Thanks,

Alex

On Sun, Feb 6, 2011 at 6:23 AM, Hugh Sanderson <[hidden email]> wrote:
Hi,
I think the easiest way to think of tilesheets is that they are nothing
but a BitmapData (texture) plus a rectangle list.  The rectangles
"live" in the NME C++ code for efficient access, since transferring
the data between haxe and NME can be expensive.
The rectangles can the tracked by ordinal position in haxe as you suggest.

The "drawTiles" can draw multiple tiles - eg you can pass in an array:

[ x1, y1, id1, x2, y2,id2, x3, y3, id3 ..... ] but they must have the same "tilesheet".

This is all about efficiency.  Currently, passing an array of doubles
over the CFFI from haxe to NME is about the most efficient way you can
transfer data.  And not swapping textures is encouraged for mobile development.

Adding "drawTiles" in a "Graphics" display list is very efficient.
Eg, it is in some ways equivalent to, but more efficient than, doing:
beginBitmapFill(bmp), drawRect() endFill().  You can choose to translate
the tiles with the displayobject.x property if you like.
But you will get more benefit if you group all your tiles into a single
call, rather than have separate "Sprite" objects, since you will have
only 1 matrix, 1 object etc.  This is quite similar to the advantages
you get with you use "copyPixels" to draw your objects in flash.
The gm2d library tries to abstract out the differences between "optimal NME"
and "optimal flash" to provide a unified API.
The disadvantage of the "optimized" way of not having separate "Sprites" is that
you need to do all the events/hit-test stuff yourself.

Making a tilesheet go out of scope or setting it to null will free it,
just like normal BitmapData.

So this API is designed for maximum efficiency.  It is then up to some
other library (eg, gm2g/yours) to add a layer on top of this to maybe make
it easier to use.


Hugh



Hi Hugh,

Thanks for the explanation!  I'm trying to wrap my head around the nme
internals, using gm2d as an example, in order to build a custom interface
that best meets my project's needs.

I'm confused on a couple of points- can you tell me if these assertions are
correct? (focused on the nme context for now)

1. A spritesheet/ texture is represented by an nme.display.Tilesheet.  You
create it with the full spritesheet in bitmapdata form as a parameter.
2. then, you call addTileRect(inRect) for each frame of the spritesheet,
where inrect is a rectangle representing the x,y,width,height of the frame
within the spritesheet above.  nothing is returned, but it can be assumed
that the 'id' is an int incremented from 0-n based on the order in which
addTileRect was called.
3. To render, you create a Shape object and call
shape.drawTiles(TileSheet,xyID) - where xyid is [TARGET x position of the
frame, TARGET y, id of the frame as defined in #2].  The method is called
drawTiles but really only draws a single 'frame'/tile from the spritesheet.


Assuming that, a few questions:

1. does nme.display.Stage.invalidate() ever need to be called by hand in
this scenario, or will it happen automagically?
2. how can Tilesheets be properly disposed from memory?  Is nulling all
references sufficient?
3. how does the approach above jive with a basic translation of flash haxe
remapped to nme- specifically, what kind of cost (if any) would be incurred
by taking a flash application with a displaylist hierarchy a few layers
deep, but replacing all frame animation code with drawTiles calls on to
shapes inside individual Sprites?  example:

Stage
 |
Sprite Characters
        |
      / | \
     /  |  \
Sprite Sprite Sprite

...Where each Sprite at the bottom of the tree contains Graphics objects,
into which frames from an nme.Tilesheet are being 'drawTile'd?

Thanks!

Alex

On Mon, Jan 31, 2011 at 2:53 AM, Hugh Sanderson <[hidden email]>wrote:

Hi,
There are a couple of considerations when optimising sprite.
On flash, the best way is copyPixels, but in opengl (iphone particularly)
this is about the worst - uploading textures is very expensive.

The gm2d.blit classes are designed to abstract out the best way for each
platform.  You start with a "viewport".  On flash, this is actually a
bitmap.  On opengl, it is basically a glViewport.

(Actually, there is 1 more complication - you add "layers" to the viewport,
and then render to these.  This allows you to have 1 static layer, and
one that is updated regularly).

In your "update" function, you use "addTile" to update the graphics.
In flash, this maps to a copyPixels.  In opengl, this adds an entry to
a list of textured-quads that will get rendered at display time.

This gives a nice API, with a small-ish overhead. Currently it runs about
40fps doing 600 32x32 sprites at retina res on a new ipod, slightly more
on a ipad.  There is probably a little room for improvement, but better
optimisations will come at a algorithm level later in the form of
some smart caching.

The Tilesheet api is very easy to use. You can add BitmapData to the
Tilesheet
and it will make space for it.  You get a "Tile" in return that specifies
a rectangle on a texture (plus a "hotspot" offset).  If you have vector
data, render it to BitmapData first.  You then add these tiles to a bitmap
layer prior to rendering.

To make an animation, simply use a array of tiles, ad do something like:

layer.addTile( animation[ Std.int(frame) % animation.length], pos.x, pos.y
);

If you don't like the abstractions, using the
nme.display.Graphics.drawTiles
is still going to be the fastest way to draw in nme.

Hugh


 I think Tilesheet is intended to be the most efficient for switching in
textures (whether for arranging tiles or frames of an animation). So you
are
going down the right track. There are some examples in the gm2d repo as
you
know, just not any specifically for animation. I would be interested in
seeing your progress as i was going to integrate tilesheets to the tmp
animation class (for iphone) but havent had time.

cheers



On Mon, Jan 31, 2011 at 4:17 PM, Alex Liebert <[hidden email]
>wrote:

 After a couple months of work, my multiplatform (iphone, android, pc,
flash- thanks haXe!) game is gameplay solid and ready to add some
graphics.
 I was wondering what other people have done implementation wise to
render
frame-based animations.

There's a thread where this was discussed a bit, and Hugh said copyPixels
won't be efficient for this on the iPhone (presumably my most resource
tight
target) but the thread was a few months old so I don't know what the
state
of the art is.  It looks like the gm2d repo has some Tilesheet stuff, but
it
does not seem to be intended for this type of thing.

I'm looking to build a reusable game animation library now to put back
out
in haxelib so any input on the most efficient methods for frame based
animation would be very helpful. (copypixels? flipping visibility?
changing
bitmapData property of a bitmap to a new image?  And are power of 2/
square
sprite sheets going to be  better for opengl/iphone?)

Thanks!

Alex


--
haXe - an open source web programming language
http://haxe.org




--
haXe - an open source web programming language
http://haxe.org

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Paul Zirkle
In reply to this post by Alex Liebert
Hey Hugh,

I'm trying to follow suit, changing my iPhone code to use TileSheet to increase render performance too.

However, I already have a layer of abstraction above this-- it has its own "graphics" context that represents a "target texture" to draw into (it holds a BitmapData internally). When the graphics should be flushed to the screen, this bitmap data gets flushed in full to the screen, all of my blits before that are just BitmapData copy pixels.

This poses a problem for me trying to switch to TileSheet, because it expects you to call  OBJ.graphics.drawTiles(), where OBJ is of base type DisplayObject. This means I can only render TileSheets onto a "Bitmap" not just a "BitmapData"? Do I need to redesign my code to have a "Bitmap" as the object used by my "graphics" context?

-Paul Zirkle

Date: Tue, 8 Feb 2011 22:48:04 -0800
From: Alex Liebert <[hidden email]>
Subject: Re: [haXe] best method for sprite sheet animation in nme/cpp?
To: The haXe compiler list <[hidden email]>
Message-ID:
       <[hidden email]>
Content-Type: text/plain; charset="iso-8859-1"

Ahh ok, Thanks Hugh.  I wasn't grokking that I could pass multiple tiles to
the drawTiles array param.

Just finished wiring up the basics, super gratifying to see 100s of sprites
animating at 30fps on the iphone!

Thanks,

Alex

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: best method for sprite sheet animation in nme/cpp?

Alex Liebert
Hi Paul,

Don't know the details of your implementation, but the gm2d implementation of blitting (http://code.google.com/p/gm2d/) by Hugh is very good performance wise, especially if you're happy with an existing 'copypixels' based flash implementation.  I would say check that out and do the upfront work to replace your rendering code with gm2d if it fits with the rest of your project.

I did something a little different myself because my app makes substantial use of parenting in the displaylist and I needed to support that in conjunction with drawTiles() etc, but if you are already using a copypixels type solution you shouldn't need this.

Alex


On Wed, Feb 9, 2011 at 2:07 PM, Paul Zirkle <[hidden email]> wrote:
Hey Hugh,

I'm trying to follow suit, changing my iPhone code to use TileSheet to increase render performance too.

However, I already have a layer of abstraction above this-- it has its own "graphics" context that represents a "target texture" to draw into (it holds a BitmapData internally). When the graphics should be flushed to the screen, this bitmap data gets flushed in full to the screen, all of my blits before that are just BitmapData copy pixels.

This poses a problem for me trying to switch to TileSheet, because it expects you to call  OBJ.graphics.drawTiles(), where OBJ is of base type DisplayObject. This means I can only render TileSheets onto a "Bitmap" not just a "BitmapData"? Do I need to redesign my code to have a "Bitmap" as the object used by my "graphics" context?

-Paul Zirkle

Date: Tue, 8 Feb 2011 22:48:04 -0800
From: Alex Liebert <[hidden email]>
Subject: Re: [haXe] best method for sprite sheet animation in nme/cpp?
To: The haXe compiler list <[hidden email]>
Message-ID:
       <[hidden email]>
Content-Type: text/plain; charset="iso-8859-1"


Ahh ok, Thanks Hugh.  I wasn't grokking that I could pass multiple tiles to
the drawTiles array param.

Just finished wiring up the basics, super gratifying to see 100s of sprites
animating at 30fps on the iphone!

Thanks,

Alex

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org