Starling-Framework icon indicating copy to clipboard operation
Starling-Framework copied to clipboard

Invalid SubTexture created using another SubTexture as parent

Open b005t3r opened this issue 10 years ago • 25 comments

In my app I create a TextureAtlas using a texture obtained from another atlas, as described here: http://forum.starling-framework.org/topic/putting-one-textureatlas-inside-another-textureatlas. Now, when I create another Texture using this inner atlas, such Texture's frame is not set right, which in effect makes it render not the way it should.

As far as I can tell, this problem is due to SubTexture constructor not checking if its parent texture is also a SubTexture which can be rotated or trimmed.

b005t3r avatar Apr 11 '14 11:04 b005t3r

Could you please verify if the problem happens with just rotation (no trimming/frame) as well? Because I think it should work with that — otherwise, it's a bug for sure.

Trimming the atlas textures (adding a frame to them) is a different story. A frame is actually (in Starling) just an information for the "Image" class (to move the vertices to different positions); it doesn't have any usage inside the texture classes. Which is admittedly not very intuitive (but the only valid solution I found for that trim logic).

So that's something that would need to be coded into the atlas class.

In any case, it would help immensely if you could share a small sample atlas that showcases the problem, so I could try it out.

Thanks in advance!

PrimaryFeather avatar Apr 15 '14 08:04 PrimaryFeather

I haven't tested the rotation variant, but it doesn't work with trimming alone as well.

Here you can find atlases I use, along with the raw assets used to create them and .tps files: https://dl.dropboxusercontent.com/u/23855128/TextureAtlasBug.zip

b005t3r avatar Apr 15 '14 08:04 b005t3r

Thanks for the link! I'll look into that.

In any case, I know that it won't work with trimming alone; the question was if it would work with just rotation. ;-)

For now, I recommend you simply create your sub-atlases not in POT-sizes, but let TexturePacker use the minimal possible size (that's an option inside Texture Packer). Then you don't need any trimming in your super-atlas-texture.

PrimaryFeather avatar Apr 15 '14 09:04 PrimaryFeather

Yes, I can disable trimming for the "super atlas" for now, but I plan to have quite a lot of "child atlases" in my game and trimming always let's you save couple of pixels per each atlas stored this way.

b005t3r avatar Apr 15 '14 09:04 b005t3r

Actually, if you create your child atlases in TexturePacker with "Geometry / Size Constraints: Any size", you shouldn't lose any pixels — or am I overlooking something? Because the atlases shouldn't have any empty space around them, then.

PrimaryFeather avatar Apr 15 '14 09:04 PrimaryFeather

:+1:

Hmm, you're probably right :)

b005t3r avatar Apr 15 '14 09:04 b005t3r

:smile: Still, I'll try to look into it — it would definitely be better if it worked with all those options.

PrimaryFeather avatar Apr 15 '14 09:04 PrimaryFeather

It should work, but it still doesn't. I set any size for the child atlases, created the super atlas and and when I create an image using texture named "blueprint_character_outline" its width and height are set to 26x26, where the original images is 24x24.

b005t3r avatar Apr 15 '14 09:04 b005t3r

Oh! :-( Could you send me the updated atlas? Ideally also with a little source code showing how you create your atlases, showing the texture creation that's off. Thanks in advance!

PrimaryFeather avatar Apr 15 '14 10:04 PrimaryFeather

Sure, but there's nothing special. I experimented with different setting and honestly couldn't make it work with any - something always renders not the way it should.

That's how I create atlases, nothing special:

        var assetManager:AssetManager = new AssetManager();
        assetManager.verbose = true;
        assetManager.enqueue("multi_texture_atlas.xml");
        assetManager.enqueue("multi_texture_atlas.png");

        assetManager.loadQueue(function(ratio:Number):void {
            if(ratio != 1) return;

            var multiTextureAtlas:TextureAtlas = assetManager.getTextureAtlas("multi_texture_atlas");

            assetManager.addTexture("blueprint_tiles", multiTextureAtlas.getTexture("blueprint_tiles"));
            assetManager.addTexture("characters", multiTextureAtlas.getTexture("characters"));
            assetManager.enqueue("blueprint_tiles.xml");
            assetManager.enqueue("characters.xml");

            assetManager.loadQueue(function(ratio:Number):void {
                if(ratio != 1) return;

                var characterTextureAtlas:TextureAtlas = assetManager.getTextureAtlas("characters");
            });
        });

Then I simply get the texture from one atlas, create an image out of it, add it to sprite and render the sprite - nothing fancy :) But notice that one one child atlas is created with extrude set to 1 (the one containing tiles). Maybe this somehow causes problems?

b005t3r avatar Apr 15 '14 11:04 b005t3r

Yes, that extrude setting could be it! If you play around in TexturePacker, you'll see that the image grows when you raise the extrude setting. So it will probably add a frame.

PrimaryFeather avatar Apr 15 '14 11:04 PrimaryFeather

OK, but, I need this to be set :)

b005t3r avatar Apr 15 '14 11:04 b005t3r

;-) OK, give me a little time, I'll see what I can do. Thanks for sending me the files!

PrimaryFeather avatar Apr 15 '14 11:04 PrimaryFeather

I managed to find the setting which render everything as it should be rendered :)

Here are the files if you need them: https://dl.dropboxusercontent.com/u/23855128/TextureAtlasWorking.zip

Everything is set to 0 except extrude in one of the atlases.

b005t3r avatar Apr 15 '14 11:04 b005t3r

Awesome, thanks!

PrimaryFeather avatar Apr 15 '14 11:04 PrimaryFeather

I spent several hours yesterday and today, trying to get this working. The result: my head is spinning, but it's still not solved ... :grimacing:

This stuff is really tricky ... right now, the "frame" property is not directly used by the texture class, only by Images. In a perfect world, textures would abstract away the frame completely, so that a texture with a frame acts exactly like a bigger texture with the original white-space. But how to get that right ... :scream:

PrimaryFeather avatar Apr 16 '14 10:04 PrimaryFeather

Good luck Daniel, I'm sure you'll figure it out!

kheftel-old avatar Apr 16 '14 18:04 kheftel-old

Yeah, at first I tried to fix it by myself, but failed pretty quickly :)

b005t3r avatar Apr 16 '14 19:04 b005t3r

Getting closer! I'm optimistic that I'll succeed to get this working ... after Easter. :wink:

PrimaryFeather avatar Apr 17 '14 13:04 PrimaryFeather

Hah, Happy Easter then! :)

b005t3r avatar Apr 17 '14 13:04 b005t3r

Thanks, the same to you!!! :smile:

PrimaryFeather avatar Apr 17 '14 19:04 PrimaryFeather

I picked this up again this week ... unfortunately, without success. Without rotations, everything would work fine; but with rotations enabled, it becomes really a pain in the :poop: to get done right. :dizzy_face:

So I'm sorry, but I have to stop working on this right now. Perhaps I'll visit it again in a few weeks, after the release of Starling 1.5; but I don't want to delay that any longer because of this issue.

For now, just make sure that your "outermost" atlas does not have any values for the "frame" attributes. As long as that is the case, everything should work, even if the atlas textures are rotated.

PrimaryFeather avatar Apr 24 '14 09:04 PrimaryFeather

All right, understood. Good luck with releasing v1.5.

b005t3r avatar Apr 24 '14 10:04 b005t3r

Thanks! Sorry, I really wanted to get this done for you. :anguished:

PrimaryFeather avatar Apr 24 '14 10:04 PrimaryFeather

No problem, Daniel, I can use it as it is for now.

b005t3r avatar Apr 24 '14 10:04 b005t3r