Starling Forum

The Starling Framework Community

Register or log in - lost password?

Starling Forum » Starling Framework » General Discussion

Dynamic Texture Atlas Generator - Starling extension

(108 posts) (36 voices)
  • Started 1 year ago by emibap
  • Latest reply from megnathamuthan

Tags:

  • atlas
  • Benchmarking
  • Big Texture
  • collision
  • collision detection
  • Dynamic
  • dynamic atlas
  • Dynamic Texture Atlas Generator
  • DynamicTextureAtlasGenerator
  • generator
  • GridCanvas
  • hit zone
  • MovieClip
  • performance
  • scaling
  • Texture
  • texture atlas
  • TextureAtlas
  • tutorial
« Previous1…34
  1. emibap

    Competent Bird
    Joined: Sep '11
    Posts: 50

    Hi,

    First one idea: Wouldn't it be better if your saved a spritesheet (a png and an xml file) instead of multiple images. I know its harder to achieve but a lot better in terms of future use and performance. In fact this was an idea that I'm considering. Sam Rivello suggested it some months ago.

    The first time the app is started means that it's using the Dynamic Atlas right? You get the error when loading the files then.
    If the files are being generated you might want to check the way you are saving/loading them.

    I'll try to take a look at your code, but in the meantime try to load that image as a BitmapData and add it to the regular Display List as a Bitmap, just to make sure that there are no issues with the image generation.

    Cheers

    Posted 11 months ago #
  2. NeedNap

    Novice Bird
    Joined: May '12
    Posts: 19

    Hi emibap,
    your idea is better than my code; it's a next step to the performance optimization process.

    I'll try to do that!

    Coming back to my problem, I had debug the application on my iPhone and there aren't errors: all works fine but the images are not displayed.
    When I try my code in the Flash Builder emulation environment all works fine!

    So I think the problem is not in the save/load images...

    However I tried to show the loaded images using regular DisplayList object but the result is the same: the images are not displayed!

    Thank you for your tips,
    I hope you can help me to find a solution

    Posted 11 months ago #
  3. RRAway

    Novice Bird
    Joined: May '12
    Posts: 15

    Your current implementation assumes that all children will be MovieClips. This is not always the case, and I don't think it needs to be implemented that way anyway.

    Using single frame objects, items can be exported from the IDE as FlexSprites rather than MCs. This will break your DynamicAtlas.

    FlexSprites still inherit from DisplayObject and support IBitmapDrawable (as do all the native DOs I think?). Changing support to DO also gives better flexibility for anything else that we might want to do at runtime (composition of stuff, static TF text, who knows...).

    I have submitted a patch to change this behaviour, though feel free to change the implementation if it's not to your taste.

    Posted 11 months ago #
  4. emibap

    Competent Bird
    Joined: Sep '11
    Posts: 50

    Hi,
    Thank you very much. I think you're right, I overlooked that detail. I'll change it as soon as possible.

    Cheers

    Posted 11 months ago #
  5. alex_h

    Moderating Bird
    Joined: Feb '10
    Posts: 192

    Hey emibap,

    I've just had a chance to try out your dynamic atlas generator, seems like it could be very useful!
    Previously I have always used the awesome TexturePacker software. One really useful feature of TexturePacker is that it compares the images you add, and any ones that are found to be identical are only included once, but with multiple texture entries pointing to them in the XML. This is something that can really help cut down the amount of texture memory you end up using so can be quite a life saver! I was wondering whether it might not be possible to achieve the same result in your atlas generator by using the BitmapData.compare method to identify matching frames in the movieclips it scans? For some animations this could allow you to end up with a much smaller atlas.

    I did find when I tested the atlas generator with an animated dancing character that I ran into the issue mentioned in some posts above whereby the textures were being stretched and shrunk at various points throughout the animation, and I had to use the workaround of sticking a transparent square on a background layer to ensure all the frames came out at the correct size. I get the feeling something might still not be quite right with the way the bounds are being calculated or applied when the checkBounds parameter is set to true.

    cheers,
    Alex

    Posted 9 months ago #
  6. emibap

    Competent Bird
    Joined: Sep '11
    Posts: 50

    Hi Alex,

    Yes, what you mentioned (both the bug and the feature) are present in my mental roadmap, but I don't think that I'll have the time to fix/enhance this extension for a while.
    Another good addition could be adding the Rectangle Packing solution developed by Ville Koskela (http://villekoskela.org/2012/08/12/rectangle-packing/).
    If anyone wishes to contribute forking and pulling we'd all benefit from it
    Cheers!

    Posted 9 months ago #
  7. alex_h

    Moderating Bird
    Joined: Feb '10
    Posts: 192

    Hi emibap,

    ok cool, well if I get the chance to look into any of this myself then I'll be sure to share the code!

    cheers,
    Alex

    Posted 9 months ago #
  8. whizzkid

    Novice Bird
    Joined: Aug '12
    Posts: 6

    Hey there,
    When you use the generator with CheckBounds=true and you have movieclips with only 1 frame, their position is off.

    This is caused by the frameBounds check only being performed if you have more than 1 frame.

    If you change the code as follows, that problem is resolved.

    regards

    // Gets the frame bounds by performing a frame-by-frame check
    if (checkBounds)
    {
    	selected.gotoAndStop(0);
    	frameBounds = getRealBounds(selected);
    	if (selectedTotalFrames > 1)
    	{
    		m = 1;
    		while (++m <= selectedTotalFrames)
    		{
    			selected.gotoAndStop(m);
    			frameBounds = frameBounds.union(getRealBounds(selected));
    		}
    	}
    }
    Posted 8 months ago #
  9. esDot

    Senior Bird
    Joined: Sep '11
    Posts: 177

    This needs to be integrated into the main trunk!!

    Dynamic Texture Atlas is a core feature, it deserves regular maintenance and documentation.'

    Thoughts?

    Posted 8 months ago #
  10. Freddufau

    Competent Bird
    Joined: Sep '11
    Posts: 28

    HI, thanks for sharing this great tool emibap.

    I've a strange issue. I've some vector assets in a swc and generate the texture of them with DTAG. It's work fine on desktop. But when i go to iPad(2), the vector are not very smooth (it's like the effect of stage.quality = "low").
    I haven't see any post on this issue, so i was wondering what i'm missing.
    I've the same code as the sample you give, the only difference is that i change the color of some assets.

    thanks.

    Edit: it's not a DTAG issue, after a simple test, when i use vector asset and then draw them on a bitmapData and then generate the texture with this bitmapdata, i've the same issue, the vector assets are not antialiased.
    So my question turn into : How to have good quality with vector asset that are convert to textures at runtime ?

    Here the constructor of custom button class :

    public function JewelCategoryIcon(fontName:String, categoryID:int = 0, fontSize:int = 24, fontColor:uint = 0xFFFFFF, iconColor:uint = 0xF7931E, label:String = "BAGUES"
    										)
    		{
    			_categoryID = categoryID;
     
    			var border:MovieClip = new squareBorder();
    			var icon:MovieClip = new watchIcon();
    			ColorUtil.setColor(icon, iconColor );
    			icon.x = (border.width - icon.width) >> 1;
    			icon.y = (border.height * .12 );
    			border.addChild( icon );
     
    			var bmpd:BitmapData = new BitmapData(border.width, border.height, true, 0);
    			bmpd.draw( border );
     
    			super(Texture.fromBitmapData(bmpd), label );
     
    			bmpd.dispose();
    			border = null;
    			icon = null;
     
    			this.fontName = fontName;
    			this.fontSize = fontSize;
    			this.fontColor = fontColor;
     
    			this.textBounds = new Rectangle(0, downState.height - 80, downState.width, 80);
     
    		}

    What i'm missing ?

    Posted 8 months ago #
  11. Etherlord

    Hatchling
    Joined: Dec '12
    Posts: 2

    Hi! This is a very useful extension! I'm having a small problem though, I can't understand how the order of frames is determined. Here's my code:

    var snowflakes:Vector.<Class> = new <Class>[S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15,S16,S17,S18];
    bitmaps.push ( new Logo() );
    bitmaps.push ( gradientBmp );
    numSnowFlakes = snowflakes.length;
    for ( var i:int = 0; i < numSnowFlakes; i++ ) {
    	bitmaps.push ( new snowflakes[i]() );
    }
     
    var atlas:TextureAtlas = DynamicAtlas.fromBitmapVector (  bitmaps, 1, 0, true, true );
     
    frames = atlas.getTextures ();

    Now, for some reason, Logo texture (added first to bitmaps vector) is indeed the first texture in atlas, but gradient texture is last, though it's added as second to bitmap vector!

    I'm not using it for a movieclip, but to draw these snowflakes, gradient and logo, so the order of textures is not a big problem. However, I'm worried that the order will change for some unknown reason in future (like less snowflakes textures or different sizes of bitmaps).

    So how do I force a right order or detect what item is where in the atlas? Thanks!

    BTW, is it possible to get/buy this avatar generating script you have here?

    And here's fromBitmapVector code, if you wonder where did I get it from (it's just a modified fromClassVector method)

    static public function fromBitmapVector(assets:Vector.<Bitmap>, scaleFactor:Number = 1, margin:uint=0, preserveColor:Boolean = true, checkBounds:Boolean=false):TextureAtlas
    {
    	var container:MovieClip = new MovieClip();
    	for each (var bmp:Bitmap in assets) {
    		bmp.name = getQualifiedClassName(bmp);
    		container.addChild( bmp );
    	}
    	return fromMovieClipContainer(container, scaleFactor, margin, preserveColor, checkBounds);
    }
    Posted 5 months ago #
  12. winxalex

    Novice Bird
    Joined: Apr '12
    Posts: 19

    Hi Emi
    I understand that Danial like to bit seal stuff in the classes and maybe getter setter of texture in TextureAtlas would make process easier and faster, but I see great performance increase if creation of xml and parsing of xml is avoided in process. Talking about below:

    for (var k:uint = 0; k < itemsLen; k++)
    {
    itm = _items[k];

    itm.graphic.dispose();

    // xml
    subText = new XML(<SubTexture />);
    subText.@name = itm.textureName;
    subText.@x = itm.x;
    subText.@y = itm.y;
    subText.@width = itm.width;
    subText.@height = itm.height;
    subText.@frameX = itm.frameX;
    subText.@frameY = itm.frameY;
    subText.@frameWidth = itm.frameWidth;
    subText.@frameHeight = itm.frameHeight;

    if (itm.frameName != "")
    subText.@frameLabel = itm.frameName;
    xml.appendChild(subText);
    }

    and then in TextureAtlas parseXML().

    I propose you create new TextureAtlas(texture,null)
    use addRegion(itm.textureName,new Rectangle(itm.x,itm.y,itm.width,itm.height),new Rectangle(itm.frameX,...)) to fill texture atlas frames instead.
    Here comes the story of having TextureAtlas.texture setter that would allow one less loop.

    The other thing is why we need new TextureAtlas is that we could now return filters from mc and not to draw them in Bitmap but apply them in Starling now we have filters there.
    Regards
    Alex

    P.S Parser should back Atlas, frameLabels, filters and bones

    Posted 5 months ago #
  13. SudoPlz

    Senior Bird
    Joined: Oct '12
    Posts: 69

    Forgive me if someone else has mentioned this in the past, but I have a problem with this extension and at this specific moment I don't have time to read all the past posts.
    It might be something many people are aware of, so there it goes..:

    I'm using this extension, i create a MovieClip container, on which I add sprites as children, then I pass this MovieClip on the fromMovieClip function and it all works perfectly fine on iphone simulator with a scale factor of 1 ! But when i switch to the iPad which has a scale factor of 3 (for example) then this DynamicAtlas generator creates an Atlas that has wrong propotions.

    eg: I give an image of 768x1023 and content scale factor of 3
    I then check the atlas png (the big atlas png which the xml reads from),
    and its size is 768x9215 ..!
    It's driving me nuts..

    Any ideas for what might be wrong?

    (plz excuse me if this has been answered in the past!)

    Posted 5 months ago #
  14. Etherlord

    Hatchling
    Joined: Dec '12
    Posts: 2

    SudoPlz, from the numbers it looks like your height (if the second value is height) is multiplied by 3 twice. Maybe the bug is in your code and you do something like this:
    mc.height *= 3
    mc.height *= 3 //instead of width

    Common copy-paste mistake.

    Posted 4 months ago #
  15. wrench

    Senior Bird
    Joined: Jun '12
    Posts: 176

    For a while now I've been thinking that the DynamicAtlas class isn't doing an optimal job of fitting all of my sprites into the TextureAtlas. The actual reason is that some of the Movieclips rely on a mask, and so the Sprite's size is increased to match the size of the mask (even though the content being masked is much smaller than the mask). I can adjust the size of the mask in this instance to solve my issue, but going forwards a rethink of the class may be useful.

    In the past I've had to take Bitmap grabs of Movieclip's containing masks to get the correct bounding box for them. DynamicAtlas is already doing this, so within the drawItem method instead of doing the getRealBounds before the bitmap is created, it may need to be done after the bitmap is created (though this may defeat the purpose of getRealBounds anyway).

    Check out this feature that Daniel's just added (https://github.com/PrimaryFeather/Starling-Framework/issues/261) if you wanted to see what your TextureAtlas actually looks like.

    Posted 4 months ago #
  16. DarthCoder

    Hatchling
    Joined: Jan '13
    Posts: 2

    Thanks @wrench for doing taking the time to investigate.

    I've been having problems with loading just 8 short animations, some are single frame movieclips, some up to 80 frames, all less than 100x100. I was excited when the first few tests worked, then i realized as i kept adding more it kept adding to the same single TextureAtlas.

    I originally thought that each call to DynamicAtlas.fromMovieClipContainer() returning a TextureAtlas were "different" spritesheets, and that as long as each atlas were within the 2048x2048 limit, i'd be fine. now i know that they all combine into a single managed TextureAtlas.

    Though even if i export my spritesheets manually with TexturePacker, when i create MovieClips with TextureAtlas, won't i run into the same problem where starling automatically combines them into a super texture and i'm once again limited to 2048x2048 worth of frames?

    How do i go about having two different MovieClips simultaneously using two different TextureAtlas if only one TextureAtlas can be active at any one time?

    Posted 4 months ago #
  17. Nebula

    Novice Bird
    Joined: Aug '12
    Posts: 13

    Thanks for this extensions!

    I would love to use it for my upcomming project but am having the following issue.

    I have 3 assets that when exported from flash CS6's sprite sheet export (with stacking and trimming off) will only take up to half of a 2048x2048 sprite sheet space.

    However when using those same 3 assets with the Dynamic Atlas system - I get the catch error (sprite sheet too big...).

    What is the cause of this?
    I'm setting up my fla exactly like in the example ie. container movie clip with 3 child clips. Does the extension have any trimming process in place?

    Any advice would be great.
    Thanks

    Posted 3 months ago #
  18. megnathamuthan

    Hatchling
    Joined: Apr '13
    Posts: 2

    Hi folks,

    Is there is a way to load the swf asset dynamically and extract the vector class and use it in the Dynamic Texture Atlas Generator, becoz all example i see here, seems we need to embed the swc, which will increase the app pack size, i tried loading swf in IOS it doesn't work, please suggest...

    Posted 3 weeks ago #

RSS feed for this topic

« Previous1…34

Reply

You must log in to post.

Gamua - Consistent Game Development across all Platforms