コード例 #1
0
ファイル: AtlasGenerator.cs プロジェクト: K4mey/Alex
        private Image <Rgba32>[] GetFrames(Image <Rgba32> source, int frameWidth, int frameHeight)
        {
            int framesInWidth  = source.Width / frameWidth;
            int framesInHeight = source.Height / frameHeight;

            if (framesInWidth * framesInHeight == 0)
            {
                //    string a = "b";
            }

            //List<Image<Rgba32>> result = new List<Image<Rgba32>>();
            Image <Rgba32>[] result = new Image <Rgba32> [framesInHeight * framesInWidth];
            int counter             = 0;

            for (int x = 0; x < framesInWidth; x++)
            {
                for (int y = 0; y < framesInHeight; y++)
                {
                    var newBitmap = new Image <Rgba32>(frameWidth, frameHeight);

                    TextureUtils.CopyRegionIntoImage(
                        source,
                        new System.Drawing.Rectangle(x * frameWidth, y * frameHeight, frameWidth, frameHeight),
                        ref newBitmap, new System.Drawing.Rectangle(0, 0, frameWidth, frameHeight));

                    result[counter++] = newBitmap;
                    //result.Add(newBitmap);
                }
            }

            return(result.ToArray());
        }
コード例 #2
0
ファイル: AtlasGenerator.cs プロジェクト: CiviledCode/Alex
        private int Process(ref Image <Rgba32> target, KeyValuePair <ResourceLocation, Image <Rgba32> >[] data, ref int xi, ref int yi, ref int xOffset, ref int yRemaining, int total, int processed, IDictionary <ResourceLocation, TextureInfo> locations, IProgressReceiver progressReceiver, bool animated)
        {
            int done  = processed;
            var count = 0;

            foreach (var bm in data.OrderByDescending(x => x.Value.Height))
            {
                var key = bm.Key;
                count++;

                // double percentage = 100D * ((double)processed / (double)total);
                progressReceiver.UpdateProgress(processed, total, null, key.ToString());

                var sourceRegion = new System.Drawing.Rectangle(0, 0, bm.Value.Width, bm.Value.Height);
                var targetRegion = new System.Drawing.Rectangle(xi, yi, bm.Value.Width, bm.Value.Height);

                TextureUtils.CopyRegionIntoImage(bm.Value, sourceRegion, ref target, targetRegion);

                if (!locations.ContainsKey(key))
                {
                    locations.Add(key, new TextureInfo(new Vector2(target.Width, target.Height), new Vector2(xi, yi), bm.Value.Width / 16, bm.Value.Height / 16, animated, true));
                }

                if (bm.Value.Height > TextureHeight)
                {
                    xOffset    = xi;
                    yRemaining = bm.Value.Height;
                }
                xi += bm.Value.Width;

                if (count == target.Width / TextureWidth)
                {
                    yi         += TextureHeight;
                    xi          = 0;
                    yRemaining -= TextureHeight;

                    count = 0;
                }

                done++;
            }

            return(done);
        }
コード例 #3
0
        private int Process(ref Bitmap bmp, KeyValuePair <string, Bitmap>[] data, ref int xi, ref int yi, ref int xOffset, ref int yRemaining, int total, int processed, IDictionary <string, TextureInfo> locations, IProgressReceiver progressReceiver)
        {
            int done  = processed;
            var count = 0;

            foreach (var bm in data.OrderByDescending(x => x.Value.Height))
            {
                string key = bm.Key;
                count++;

                double percentage = 100D * ((double)processed / (double)total);
                progressReceiver.UpdateProgress((int)percentage, "Stitching textures...", key);

                var sourceRegion = new System.Drawing.Rectangle(0, 0, bm.Value.Width, bm.Value.Height);
                var targetRegion = new System.Drawing.Rectangle(xi, yi, bm.Value.Width, bm.Value.Height);

                TextureUtils.CopyRegionIntoImage(bm.Value, sourceRegion, ref bmp, targetRegion);

                if (!locations.ContainsKey(key))
                {
                    locations.Add(key, new TextureInfo(new Vector2(xi, yi), bm.Value.Width, bm.Value.Height));
                }

                if (bm.Value.Height > TextureHeight)
                {
                    xOffset    = xi;
                    yRemaining = bm.Value.Height;
                }
                xi += bm.Value.Width;

                if (count == AtlasWidth / TextureWidth)
                {
                    yi         += TextureHeight;
                    xi          = 0;
                    yRemaining -= TextureHeight;

                    count = 0;
                }

                done++;
            }

            return(done);
        }
コード例 #4
0
ファイル: AtlasGenerator.cs プロジェクト: LegacyGamerHD/Alex
        private Image <Rgba32>[] GetFrames(Image <Rgba32> source)
        {
            int ix = source.Width / TextureWidth;
            int iy = source.Height / TextureHeight;

            List <Image <Rgba32> > result = new List <Image <Rgba32> >();

            for (int x = 0; x < ix; x++)
            {
                for (int y = 0; y < iy; y++)
                {
                    var newBitmap = new Image <Rgba32>(TextureWidth, TextureHeight);
                    TextureUtils.CopyRegionIntoImage(source, new System.Drawing.Rectangle(x * TextureWidth, y * TextureHeight, TextureWidth, TextureHeight), ref newBitmap, new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight));

                    result.Add(newBitmap);
                }
            }

            return(result.ToArray());
        }
コード例 #5
0
        private Bitmap[] GetFrames(Bitmap source)
        {
            int ix = source.Width / TextureWidth;
            int iy = source.Height / TextureHeight;

            List <Bitmap> result = new List <Bitmap>();

            for (int x = 0; x < ix; x++)
            {
                for (int y = 0; y < iy; y++)
                {
                    Bitmap newBitmap = new Bitmap(TextureWidth, TextureHeight);
                    TextureUtils.CopyRegionIntoImage(source, new System.Drawing.Rectangle(x, y, TextureWidth, TextureHeight), ref newBitmap, new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight));

                    result.Add(newBitmap);
                }
            }

            return(result.ToArray());
        }
コード例 #6
0
ファイル: AtlasGenerator.cs プロジェクト: CiviledCode/Alex
        private PooledTexture2D[] ProcessFrames(GraphicsDevice device, IProgressReceiver progressReceiver,
                                                IDictionary <ResourceLocation, ImageEntry> blockTextures)
        {
            Dictionary <ResourceLocation, Image <Rgba32>[]> blockFrames =
                new Dictionary <ResourceLocation, Image <Rgba32>[]>();

            foreach (var other in blockTextures.Where(
                         x => x.Value.Image.Height != x.Value.Image.Width))
            {
                if (!blockFrames.TryGetValue(other.Key, out _))
                {
                    blockFrames.Add(other.Key, GetFrames(other.Value, TextureWidth, TextureHeight));
                }
            }

            var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(
                blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(),
                progressReceiver, animatedFrameInfo, true, out var animatedFrame);

            AnimatedAtlasSize       = new Vector2(animatedFrame.Width, animatedFrame.Height);
            _animatedAtlasLocations = animatedFrameInfo;


            var frameCount = blockFrames.Max(x => x.Value.Length);

            while (frameCount % 2 != 0)
            {
                frameCount++;
            }

            var frames = new Image <Rgba32> [frameCount];

            frames[0] = animatedFrame;

            for (int i = 1; i < frames.Length; i++)
            {
                //  double percentage = 100D * ((double) i / (double) frames.Length);
                progressReceiver.UpdateProgress(i, frames.Length, $"Animating frame {i + 1} / {frames.Length}...");

                var target = (i > 0 ? frames[i - 1] : animatedFrame).CloneAs <Rgba32>();            //new Bitmap(animatedFrame);

                // System.Drawing.Rectangle destination;

                foreach (var animated in blockFrames)
                {
                    progressReceiver.UpdateProgress(i, frames.Length, null, animated.Key.ToString());

                    if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo))
                    {
                        //((i % 3 == 0 ? i - 1 : i) / 6)

                        var destination = new System.Drawing.Rectangle(
                            (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width * 16,
                            textureInfo.Height * 16);

                        var sourceRegion = new System.Drawing.Rectangle(0, 0, textureInfo.Width * 16, textureInfo.Height * 16);

                        var index = i % animated.Value.Length;

                        var   indexOffset        = 0;
                        bool  shouldInterpolate  = false;
                        float interpolationValue = 0.5f;

                        if (blockTextures.TryGetValue(animated.Key, out var imageEntry) && imageEntry.Meta != null)
                        {
                            var meta = imageEntry.Meta;

                            if (meta.Animation != null)
                            {
                                if (meta.Animation.Interpolate)
                                {
                                    int extraFrames = (frames.Length - animated.Value.Length);

                                    var interpolationFrames = (int)Math.Floor(
                                        ((double)extraFrames / (double)animated.Value.Length));

                                    var remainder = i % interpolationFrames;

                                    if (remainder != 0)
                                    {
                                        shouldInterpolate  = true;
                                        interpolationValue = (1f / interpolationFrames) * remainder;

                                        indexOffset = -remainder;
                                        //   index -= remainder;
                                    }
                                }

                                if (meta.Animation.Frames != null)
                                {
                                    var entry = meta.Animation.Frames[(i + indexOffset) % meta.Animation.Frames.Length];

                                    if (entry.Integer.HasValue)
                                    {
                                        index = (int)entry.Integer.Value;
                                    }
                                    else if (entry.FrameClass != null)
                                    {
                                        index = (int)entry.FrameClass.Index;
                                    }
                                }
                                else
                                {
                                    index = (i + indexOffset) % animated.Value.Length;
                                }
                            }
                        }

                        //TextureUtils.ClearRegion(ref target, destination);

                        if (shouldInterpolate)
                        {
                            TextureUtils.CopyRegionIntoImage(
                                ((i + indexOffset >= 0) ? frames[(i + indexOffset) % frames.Length] : animatedFrame),
                                destination, ref target, destination, clear: true);
                        }

                        var texture = animated.Value[index];

                        TextureUtils.CopyRegionIntoImage(
                            texture, sourceRegion, ref target, destination, shouldInterpolate, interpolationValue,
                            clear: !shouldInterpolate);
                    }
                }

                frames[i] = target;
            }

            return(frames.Select(
                       (x, index) =>
            {
                var a = GetMipMappedTexture2D(device, x);
                //totalSize += a.MemoryUsage;

                return a;
            }).ToArray());
        }
コード例 #7
0
ファイル: AtlasGenerator.cs プロジェクト: LegacyGamerHD/Alex
        public void GenerateAtlas(GraphicsDevice device, KeyValuePair <string, Image <Rgba32> >[] bitmaps, IReadOnlyDictionary <string, TextureMeta> meta, IProgressReceiver progressReceiver)
        {
            Stopwatch sw = Stopwatch.StartNew();

            Log.Info($"Generating texture atlas out of {bitmaps.Length} bitmaps...");

            long totalSize = 0;

            Image <Rgba32> no;

            using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png")))
            {
                no = Image.Load <Rgba32>(ms);
            }

            //  Dictionary<string, Bitmap[]> animatedFrames = new Dictionary<string, Bitmap[]>();
            foreach (var bmp in bitmaps)
            {
                if (meta.TryGetValue(bmp.Key, out var textureMeta))
                {
                    if (textureMeta.Animation == null || textureMeta.Animation == default)
                    {
                        continue;
                    }

                    // Bitmap[] bmpFrames = GetFrames(bmp.Value);
                    //   animatedFrames.Add(bmp.Key, bmpFrames);
                }
            }

            var regular = new[]
            {
                new KeyValuePair <string, Image <Rgba32> >("no_texture", no),
            }.Concat(bitmaps.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray();

            var others = bitmaps.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToList();

            Image <Rgba32>[] waterFrames     = new Image <Rgba32> [0];
            Image <Rgba32>[] lavaFrames      = new Image <Rgba32> [0];
            Image <Rgba32>[] waterFlowFrames = new Image <Rgba32> [0];
            Image <Rgba32>[] lavaFlowFrames  = new Image <Rgba32> [0];
            Image <Rgba32>[] fireFrames      = new Image <Rgba32> [0];
            Image <Rgba32>[] fireFrames2     = new Image <Rgba32> [0];
            Image <Rgba32>[] portalFrames    = new Image <Rgba32> [0];
            Image <Rgba32>[] seagrassFrames  = new Image <Rgba32> [0];

            foreach (var other in others.ToArray())
            {
                if (other.Key.Contains("water") && other.Key.Contains("still"))
                {
                    waterFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("water") && other.Key.Contains("flow"))
                {
                    waterFlowFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("lava") && other.Key.Contains("still"))
                {
                    lavaFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("lava") && other.Key.Contains("flow"))
                {
                    lavaFlowFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("fire_0"))
                {
                    fireFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("fire_1"))
                {
                    fireFrames2 = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("nether_portal"))
                {
                    portalFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("seagrass"))
                {
                    seagrassFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                //seagrass
            }

            Dictionary <string, TextureInfo> stillFrameInfo = new Dictionary <string, TextureInfo>();

            GenerateAtlasInternal(regular, others.ToArray(), progressReceiver, stillFrameInfo, out var stillAtlas);
            _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size);

            //stillAtlas.Save(Path.Combine(DebugPath, "atlas.png"));

            totalSize += size;

            _atlasLocations = stillFrameInfo;

            Dictionary <string, Image <Rgba32> > animated = new Dictionary <string, Image <Rgba32> >();

            if (waterFrames.Length > 0)
            {
                animated.Add("block/water_still", waterFrames[0]);
            }


            if (waterFlowFrames.Length > 0)
            {
                animated.Add("block/water_flow", waterFlowFrames[0]);
            }


            if (lavaFrames.Length > 0)
            {
                animated.Add("block/lava_still", lavaFrames[0]);
            }


            if (lavaFlowFrames.Length > 0)
            {
                animated.Add("block/lava_flow", lavaFlowFrames[0]);
            }

            if (fireFrames.Length > 0)
            {
                animated.Add("block/fire_0", fireFrames[0]);
            }

            if (fireFrames2.Length > 0)
            {
                animated.Add("block/fire_1", fireFrames2[0]);
            }

            if (portalFrames.Length > 0)
            {
                animated.Add("block/nether_portal", portalFrames[0]);
            }

            if (seagrassFrames.Length > 0)
            {
                animated.Add("block/seagrass", seagrassFrames[0]);
            }

            var animatedFrameInfo = new Dictionary <string, TextureInfo>();

            GenerateAtlasInternal(animated.ToArray(), new KeyValuePair <string, Image <Rgba32> > [0], progressReceiver,
                                  animatedFrameInfo, out Image <Rgba32> animatedFrame);

            AnimatedAtlasSize = new Vector2(animatedFrame.Width, animatedFrame.Height);

            TextureInfo waterLocation, waterFlowLocation, lavaLocation, lavaFlowLocation, fireLocation, fireLocation2, portalLocation, seagrassLocation;

            animatedFrameInfo.TryGetValue("block/water_still", out waterLocation);
            animatedFrameInfo.TryGetValue("block/water_flow", out waterFlowLocation);
            animatedFrameInfo.TryGetValue("block/lava_still", out lavaLocation);
            animatedFrameInfo.TryGetValue("block/lava_flow", out lavaFlowLocation);
            animatedFrameInfo.TryGetValue("block/fire_0", out fireLocation);
            animatedFrameInfo.TryGetValue("block/fire_1", out fireLocation2);
            animatedFrameInfo.TryGetValue("block/nether_portal", out portalLocation);
            animatedFrameInfo.TryGetValue("block/seagrass", out seagrassLocation);

            //var waterLocation = new Vector3();

            // var baseBitmap = new Bitmap(stillAtlas.Width, stillAtlas.Height);
            var frameCount = Math.Max(Math.Max(Math.Max(waterFrames.Length,
                                                        Math.Max(waterFlowFrames.Length,
                                                                 Math.Max(lavaFrames.Length, Math.Max(lavaFlowFrames.Length, fireFrames.Length)))), portalFrames.Length), seagrassFrames.Length);

            while (frameCount % 2 != 0)
            {
                frameCount++;
            }

            var frames = new Texture2D[frameCount];

            for (int i = 0; i < frames.Length; i++)
            {
                var target      = animatedFrame.CloneAs <Rgba32>();       //new Bitmap(animatedFrame);
                var r           = new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight);
                var destination = new System.Drawing.Rectangle((int)waterLocation.Position.X, (int)waterLocation.Position.Y, TextureWidth, TextureHeight);

                if (waterFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(waterFrames[((i % 3 == 0 ? i - 1 : i) / 6) % waterFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)waterFlowLocation.Position.X, (int)waterFlowLocation.Position.Y, TextureWidth, TextureHeight);
                if (waterFlowFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(waterFlowFrames[i % waterFlowFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)lavaLocation.Position.X, (int)lavaLocation.Position.Y, TextureWidth, TextureHeight);
                if (lavaFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(lavaFrames[i % lavaFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)lavaFlowLocation.Position.X, (int)lavaFlowLocation.Position.Y, TextureWidth, TextureHeight);
                if (lavaFlowFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(lavaFlowFrames[i % lavaFlowFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)fireLocation.Position.X, (int)fireLocation.Position.Y, TextureWidth, TextureHeight);
                if (fireFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(fireFrames[i % fireFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)fireLocation2.Position.X, (int)fireLocation2.Position.Y, TextureWidth, TextureHeight);
                if (fireFrames2.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(fireFrames2[i % fireFrames2.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)portalLocation.Position.X, (int)portalLocation.Position.Y, TextureWidth, TextureHeight);
                if (portalFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(portalFrames[i % portalFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)seagrassLocation.Position.X, (int)seagrassLocation.Position.Y, TextureWidth, TextureHeight);
                if (seagrassFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(seagrassFrames[i % seagrassFrames.Length], r, ref target, destination);
                }

                frames[i]  = TextureUtils.BitmapToTexture2D(device, target, out var s);
                totalSize += s;

                //   target.Save(Path.Combine(DebugFramePath, $"frame{i}.png"));
            }

            _animatedAtlasLocations = animatedFrameInfo;

            AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height);
            _frames   = frames;

            sw.Stop();

            Log.Info($"TextureAtlas generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})");
        }
コード例 #8
0
        private void GenerateAtlas(GraphicsDevice device,
                                   IDictionary <ResourceLocation, ImageEntry> blockTextures,
                                   IProgressReceiver progressReceiver)
        {
            Stopwatch sw = Stopwatch.StartNew();

            Log.Info($"Generating texture atlas out of {(blockTextures.Count)} bitmaps...");

            long totalSize = 0;

            Image <Rgba32> no;

            using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png")))
            {
                no = Image.Load <Rgba32>(ms);
            }

            Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(
                new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat(
                    blockTextures
                    .Where(x => x.Value.Image.Height == TextureHeight && x.Value.Image.Width == TextureWidth).Select(
                        x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value.Image))).ToArray(),
                progressReceiver, stillFrameInfo, false, out var stillAtlas);

            AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height);

            //  totalSize += size;

            _atlasLocations = stillFrameInfo;


            Dictionary <ResourceLocation, Image <Rgba32>[]> blockFrames =
                new Dictionary <ResourceLocation, Image <Rgba32>[]>();

            foreach (var other in blockTextures.Where(
                         x => x.Value.Image.Height != x.Value.Image.Width))
            {
                if (!blockFrames.TryGetValue(other.Key, out _))
                {
                    blockFrames.Add(other.Key, GetFrames(other.Value.Image, TextureWidth, TextureHeight));
                }
            }

            var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(
                blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(),
                progressReceiver, animatedFrameInfo, true, out Image <Rgba32> animatedFrame);

            AnimatedAtlasSize       = new Vector2(animatedFrame.Width, animatedFrame.Height);
            _animatedAtlasLocations = animatedFrameInfo;


            var frameCount = blockFrames.Max(x => x.Value.Length);

            while (frameCount % 2 != 0)
            {
                frameCount++;
            }

            var frames = new Image <Rgba32> [frameCount];

            frames[0] = animatedFrame;

            for (int i = 1; i < frames.Length; i++)
            {
                double percentage = 100D * ((double)i / (double)frames.Length);
                progressReceiver.UpdateProgress((int)percentage, $"Animating frame {i + 1} / {frames.Length}...");

                var target = (i > 0 ? frames[i - 1] : animatedFrame).CloneAs <Rgba32>();            //new Bitmap(animatedFrame);

                // System.Drawing.Rectangle destination;

                foreach (var animated in blockFrames)
                {
                    progressReceiver.UpdateProgress((int)percentage, null, animated.Key.ToString());

                    if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo))
                    {
                        //((i % 3 == 0 ? i - 1 : i) / 6)

                        var destination = new System.Drawing.Rectangle(
                            (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width,
                            textureInfo.Height);

                        var sourceRegion = new System.Drawing.Rectangle(0, 0, textureInfo.Width, textureInfo.Height);

                        var index = i % animated.Value.Length;

                        var   indexOffset        = 0;
                        bool  shouldInterpolate  = false;
                        float interpolationValue = 0.5f;
                        if (blockTextures.TryGetValue(animated.Key, out var imageEntry) && imageEntry.Meta != null)
                        {
                            var meta = imageEntry.Meta;

                            if (meta.Animation != null)
                            {
                                if (meta.Animation.Interpolate)
                                {
                                    int extraFrames = (frames.Length - animated.Value.Length);

                                    var interpolationFrames = (int)Math.Floor(((double)extraFrames / (double)animated.Value.Length));

                                    var remainder = i % interpolationFrames;

                                    if (remainder != 0)
                                    {
                                        shouldInterpolate  = true;
                                        interpolationValue = (1f / interpolationFrames) * remainder;

                                        indexOffset = -remainder;
                                        //   index -= remainder;
                                    }
                                }

                                if (meta.Animation.Frames != null)
                                {
                                    var entry = meta.Animation.Frames[(i + indexOffset) % meta.Animation.Frames.Length];

                                    if (entry.Integer.HasValue)
                                    {
                                        index = (int)entry.Integer.Value;
                                    }
                                    else if (entry.FrameClass != null)
                                    {
                                        index = (int)entry.FrameClass.Index;
                                    }
                                }
                                else
                                {
                                    index = (i + indexOffset) % animated.Value.Length;
                                }
                            }
                        }

                        //TextureUtils.ClearRegion(ref target, destination);

                        if (shouldInterpolate)
                        {
                            TextureUtils.CopyRegionIntoImage(
                                ((i + indexOffset >= 0) ? frames[(i + indexOffset) % frames.Length] : animatedFrame), destination, ref target,
                                destination, clear: true);
                        }

                        var texture = animated.Value[index];

                        TextureUtils.CopyRegionIntoImage(texture,
                                                         sourceRegion, ref target,
                                                         destination, shouldInterpolate, interpolationValue, clear: !shouldInterpolate);
                    }
                }

                frames[i] = target;
            }

            _frames = frames.Select(
                x =>
            {
                var a      = TextureUtils.BitmapToTexture2D(device, x, out var s);
                totalSize += s;

                return(a);
            }).ToArray();

            _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size);
            totalSize  += size;

            sw.Stop();

            Log.Info(
                $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})");

            /*
             * PngEncoder encoder = new PngEncoder();
             *
             * stillAtlas.Save("atlas.png", encoder);
             *
             * if (!Directory.Exists("frames"))
             *      Directory.CreateDirectory("frames");
             *
             * for (var index = 0; index < frames.Length; index++)
             * {
             *      var frame = frames[index];
             *
             *      frame.Save(Path.Combine("frames", $"frame-{index}.png"), encoder);
             * }*/
        }
コード例 #9
0
        private void GenerateAtlas(GraphicsDevice device, IDictionary <ResourceLocation, Image <Rgba32>[]> blockFrames, IDictionary <ResourceLocation, Image <Rgba32> > blockTextures, IProgressReceiver progressReceiver)
        {
            Stopwatch sw = Stopwatch.StartNew();

            Log.Info($"Generating texture atlas out of {(blockFrames.Count + blockTextures.Count)} bitmaps...");

            long totalSize = 0;

            Image <Rgba32> no;

            using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png")))
            {
                no = Image.Load <Rgba32>(ms);
            }

            var regularTextures = new[]
            {
                new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no),
            }.Concat(blockTextures.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray();

            var oddSizedTextures = blockTextures.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToArray();

            for (var index = 0; index < oddSizedTextures.Length; index++)
            {
                var other = oddSizedTextures[index];

                if (blockFrames.TryGetValue(other.Key, out var values))
                {
                    oddSizedTextures[index] = new KeyValuePair <ResourceLocation, Image <Rgba32> >(other.Key, values[0]);
                }
            }

            Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(regularTextures, oddSizedTextures, progressReceiver, stillFrameInfo, false, out var stillAtlas);
            _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size);
            AtlasSize   = new Vector2(stillAtlas.Width, stillAtlas.Height);

            totalSize += size;

            _atlasLocations = stillFrameInfo;

            var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(), new KeyValuePair <ResourceLocation, Image <Rgba32> > [0], progressReceiver,
                                  animatedFrameInfo, true, out Image <Rgba32> animatedFrame);

            AnimatedAtlasSize       = new Vector2(animatedFrame.Width, animatedFrame.Height);
            _animatedAtlasLocations = animatedFrameInfo;


            var frameCount = blockFrames.Max(x => x.Value.Length);

            while (frameCount % 2 != 0)
            {
                frameCount++;
            }

            var frames = new Texture2D[frameCount];

            for (int i = 0; i < frames.Length; i++)
            {
                double percentage = 100D * ((double)i / (double)frames.Length);
                progressReceiver.UpdateProgress((int)percentage, $"Animating frame {i}...");

                var target = animatedFrame.CloneAs <Rgba32>();            //new Bitmap(animatedFrame);

                // System.Drawing.Rectangle destination;

                foreach (var animated in blockFrames)
                {
                    progressReceiver.UpdateProgress((int)percentage, null, animated.Key.ToString());

                    if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo))
                    {
                        //((i % 3 == 0 ? i - 1 : i) / 6)

                        var destination = new System.Drawing.Rectangle(
                            (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width, textureInfo.Height);

                        TextureUtils.CopyRegionIntoImage(
                            animated.Value[i % animated.Value.Length], new System.Drawing.Rectangle(0, 0, textureInfo.Width, textureInfo.Height), ref target,
                            destination);
                    }
                }

                frames[i]  = TextureUtils.BitmapToTexture2D(device, target, out var s);
                totalSize += s;
            }

            _frames = frames;

            sw.Stop();

            Log.Info($"TextureAtlas generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})");
        }
コード例 #10
0
        public void GenerateAtlas(KeyValuePair <string, Bitmap>[] bitmaps, IProgressReceiver progressReceiver)
        {
            Log.Info($"Generating texture atlas out of {bitmaps.Length} bitmaps...");

            long totalSize = 0;

            Bitmap no;

            using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png")))
            {
                no = new Bitmap(ms);
            }

            var regular = new[]
            {
                new KeyValuePair <string, Bitmap>("no_texture", no),
            }.Concat(bitmaps.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray();

            var others = bitmaps.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToList();

            Bitmap[] waterFrames     = new Bitmap[0];
            Bitmap[] lavaFrames      = new Bitmap[0];
            Bitmap[] waterFlowFrames = new Bitmap[0];
            Bitmap[] lavaFlowFrames  = new Bitmap[0];

            foreach (var other in others.ToArray())
            {
                if (other.Key.Contains("water") && other.Key.Contains("still"))
                {
                    waterFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("water") && other.Key.Contains("flow"))
                {
                    waterFlowFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("lava") && other.Key.Contains("still"))
                {
                    lavaFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
                else if (other.Key.Contains("lava") && other.Key.Contains("flow"))
                {
                    lavaFlowFrames = GetFrames(other.Value);
                    others.Remove(other);
                }
            }

            Dictionary <string, TextureInfo> stillFrameInfo = new Dictionary <string, TextureInfo>();

            GenerateAtlasInternal(regular, others.ToArray(), progressReceiver, stillFrameInfo, out Bitmap stillAtlas);
            _stillFrame = TextureUtils.BitmapToTexture2D(Graphics, stillAtlas, out var size);
            totalSize  += size;

            _atlasLocations = stillFrameInfo;

            Dictionary <string, Bitmap> animated = new Dictionary <string, Bitmap>();

            if (waterFrames.Length > 0)
            {
                //  total++;
                animated.Add("block/water_still", waterFrames[0]);
                //  regular = regular.Append(new KeyValuePair<string, Bitmap>("block/water_still", waterFrames[0])).ToArray();
            }

            if (waterFlowFrames.Length > 0)
            {
                //  total++;
                animated.Add("block/water_flow", waterFlowFrames[0]);
                //  regular = regular.Append(new KeyValuePair<string, Bitmap>("block/water_flow", waterFlowFrames[0])).ToArray();
            }

            if (lavaFrames.Length > 0)
            {
                animated.Add("block/lava_still", lavaFrames[0]);
                //  total++;
                //  regular = regular.Append(new KeyValuePair<string, Bitmap>("block/lava_still", lavaFrames[0])).ToArray();
            }

            if (lavaFlowFrames.Length > 0)
            {
                animated.Add("block/lava_flow", lavaFlowFrames[0]);
                // total++;
                // regular = regular.Append(new KeyValuePair<string, Bitmap>("block/lava_flow", lavaFlowFrames[0])).ToArray();
            }

            var animatedFrameInfo = new Dictionary <string, TextureInfo>();

            GenerateAtlasInternal(animated.ToArray(), new KeyValuePair <string, Bitmap> [0], progressReceiver,
                                  animatedFrameInfo, out Bitmap animatedFrame);

            TextureInfo waterLocation, waterFlowLocation, lavaLocation, lavaFlowLocation;

            animatedFrameInfo.TryGetValue("block/water_still", out waterLocation);
            animatedFrameInfo.TryGetValue("block/water_flow", out waterFlowLocation);
            animatedFrameInfo.TryGetValue("block/lava_still", out lavaLocation);
            animatedFrameInfo.TryGetValue("block/lava_flow", out lavaFlowLocation);

            //var waterLocation = new Vector3();

            // var baseBitmap = new Bitmap(stillAtlas.Width, stillAtlas.Height);
            var frames = new Texture2D[Math.Max(waterFrames.Length, waterFlowFrames.Length)];

            for (int i = 0; i < frames.Length; i++)
            {
                var target      = new Bitmap(animatedFrame);
                var r           = new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight);
                var destination = new System.Drawing.Rectangle((int)waterLocation.Position.X, (int)waterLocation.Position.Y, TextureWidth, TextureHeight);

                if (waterFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(waterFrames[((i % 3 == 0 ? i - 1 : i) / 6) % waterFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)waterFlowLocation.Position.X, (int)waterFlowLocation.Position.Y, TextureWidth, TextureHeight);
                if (waterFlowFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(waterFlowFrames[i % waterFlowFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)lavaLocation.Position.X, (int)lavaLocation.Position.Y, TextureWidth, TextureHeight);
                if (lavaFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(lavaFrames[i % lavaFrames.Length], r, ref target, destination);
                }

                destination = new System.Drawing.Rectangle((int)lavaFlowLocation.Position.X, (int)lavaFlowLocation.Position.Y, TextureWidth, TextureHeight);
                if (lavaFlowFrames.Length > 0)
                {
                    TextureUtils.CopyRegionIntoImage(lavaFlowFrames[i % lavaFlowFrames.Length], r, ref target, destination);
                }

                frames[i]  = TextureUtils.BitmapToTexture2D(Graphics, target, out var s);
                totalSize += s;
            }

            _animatedAtlasLocations = animatedFrameInfo;

            AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height);
            _frames   = frames;

            Log.Info($"TextureAtlas generated! ({PlayingState.GetBytesReadable(totalSize, 2)})");
        }