public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);
            var size         = manifestJson["size"].ToObject <Vector2u>();

            var rsi = new RSI(size);

            var images = new List <Image <Rgba32> >();
            var directionFramesList = new List <(Texture, float)[]>();
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            if (!cache.ContentFileExists(path))
            {
                throw new FileNotFoundException("Content file does not exist for font");
            }

            switch (GameController.Mode)
            {
            case GameController.DisplayMode.Headless:
                break;

            case GameController.DisplayMode.Godot:
                if (!cache.TryGetDiskFilePath(path, out string diskPath))
                {
                    throw new InvalidOperationException("Fonts can only be loaded from disk.");
                }

                var res = Godot.ResourceLoader.Load(diskPath);
                if (!(res is Godot.DynamicFontData fontData))
                {
                    throw new InvalidDataException("Path does not point to a font.");
                }

                FontData = fontData;
                break;

            case GameController.DisplayMode.Clyde:
                FontFaceHandle = IoCManager.Resolve <IFontManagerInternal>().Load(cache.ContentFileRead(path).ToArray());
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #3
0
        private Dictionary <string, Image> GetTileImages(
            ITileDefinitionManager tileDefinitionManager,
            IResourceCache resourceCache,
            int tileSize)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var images = new Dictionary <string, Image>();

            foreach (var definition in tileDefinitionManager)
            {
                var sprite = definition.SpriteName;

                if (string.IsNullOrEmpty(sprite))
                {
                    continue;
                }

                using var stream = resourceCache.ContentFileRead($"{TilesPath}{sprite}.png");
                Image tileImage = Image.Load <Rgba32>(stream);

                if (tileImage.Width != tileSize || tileImage.Height != tileSize)
                {
                    throw new NotSupportedException($"Unable to use tiles with a dimension other than {tileSize}x{tileSize}.");
                }

                images[sprite] = tileImage;
            }

            Console.WriteLine($"Indexed all tile images in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");

            return(images);
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

#if DEBUG
            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }
#endif

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);

            var toAtlas = new List <(Image <Rgba32> src, Texture[][] output, int[][] indices, Vector2i[][] offsets, int totalFrameCount)>();
        public override void Reload(IResourceCache cache, ResourcePath path, CancellationToken ct = default)
        {
            ct = ct != default ? ct : new CancellationTokenSource(30000).Token;

            for (;;)
            {
                try
                {
                    using var stream = cache.ContentFileRead(path);
                    using var reader = new StreamReader(stream, EncodingHelpers.UTF8);
                    ParsedShader     = ShaderParser.Parse(reader, cache);
                    break;
                }
                catch (IOException ioe)
                {
                    if (!PathHelpers.IsFileInUse(ioe))
                    {
                        throw;
                    }

                    ct.ThrowIfCancellationRequested();

                    Thread.Sleep(3);
                }
            }

            var clyde = IoCManager.Resolve <IClydeInternal>();

            clyde.ReloadShader(ClydeHandle, ParsedShader);
        }
 public override void Load(IResourceCache cache, ResourcePath path)
 {
     using (var stream = cache.ContentFileRead(path))
         using (var reader = new StreamReader(stream, EncodingHelpers.UTF8))
         {
             Asset = GodotParser.Parse(reader);
         }
 }
        private void _loadOpenGL(IResourceCache cache, ResourcePath path, TextureLoadParameters?parameters)
        {
            DebugTools.Assert(GameController.Mode == GameController.DisplayMode.Clyde);

            var manager = IoCManager.Resolve <IClyde>();

            Texture = manager.LoadTextureFromPNGStream(cache.ContentFileRead(path), path.ToString(), parameters);
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            if (!cache.ContentFileExists(path))
            {
                throw new FileNotFoundException("Content file does not exist for font");
            }

            FontFaceHandle = IoCManager.Resolve <IFontManagerInternal>().Load(cache.ContentFileRead(path).ToArray());
        }
Exemple #9
0
 public override void Load(IResourceCache cache, ResourcePath path)
 {
     using (var stream = cache.ContentFileRead(path))
         using (var reader = new StreamReader(stream, Encoding.UTF8))
         {
             var code = reader.ReadToEnd();
             GodotShader = new Godot.Shader
             {
                 Code = code,
             };
         }
 }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            using (var stream = cache.ContentFileRead(path))
                using (var reader = new StreamReader(stream, EncodingHelpers.UTF8))
                {
                    ParsedShader = ShaderParser.Parse(reader, cache);
                }

            var clyde = IoCManager.Resolve <IClydeInternal>();

            ClydeHandle = clyde.LoadShader(ParsedShader, path.ToString());
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            if (!cache.ContentFileExists(path))
            {
                throw new FileNotFoundException("Content file does not exist for audio sample.");
            }

            switch (GameController.Mode)
            {
            case GameController.DisplayMode.Headless:
                AudioStream = new AudioStream();
                break;

            case GameController.DisplayMode.Godot:
                using (var fileStream = cache.ContentFileRead(path))
                {
                    var stream = new Godot.AudioStreamOGGVorbis()
                    {
                        Data = fileStream.ToArray(),
                    };
                    if (stream.GetLength() == 0)
                    {
                        throw new InvalidDataException();
                    }
                    AudioStream = new AudioStream(stream);
                }
                break;

            case GameController.DisplayMode.Clyde:
                using (var fileStream = cache.ContentFileRead(path))
                {
                    AudioStream = IoCManager.Resolve <IClyde>().LoadAudioOggVorbis(fileStream);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #12
0
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            using (var stream = cache.ContentFileRead(path))
                using (var reader = new StreamReader(stream, Encoding.UTF8))
                {
                    var code = reader.ReadToEnd();
                    GodotShader = new Godot.Shader
                    {
                        Code = code,
                    };
                }

            var properties = Godot.VisualServer.ShaderGetParamList(GodotShader.GetRid());

            foreach (var dict in properties.Cast <IDictionary <object, object> >())
            {
                Parameters.Add((string)dict["name"], DetectParamType(dict));
            }
        }
        private void _genTextureAtlas()
        {
            var       defList  = TileDefs.Where(t => !string.IsNullOrEmpty(t.SpriteName)).ToList();
            const int tileSize = EyeManager.PIXELSPERMETER;

            var dimensionX = (int)Math.Ceiling(Math.Sqrt(defList.Count));
            var dimensionY = (int)Math.Ceiling((float)defList.Count / dimensionX);

            var sheet = new Image <Rgba32>(dimensionX * tileSize, dimensionY * tileSize);

            for (var i = 0; i < defList.Count; i++)
            {
                var def    = defList[i];
                var column = i % dimensionX;
                var row    = i / dimensionX;

                Image <Rgba32> image;
                using (var stream = _resourceCache.ContentFileRead($"/Textures/Tiles/{def.SpriteName}.png"))
                {
                    image = Image.Load(stream);
                }

                if (image.Width != tileSize || image.Height != tileSize)
                {
                    throw new NotSupportedException("Unable to use tiles with a dimension other than 32x32.");
                }

                var point = new Vector2i(column * tileSize, row * tileSize);

                image.Blit(new UIBox2i(0, 0, image.Width, image.Height), sheet, point);

                var w = (float)sheet.Width;
                var h = (float)sheet.Height;

                _tileRegions.Add(def.TileId,
                                 Box2.FromDimensions(
                                     point.X / w, (h - point.Y - EyeManager.PIXELSPERMETER) / h,
                                     tileSize / w, tileSize / h));
            }

            TileTextureAtlas = Texture.LoadFromImage(sheet, "Tile Atlas");
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            using (var stream = cache.ContentFileRead(path))
                using (var reader = new StreamReader(stream, Encoding.UTF8))
                {
                    ParsedShader = ShaderParser.Parse(reader);
                }

            switch (GameController.Mode)
            {
            case GameController.DisplayMode.Headless:
                return;

            case GameController.DisplayMode.Godot:
                GodotShader = new Godot.Shader
                {
                    Code = _getGodotCode(),
                };
                break;

            case GameController.DisplayMode.Clyde:
                ClydeHandle = IoCManager.Resolve <IClyde>().LoadShader(ParsedShader);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (GameController.OnGodot)
            {
                GodotShader = new Godot.Shader
                {
                    Code = _getGodotCode(),
                };
            }
            else
            {
                var clyde = IoCManager.Resolve <IClyde>();
                // TODO: vertex shaders.
                ClydeHandle = clyde.LoadShader(ParsedShader, path.ToString());
            }
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            if (!cache.ContentFileExists(path))
            {
                throw new FileNotFoundException("Content file does not exist for audio sample.");
            }

            using (var fileStream = cache.ContentFileRead(path))
            {
                var stream = new Godot.AudioStreamOGGVorbis()
                {
                    Data = fileStream.ToArray(),
                };
                if (stream.GetLength() == 0)
                {
                    throw new InvalidDataException();
                }
                AudioStream = new GodotAudioStreamSource(stream);
            }
        }
        private void _loadGodot(IResourceCache cache, ResourcePath path, TextureLoadParameters?parameters)
        {
            DebugTools.Assert(GameController.Mode == GameController.DisplayMode.Godot);

            using (var stream = cache.ContentFileRead(path))
            {
                var buffer = stream.ToArray();
                var image  = new Godot.Image();
                var error  = image.LoadPngFromBuffer(buffer);
                if (error != Godot.Error.Ok)
                {
                    throw new InvalidDataException($"Unable to load texture from buffer, reason: {error}");
                }
                godotTexture = new Godot.ImageTexture();
                godotTexture.CreateFromImage(image);
            }

            // Disable filter by default because pixel art.
            (parameters ?? TextureLoadParameters.Default).SampleParameters.ApplyToGodotTexture(godotTexture);
            Texture = new GodotTextureSource(godotTexture);
        }
Exemple #17
0
        private Dictionary <string, List <Image> > GetTileImages(
            ITileDefinitionManager tileDefinitionManager,
            IResourceCache resourceCache,
            int tileSize)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var images = new Dictionary <string, List <Image> >();

            foreach (var definition in tileDefinitionManager)
            {
                var sprite = definition.SpriteName;
                images[sprite] = new List <Image>(definition.Variants);

                if (string.IsNullOrEmpty(sprite))
                {
                    continue;
                }

                using var stream = resourceCache.ContentFileRead($"{TilesPath}{sprite}.png");
                Image tileSheet = Image.Load <Rgba32>(stream);

                if (tileSheet.Width != tileSize * definition.Variants || tileSheet.Height != tileSize)
                {
                    throw new NotSupportedException($"Unable to use tiles with a dimension other than {tileSize}x{tileSize}.");
                }

                for (var i = 0; i < definition.Variants; i++)
                {
                    var tileImage = tileSheet.Clone(o => o.Crop(new Rectangle(tileSize * i, 0, 32, 32)));
                    images[sprite].Add(tileImage);
                }
            }

            Console.WriteLine($"Indexed all tile images in {(int) stopwatch.Elapsed.TotalMilliseconds} ms");

            return(images);
        }
        private void _genTextureAtlas()
        {
            var       defList  = TileDefs.Where(t => !string.IsNullOrEmpty(t.SpriteName)).ToList();
            const int tileSize = EyeManager.PIXELSPERMETER;

            var dimensionX = (int)Math.Ceiling(Math.Sqrt(defList.Count));
            var dimensionY = (int)Math.Ceiling((float)defList.Count / dimensionX);

            var sheet = new Image <Rgba32>(dimensionX * tileSize, dimensionY * tileSize);

            for (var i = 0; i < defList.Count; i++)
            {
                var def    = defList[i];
                var column = i % dimensionX;
                var row    = i / dimensionX;

                Image <Rgba32> image;
                using (var stream = _resourceCache.ContentFileRead($"/Textures/Tiles/{def.SpriteName}.png"))
                {
                    image = Image.Load(stream);
                }

                if (image.Width != tileSize || image.Height != tileSize)
                {
                    throw new NotImplementedException("Unable to use tiles with a dimension other than 32x32.");
                }

                var point = new Point(column * tileSize, row * tileSize);

                sheet.Mutate(x => x.DrawImage(image, point,
                                              PixelColorBlendingMode.Overlay, 1));

                _tileRegions.Add(def.TileId,
                                 UIBox2.FromDimensions(
                                     point.X / (float)sheet.Width, point.Y / (float)sheet.Height,
                                     tileSize / (float)sheet.Width, tileSize / (float)sheet.Height));
            }

            TileTextureAtlas = Texture.LoadFromImage(sheet, "Tile Atlas");
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            if (!cache.ContentFileExists(path))
            {
                throw new FileNotFoundException("Content file does not exist for audio sample.");
            }

            using (var fileStream = cache.ContentFileRead(path))
            {
                var clyde = IoCManager.Resolve <IClydeAudio>();
                if (path.Extension == "ogg")
                {
                    AudioStream = clyde.LoadAudioOggVorbis(fileStream, path.ToString());
                }
                else if (path.Extension == "wav")
                {
                    AudioStream = clyde.LoadAudioWav(fileStream, path.ToString());
                }
                else
                {
                    throw new NotSupportedException("Unable to load audio files outside of ogg Vorbis or PCM wav");
                }
            }
        }
Exemple #20
0
        private void _loadOpenGL(IResourceCache cache, ResourcePath path, TextureLoadParameters?parameters)
        {
            var manager = IoCManager.Resolve <IClyde>();

            Texture = manager.LoadTextureFromPNGStream(cache.ContentFileRead(path), path.ToString(), parameters);
        }
Exemple #21
0
        internal static void LoadPreTexture(IResourceCache cache, LoadStepData data)
        {
            var metadata = LoadRsiMetadata(cache, data.Path);

            var stateCount = metadata.States.Length;
            var toAtlas    = new StateReg[stateCount];

            var frameSize = metadata.Size;
            var rsi       = new RSI(frameSize, data.Path, metadata.States.Length);

            var callbackOffsets = new Dictionary <RSI.StateId, Vector2i[][]>(stateCount);

            // Check for duplicate states
            for (var i = 0; i < metadata.States.Length; i++)
            {
                var stateId = metadata.States[i].StateId;

                for (int j = i + 1; j < metadata.States.Length; j++)
                {
                    if (stateId == metadata.States[j].StateId)
                    {
                        throw new RSILoadException($"RSI '{data.Path}' has a duplicate stateId '{stateId}'.");
                    }
                }
            }

            // Do every state.
            for (var index = 0; index < metadata.States.Length; index++)
            {
                ref var reg = ref toAtlas[index];

                var stateObject = metadata.States[index];
                // Load image from disk.
                var texPath = data.Path / (stateObject.StateId + ".png");
                using (var stream = cache.ContentFileRead(texPath))
                {
                    reg.Src = Image.Load <Rgba32>(stream);
                }

                if (reg.Src.Width % frameSize.X != 0 || reg.Src.Height % frameSize.Y != 0)
                {
                    var regDims  = $"{reg.Src.Width}x{reg.Src.Height}";
                    var iconDims = $"{frameSize.X}x{frameSize.Y}";
                    throw new RSILoadException($"State '{stateObject.StateId}' image size ({regDims}) is not a multiple of the icon size ({iconDims}).");
                }

                // Load all frames into a list so we can operate on it more sanely.
                reg.TotalFrameCount = stateObject.Delays.Sum(delayList => delayList.Length);

                var(foldedDelays, foldedIndices) = FoldDelays(stateObject.Delays);

                var textures       = new Texture[foldedIndices.Length][];
                var callbackOffset = new Vector2i[foldedIndices.Length][];

                for (var i = 0; i < textures.Length; i++)
                {
                    textures[i]       = new Texture[foldedIndices[0].Length];
                    callbackOffset[i] = new Vector2i[foldedIndices[0].Length];
                }

                reg.Output  = textures;
                reg.Indices = foldedIndices;
                reg.Offsets = callbackOffset;

                var state = new RSI.State(frameSize, rsi, stateObject.StateId, stateObject.DirType, foldedDelays,
                                          textures);
                rsi.AddState(state);

                callbackOffsets[stateObject.StateId] = callbackOffset;
            }
Exemple #22
0
        private void _initWindow()
        {
            var width  = _configurationManager.GetCVar <int>("display.width");
            var height = _configurationManager.GetCVar <int>("display.height");

            _window = new GameWindow(
                width,
                height,
                GraphicsMode.Default,
                "Space Station 14",
                GameWindowFlags.Default,
                DisplayDevice.Default,
                3, 3,
#if DEBUG
                GraphicsContextFlags.Debug | GraphicsContextFlags.ForwardCompatible
#else
                GraphicsContextFlags.ForwardCompatible
#endif
                )
            {
                Visible = true
            };

            _windowSize = new Vector2i(_window.Width, _window.Height);

            _mainThread = Thread.CurrentThread;

            _window.KeyDown += (sender, eventArgs) =>
            {
                _gameController.GameController.KeyDown((KeyEventArgs)eventArgs);
            };

            _window.KeyUp  += (sender, eventArgs) => { _gameController.GameController.KeyUp((KeyEventArgs)eventArgs); };
            _window.Closed += (sender, eventArgs) => { _gameController.GameController.Shutdown("Window closed"); };
            _window.Resize += (sender, eventArgs) =>
            {
                var oldSize = _windowSize;
                _windowSize = new Vector2i(_window.Width, _window.Height);
                GL.Viewport(0, 0, _window.Width, _window.Height);
                GL.BindTexture(TextureTarget.Texture2D, LightTexture.Handle);
                var(lightW, lightH) = _lightMapSize();
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba16f, lightW, lightH, 0,
                              PixelFormat.Rgba, PixelType.Float, IntPtr.Zero);
                OnWindowResized?.Invoke(new WindowResizedEventArgs(oldSize, _windowSize));
            };
            _window.MouseDown += (sender, eventArgs) =>
            {
                var mouseButtonEventArgs = (MouseButtonEventArgs)eventArgs;
                _gameController.GameController.MouseDown(mouseButtonEventArgs);
                if (!mouseButtonEventArgs.Handled)
                {
                    _gameController.GameController.KeyDown((KeyEventArgs)eventArgs);
                }
            };
            _window.MouseUp += (sender, eventArgs) =>
            {
                var mouseButtonEventArgs = (MouseButtonEventArgs)eventArgs;
                _gameController.GameController.MouseUp(mouseButtonEventArgs);
                if (!mouseButtonEventArgs.Handled)
                {
                    _gameController.GameController.KeyUp((KeyEventArgs)eventArgs);
                }
            };
            _window.MouseMove += (sender, eventArgs) =>
            {
                MouseScreenPosition = new Vector2(eventArgs.X, eventArgs.Y);
                _gameController.GameController.MouseMove((MouseMoveEventArgs)eventArgs);
            };
            _window.MouseWheel += (sender, eventArgs) =>
            {
                _gameController.GameController.MouseWheel((MouseWheelEventArgs)eventArgs);
            };
            _window.KeyPress += (sender, eventArgs) =>
            {
                // If this is a surrogate it has to be specifically handled and I'm not doing that yet.
                DebugTools.Assert(!char.IsSurrogate(eventArgs.KeyChar));

                _gameController.GameController.TextEntered(new TextEventArgs(eventArgs.KeyChar));
            };

            using (var iconFile = _resourceCache.ContentFileRead("/Textures/Logo/icon.ico"))
            {
                _window.Icon = new Icon(iconFile);
            }

            _initOpenGL();
        }
Exemple #23
0
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

#if DEBUG
            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }
#endif

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);

            var toAtlas = new List <(Image <Rgba32> src, Texture[][] output, int[][] indices, int totalFrameCount)>();

            var metaData  = ParseMetaData(manifestJson);
            var frameSize = metaData.Size;
            var rsi       = new RSI(frameSize);

            // Do every state.
            foreach (var stateObject in metaData.States)
            {
                // Load image from disk.
                var texPath   = path / (stateObject.StateId + ".png");
                var image     = Image.Load(cache.ContentFileRead(texPath));
                var sheetSize = new Vector2i(image.Width, image.Height);

                if (sheetSize.X % frameSize.X != 0 || sheetSize.Y % frameSize.Y != 0)
                {
                    throw new RSILoadException("State image size is not a multiple of the icon size.");
                }

                // Load all frames into a list so we can operate on it more sanely.
                var frameCount = stateObject.Delays.Sum(delayList => delayList.Length);

                var(foldedDelays, foldedIndices) = FoldDelays(stateObject.Delays);

                var textures = new Texture[foldedIndices.Length][];

                for (var i = 0; i < textures.Length; i++)
                {
                    textures[i] = new Texture[foldedIndices[0].Length];
                }

                var state = new RSI.State(frameSize, stateObject.StateId, stateObject.DirType, foldedDelays, textures);
                rsi.AddState(state);

                toAtlas.Add((image, textures, foldedIndices, frameCount));
            }

            // Poorly hacked in texture atlas support here.
            {
                var totalFrameCount = toAtlas.Sum(p => p.totalFrameCount);

                // Generate atlas.
                var dimensionX = (int)MathF.Ceiling(MathF.Sqrt(totalFrameCount));
                var dimensionY = (int)MathF.Ceiling((float)totalFrameCount / dimensionX);

                using var sheet = new Image <Rgba32>(dimensionX * frameSize.X, dimensionY * frameSize.Y);

                var sheetIndex = 0;
                foreach (var(src, _, _, frameCount) in toAtlas)
                {
                    // Blit all the frames over.
                    for (var i = 0; i < frameCount; i++)
                    {
                        var srcWidth  = (src.Width / frameSize.X);
                        var srcColumn = i % srcWidth;
                        var srcRow    = i / srcWidth;
                        var srcPos    = (srcColumn * frameSize.X, srcRow *frameSize.Y);

                        var sheetColumn = (sheetIndex + i) % dimensionX;
                        var sheetRow    = (sheetIndex + i) / dimensionX;
                        var sheetPos    = (sheetColumn * frameSize.X, sheetRow *frameSize.Y);

                        var srcBox = UIBox2i.FromDimensions(srcPos, frameSize);

                        src.Blit(srcBox, sheet, sheetPos);
                    }

                    sheetIndex += frameCount;
                }

                // Load atlas.
                var texture = Texture.LoadFromImage(sheet, path.ToString());

                var sheetOffset = 0;
                foreach (var(src, output, indices, frameCount) in toAtlas)
                {
                    for (var i = 0; i < indices.Length; i++)
                    {
                        var dirIndices = indices[i];
                        var dirOutput  = output[i];

                        for (var j = 0; j < dirIndices.Length; j++)
                        {
                            var index = sheetOffset + dirIndices[j];

                            var sheetColumn = index % dimensionX;
                            var sheetRow    = index / dimensionX;
                            var sheetPos    = (sheetColumn * frameSize.X, sheetRow *frameSize.Y);

                            dirOutput[j] = new AtlasTexture(texture, UIBox2.FromDimensions(sheetPos, frameSize));
                        }
                    }

                    sheetOffset += frameCount;
                }
            }

            foreach (var(image, _, _, _) in toAtlas)
            {
                image.Dispose();
            }

            RSI = rsi;
        }
Exemple #24
0
        private ShaderProgram _compileProgram(ResourcePath vertex, ResourcePath fragment, string name = null)
        {
            string vertexSource;
            string fragmentSource;

            using (var vertexReader = new StreamReader(_resourceCache.ContentFileRead(vertex), Encoding.UTF8))
            {
                vertexSource = vertexReader.ReadToEnd();
            }

            using (var fragmentReader = new StreamReader(_resourceCache.ContentFileRead(fragment), Encoding.UTF8))
            {
                fragmentSource = fragmentReader.ReadToEnd();
            }

            Shader vertexShader   = null;
            Shader fragmentShader = null;

            try
            {
                try
                {
                    vertexShader = new Shader(this, ShaderType.VertexShader, vertexSource, vertex.ToString());
                }
                catch (ShaderCompilationException e)
                {
                    throw new ShaderCompilationException(
                              $"Failed to compile vertex shader {vertex}, see inner for details.", e);
                }

                try
                {
                    fragmentShader = new Shader(this, ShaderType.FragmentShader, fragmentSource, fragment.ToString());
                }
                catch (ShaderCompilationException e)
                {
                    throw new ShaderCompilationException(
                              $"Failed to compile fragment shader {fragment}, see inner for details.", e);
                }

                var program = new ShaderProgram(this, name);
                program.Add(vertexShader);
                program.Add(fragmentShader);

                try
                {
                    program.Link();
                }
                catch (ShaderCompilationException e)
                {
                    program.Delete();

                    throw new ShaderCompilationException(
                              $"Failed to link shaders. vert: {vertex}, frag: {fragment}, see inner for details.", e);
                }

                return(program);
            }
            finally
            {
                vertexShader?.Delete();
                fragmentShader?.Delete();
            }
        }
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);
            var size         = manifestJson["size"].ToObject <Vector2u>();

            var rsi = new RSI(size);

            // Do every state.
            foreach (var stateObject in manifestJson["states"].Cast <JObject>())
            {
                var stateName = stateObject["name"].ToObject <string>();
                var dirValue  = stateObject["directions"].ToObject <int>();
                RSI.State.DirectionType directions;

                switch (dirValue)
                {
                case 1:
                    directions = RSI.State.DirectionType.Dir1;
                    break;

                case 4:
                    directions = RSI.State.DirectionType.Dir4;
                    break;

                default:
                    throw new RSILoadException($"Invalid direction: {dirValue}");
                }

                // We can ignore selectors and flags for now,
                // because they're not used yet!

                // Get the lists of delays.
                float[][] delays;
                if (stateObject.TryGetValue("delays", out var delayToken))
                {
                    delays = delayToken.ToObject <float[][]>();

                    if (delays.Length != dirValue)
                    {
                        throw new RSILoadException($"Directions count does not match amount of delays specified.");
                    }

                    for (var i = 0; i < delays.Length; i++)
                    {
                        var delayList = delays[i];
                        if (delayList.Length == 0)
                        {
                            delays[i] = new float[] { 1 };
                        }
                    }
                }
                else
                {
                    delays = new float[dirValue][];
                    // No delays specified, default to 1 frame per dir.
                    for (var i = 0; i < dirValue; i++)
                    {
                        delays[i] = new float[] { 1 };
                    }
                }

                var texPath = path / (stateName + ".png");
                var texture = cache.GetResource <TextureResource>(texPath).Texture;

                if (texture.Width % size.X != 0 || texture.Height % size.Y != 0)
                {
                    throw new RSILoadException("State image size is not a multiple of the icon size.");
                }

                // Amount of icons per row of the sprite sheet.
                var sheetWidth = texture.Width / size.X;

                var iconFrames = new (Texture, float)[dirValue][];