예제 #1
0
 public void Dispose()
 {
     Down?.Dispose();
     Down = null;
     Right?.Dispose();
     Right = null;
 }
예제 #2
0
 public void Clear()
 {
     prePacked.Clear();
     RootRegion.Dispose();
     RootRegion   = new PackerRegion(new Rectangle(0, 0, Width, Height));
     unammedIndex = 0;
 }
예제 #3
0
 public void Dispose()
 {
     RootRegion?.Dispose();
     RootRegion = null;
     prePacked.Clear();
     prePacked    = null;
     unammedIndex = 0;
     Width        = 0;
     Height       = 0;
 }
예제 #4
0
        private Point SplitRegion(PackerRegion region, int w, int h)
        {
            Debug.Assert(region != null, "Region is null, cannot split it!");
            Debug.Assert(!region.Used, "Region is already used!");

            region.Used  = true;
            region.Down  = new PackerRegion(new Rectangle(region.Bounds.X, region.Bounds.Y + h, region.Bounds.Width, region.Bounds.Height - h));
            region.Right = new PackerRegion(new Rectangle(region.Bounds.X + w, region.Bounds.Y, region.Bounds.Width - w, h));

            return(region.Bounds.Location);
        }
예제 #5
0
        private PackerRegion FindRegion(PackerRegion region, int w, int h)
        {
            if (region.Used)
            {
                var right = this.FindRegion(region.Right, w, h);
                if (right != null)
                {
                    return(right);
                }
                var down = this.FindRegion(region.Down, w, h);
                return(down);
            }

            if (w <= region.Bounds.Width && h <= region.Bounds.Height)
            {
                return(region);
            }

            return(null);
        }
예제 #6
0
        public FixedSizeSpritePacker(int width, int height, int padding)
        {
            if (width <= 1)
            {
                throw new SpriteException($"Invalid packer width: {width}");
            }
            if (height <= 1)
            {
                throw new SpriteException($"Invalid packer height: {width}");
            }
            if (padding < 0)
            {
                padding = 0;
            }

            Padding    = padding;
            Width      = width;
            Height     = height;
            RootRegion = new PackerRegion(new Rectangle(0, 0, width, height));

            texture = SpriteAtlas.CreateTexture(width, height);
        }
예제 #7
0
        public void Pack(bool allowUnpackedSprites)
        {
            if (!IsDirty)
            {
                Debug.Warn("Sprite atlas is not dirty, will not repack.");
                return;
            }
            IsDirty = false;

            packedSprites.Clear();
            if (prePacked.Count == 0)
            {
                return;
            }

            // Go!
            Debug.StartTimer("Pack tiles atlas");
            int packedCount = prePacked.Count;

            Debug.Log($"Packing the sprite atlas, {packedCount} sprites in a {Width}x{Height} texture.");
            Debug.Log($"Sprite sorting: {SortingMode} ({SortingDirection})");

            // Sort the pre-packed sprites by longest length, decreasing.
            prePacked.Sort();

            // Create the texture.
            Texture2D tex = new Texture2D(Main.GlobalGraphicsDevice, Width, Height, false, SurfaceFormat.Color);

            // Try to pack all of those sprites into the atlas.
            rootRegion = new PackerRegion(new Rectangle(0, 0, Width, Height));
            foreach (SpriteWrapper pp in prePacked)
            {
                bool canFit = this.TryFit(pp.Width + Padding * 2, pp.Height + Padding * 2, out Point packedPos);
                if (!canFit)
                {
                    Debug.Error($"Failed to pack {pp.Texture.Name} into the atlas!");
                    if (allowUnpackedSprites)
                    {
                        pp.Sprite.SetTexture(pp.Texture);
                        pp.Sprite.Region = new Rectangle(0, 0, pp.Texture.Width, pp.Texture.Height);
                        pp.Sprite.Name   = pp.Texture.Name;
                        Debug.Warn("The sprite will still function, but will have greatly decreased performance.");
                    }
                    else
                    {
                        pp.Sprite.SetTexture(null);
                        pp.Sprite.Name   = pp.Texture.Name;
                        pp.Sprite.Region = new Rectangle(0, 0, pp.Texture.Width, pp.Texture.Height);
                        Debug.Warn("The sprite will be invalid (will show missing texture)");
                    }
                    continue;
                }

                // Write to the texture.
                Blit(pp.Texture, tex, packedPos, Padding);

                // Set up the sprite to have the final data.
                pp.Sprite.SetTexture(tex);
                pp.Sprite.Name   = pp.Texture.Name;
                pp.Sprite.Region = new Rectangle(packedPos.X + Padding, packedPos.Y + padding, pp.Texture.Width, pp.Texture.Height);

                // Dispose of the old pre-packed texture...
                pp.Texture.Dispose();
                pp.Texture = null;

                // Add this packed sprite to the list of packed sprites.
                packedSprites.Add(pp.Sprite.Name, pp.Sprite);
            }

            // Clear the pre-packed list.
            prePacked.Clear();

            // Clear the color cache. Used in Blit().
            colorCaches.Clear();

            // Clear the region binary tree. It gets messy.
            rootRegion.Dispose();
            rootRegion = null;

            // Save this texture, and delete old texture.
            if (this.Texture != null)
            {
                this.Texture.Dispose();
            }
            this.Texture = tex;

            Debug.StopTimer(true);
        }