示例#1
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;

            var stillFrame = GetMipMappedTexture2D(device, stillAtlas);

            totalSize  += stillFrame.MemoryUsage;
            _stillFrame = stillFrame;

            _frames = ProcessFrames(device,
                                    progressReceiver, blockTextures);

            totalSize += _frames.Sum(x => x.MemoryUsage);

            sw.Stop();

            Log.Info(
                $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})");
        }
示例#2
0
        public ModelDebugState()
        {
            _debugInfo = new GuiDebugInfo();

            Background = Color.DeepSkyBlue;

            BlockModelExplorer  = new BlockModelExplorer(Alex.Instance, null);
            EntityModelExplorer = new EntityModelExplorer(Alex.Instance, null);

            ModelExplorer = BlockModelExplorer;

            //AddChild(_wrap = new GuiStackContainer()
            //{
            //	Orientation = Orientation.Horizontal,
            //	Anchor = Alignment.Fill,
            //	ChildAnchor = Alignment.FillY
            //});

            AddChild(_modelExplorerView = new GuiModelExplorerView(ModelExplorer, new Vector3(0f, 1.85f, 6f), new Vector3(0.5f, 0.5f, 0.5f))
            {
                Anchor            = Alignment.Fill,
                Background        = Color.TransparentBlack,
                BackgroundOverlay = new Color(Color.Black, 0.15f),

                Margin = new Thickness(0),

                Width  = 92,
                Height = 128,

                AutoSizeMode = AutoSizeMode.None,

                //Anchor = Alignment.BottomRight,

                // Width = 100,
                // Height = 100
            });

            AddChild(_mainMenu = new GuiStackMenu()
            {
                Margin  = new Thickness(0, 0, 15, 0),
                Padding = new Thickness(0, 50, 0, 0),
                Width   = 125,
                Anchor  = Alignment.FillY | Alignment.MinX,

                ChildAnchor       = Alignment.CenterY | Alignment.FillX,
                BackgroundOverlay = new Color(Color.Black, 0.35f)
            });

            //_wrap.AddChild(_modelRenderer = new DebugModelRenderer(Alex)
            //{
            //	Anchor = Alignment.Fill,
            //	// Width = 100,
            //	// Height = 100
            //});



            _mainMenu.AddMenuItem("Skip", () => { Task.Run(() => { ModelExplorer.Skip(); }); });
            _mainMenu.AddMenuItem("Next", NextModel);
            _mainMenu.AddMenuItem("Previous", PrevModel);
            _mainMenu.AddMenuItem("Switch Models", () =>
            {
                SwitchModelExplorers();
                _modelExplorerView.ModelExplorer = ModelExplorer;
            });

            //AddChild(_mainMenu);

            _debugInfo.AddDebugRight(() => Alex.DotnetRuntime);
            //_debugInfo.AddDebugRight(() => MemoryUsageDisplay);
            _debugInfo.AddDebugRight(() => $"RAM: {PlayingState.GetBytesReadable(_ramUsage, 2)}");
            _debugInfo.AddDebugRight(() =>
                                     $"GPU: {PlayingState.GetBytesReadable(GpuResourceManager.GetMemoryUsage, 2)}");
            _debugInfo.AddDebugRight(() =>
            {
                return
                ($"Threads: {(_threadsUsed):00}/{_maxThreads}\nCompl.ports: {_complPortUsed:00}/{_maxComplPorts}");
            });

            _debugInfo.AddDebugRight(() =>
            {
                if (ModelExplorer == null)
                {
                    return(string.Empty);
                }

                return(ModelExplorer.GetDebugInfo());
            });

            _keyState = Keyboard.GetState();
        }
示例#3
0
        public bool CheckUpdate(IProgressReceiver progressReceiver, out string path)
        {
            path = String.Empty;
            progressReceiver?.UpdateProgress(0, "Checking for resource updates...");

            using var httpClient = new HttpClient(new HttpClientHandler
            {
                AllowAutoRedirect = true,
            });

            try
            {
                //  string assetsZipSavePath = String.Empty;

                string currentVersion;
                if (TryGetStoredAssetVersion(out currentVersion))
                {
                    path = Path.Combine("assets", $"bedrock-{currentVersion}.zip");

                    if (!Storage.Exists(path))
                    {
                        currentVersion = null;
                    }
                }

                try
                {
                    var zipDownloadHeaders = httpClient.Send(
                        new HttpRequestMessage(HttpMethod.Get, DownloadURL), HttpCompletionOption.ResponseHeadersRead);

                    var fileName = zipDownloadHeaders.Content?.Headers?.ContentDisposition?.FileName
                                   ?? zipDownloadHeaders.RequestMessage?.RequestUri?.LocalPath;

                    var versionMatch = ExtractVersionFromFilename.Match(fileName);

                    if (versionMatch.Success)
                    {
                        var latestVersion = versionMatch.Groups["version"].Value;

                        if (latestVersion != currentVersion ||
                            (!string.IsNullOrWhiteSpace(path) && !Storage.Exists(path)))
                        {
                            if (Storage.Exists(path))
                            {
                                Storage.Delete(path);
                            }

                            progressReceiver?.UpdateProgress(
                                0, "Downloading latest bedrock assets...", "This could take a while...");

                            /* zipDownloadHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get,
                             *   zipDownloadHeaders.Headers.Location), HttpCompletionOption.ResponseContentRead);
                             * var content = await zipDownloadHeaders.Content.ReadAsByteArrayAsync();*/
                            Stopwatch sw = new Stopwatch();
                            WebClient wc = new WebClient();

                            wc.DownloadProgressChanged += (sender, args) =>
                            {
                                var downloadSpeed =
                                    $"Download speed: {PlayingState.GetBytesReadable((long) (Convert.ToDouble(args.BytesReceived) / sw.Elapsed.TotalSeconds), 2)}/s";

                                progressReceiver?.UpdateProgress(
                                    args.ProgressPercentage, $"Downloading latest bedrock assets...", downloadSpeed);
                            };

                            bool   complete    = false;
                            string archivePath = string.Empty;
                            wc.DownloadDataCompleted += (sender, args) =>
                            {
                                var content = args.Result;

                                archivePath = Path.Combine("assets", $"bedrock-{latestVersion}.zip");

                                // save locally

                                Storage.TryWriteString(CurrentBedrockVersionStorageKey, latestVersion);

                                Storage.TryWriteBytes(archivePath, content);

                                complete = true;
                            };

                            wc.DownloadDataAsync(zipDownloadHeaders.RequestMessage.RequestUri);
                            sw.Restart();

                            SpinWait.SpinUntil(() => complete);

                            path = archivePath;

                            return(true);
                        }
                    }

                    return(false);
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Failed to download bedrock assets...");

                    return(false);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Failed to fetch latest bedrock assets pack.");
                throw;
            }
        }
示例#4
0
        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)})");
        }
示例#5
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 = new Image <Rgba32>(TextureWidth, TextureHeight);

            for (int x = 0; x < no.Width; x++)
            {
                var xCheck = x < no.Width / 2;

                for (int y = 0; y < no.Height; y++)
                {
                    var yCheck = y < no.Height / 2;

                    if ((xCheck && yCheck) || (!xCheck && !yCheck))
                    {
                        no[x, y] = Color.Purple;
                    }
                    else
                    {
                        no[x, y] = Color.Black;
                    }
                }
            }

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

            var normal = blockTextures.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)
                         .Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value.Image)).ToArray();

            var nonNormal = blockTextures.Where(x => x.Value.Height != x.Value.Width)
                            .ToDictionary(x => x.Key, x => x.Value);
            //  .Select(x => new KeyValuePair<ResourceLocation, Image<Rgba32>>(x.Key, x.Value.Image.Value)).ToArray();

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

            GenerateAtlasInternal(
                new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat(
                    normal
                    ).ToArray(),
                progressReceiver, stillFrameInfo, false, out var stillAtlas);

            foreach (var nor in normal)
            {
                nor.Value.Dispose();
            }

            AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height);
            //  totalSize += size;

            _atlasLocations = stillFrameInfo;

            var stillFrame = GetMipMappedTexture2D(device, stillAtlas);

            totalSize  += stillFrame.MemoryUsage;
            _stillFrame = stillFrame;

            _frames = ProcessFrames(device,
                                    progressReceiver, nonNormal);

            totalSize += _frames.Sum(x => x.MemoryUsage);

            sw.Stop();

            Log.Info(
                $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})");
        }
示例#6
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);
             * }*/
        }
示例#7
0
        public async Task <string> CheckAndDownloadResources(IProgressReceiver progressReceiver)
        {
            progressReceiver?.UpdateProgress(0, "Checking for resource updates...");

            using var httpClient = new HttpClient(new HttpClientHandler
            {
                AllowAutoRedirect = true,
            });

            try
            {
                string assetsZipSavePath = String.Empty;

                if (Storage.TryReadString(CurrentBedrockVersionStorageKey, out var currentVersion))
                {
                    assetsZipSavePath = Path.Combine("assets", $"bedrock-{currentVersion}.zip");

                    if (!Storage.Exists(assetsZipSavePath))
                    {
                        currentVersion = null;
                    }
                }

                try
                {
                    //   var preRedirectHeaders = await httpClient.SendAsync(
                    //      new HttpRequestMessage(HttpMethod.Get, DownloadURL), HttpCompletionOption.ResponseHeadersRead);
                    //   if (preRedirectHeaders.StatusCode == HttpStatusCode.MovedPermanently)
                    //  {
                    var zipDownloadHeaders =
                        await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get,
                                                                          DownloadURL), HttpCompletionOption.ResponseHeadersRead);

                    var fileName = zipDownloadHeaders.Content?.Headers?.ContentDisposition?.FileName ??
                                   zipDownloadHeaders.RequestMessage?.RequestUri?.LocalPath;
                    var versionMatch = ExtractVersionFromFilename.Match(fileName);
                    if (versionMatch.Success)
                    {
                        var latestVersion = versionMatch.Groups["version"].Value;

                        if (latestVersion != currentVersion ||
                            (!string.IsNullOrWhiteSpace(assetsZipSavePath) &&
                             !Storage.Exists(assetsZipSavePath)))
                        {
                            progressReceiver?.UpdateProgress(
                                0, "Downloading latest bedrock assets...", "This could take a while...");

                            /* zipDownloadHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get,
                             *   zipDownloadHeaders.Headers.Location), HttpCompletionOption.ResponseContentRead);
                             * var content = await zipDownloadHeaders.Content.ReadAsByteArrayAsync();*/

                            Stopwatch sw = Stopwatch.StartNew();
                            WebClient wc = new WebClient();

                            wc.DownloadProgressChanged += (sender, args) =>
                            {
                                var downloadSpeed =
                                    $"Download speed: {PlayingState.GetBytesReadable((long) (Convert.ToDouble(args.BytesReceived) / sw.Elapsed.TotalSeconds), 2)}/s";

                                progressReceiver?.UpdateProgress(
                                    args.ProgressPercentage,
                                    $"Downloading latest bedrock assets...",
                                    downloadSpeed);
                            };


                            var content = await wc.DownloadDataTaskAsync(zipDownloadHeaders.RequestMessage.RequestUri);

                            assetsZipSavePath = Path.Combine("assets", $"bedrock-{latestVersion}.zip");

                            // save locally
                            Storage.TryWriteString(CurrentBedrockVersionStorageKey, latestVersion);

                            Storage.TryWriteBytes(assetsZipSavePath, content);

                            var existingPath = Path.Combine("assets", "bedrock");

                            Storage.TryDeleteDirectory(existingPath);
                        }
                    }
                    // }

                    return(assetsZipSavePath);
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "Failed to download bedrock assets...");
                    return(assetsZipSavePath);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Failed to fetch latest bedrock assets pack.");
                throw;
            }
        }
示例#8
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)})");
        }
示例#9
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)})");
        }