ReleaseBuffer() public méthode

public ReleaseBuffer ( ) : void
Résultat void
Exemple #1
0
        public Theater(TileSet tileset)
        {
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize), true));
            };

            var sourceCache = new Dictionary <string, ISpriteSource>();

            templates    = new Dictionary <ushort, Sprite[]>();
            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            foreach (var t in tileset.Templates)
            {
                templates.Add(t.Value.Id, LoadTemplate(t.Value.Image, tileset.Extensions, sourceCache, t.Value.Frames));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Exemple #2
0
        public Theater(TileSet tileset)
        {
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize), true));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            templates    = new Dictionary <ushort, Sprite[]>();

            var frameCache = new FrameCache(Game.modData.SpriteLoaders, tileset.Extensions);

            foreach (var t in tileset.Templates)
            {
                var allFrames = frameCache[t.Value.Image];
                var frames    = t.Value.Frames != null?t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                templates.Add(t.Value.Id, frames.Select(f => sheetBuilder.Add(f)).ToArray());
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Exemple #3
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames = frameCache[i];
                    var frames    = t.Value.Frames != null?t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                    variants.Add(frames.Select(f => sheetBuilder.Add(f)).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Exemple #4
0
        /// <summary>
        /// Резервирует место под SPrite в текстуре opengl
        /// Определяет в какой канал текстуры будут записаны байты
        /// </summary>
        /// <param name="imageSize"></param>
        /// <param name="zRamp"></param>
        /// <param name="spriteOffset"></param>
        /// <returns></returns>
        public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset)
        {
            //используется одномерный массив. Поэтому все разбито по Height(row) и смещение внутри row.
            if (imageSize.Width + p.X > currentSheet.Size.Width)             //если дошли до смещения равного ширине картинки, то сбрасываем смещение до 0 и делаем переход на высоту равную предыдущей высоте.
            {
                p         = new int2(0, p.Y + rowHeight);
                rowHeight = imageSize.Height;
            }

            if (imageSize.Height > rowHeight)
            {
                rowHeight = imageSize.Height;
            }

            if (p.Y + imageSize.Height > currentSheet.Size.Height)             //если вышли за пределы высоты в одном канале, то переходим в другой канал. и скидываем p=int2.Zero
            {
                var next = NextChannel(channel);
                if (next == null)                 //если закончились каналы внутри текстуры , то создаем новый Sheet.
                {
                    currentSheet.ReleaseBuffer();
                    currentSheet = allocateSheetDelegate();
                    sheets.Add(currentSheet);
                    channel = Type == SheetType.Indexed ? TextureChannel.Red : TextureChannel.RGBA;
                }
                else
                {
                    channel = next.Value;
                }

                rowHeight = imageSize.Height;
                p         = int2.Zero;
            }

            var rect = new Sprite(currentSheet, new Rectangle(p.X, p.Y, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha);

            p += new int2(imageSize.Width, 0);

            return(rect);
        }
Exemple #5
0
        public Sprite Allocate(Size imageSize, float2 spriteOffset)
        {
            if (imageSize.Width + p.X > current.Size.Width)
            {
                p         = new Point(0, p.Y + rowHeight);
                rowHeight = imageSize.Height;
            }

            if (imageSize.Height > rowHeight)
            {
                rowHeight = imageSize.Height;
            }

            if (p.Y + imageSize.Height > current.Size.Height)
            {
                var next = NextChannel(channel);
                if (next == null)
                {
                    current.ReleaseBuffer();
                    current = allocateSheet();
                    sheets.Add(current);
                    channel = TextureChannel.Red;
                }
                else
                {
                    channel = next.Value;
                }

                rowHeight = imageSize.Height;
                p         = new Point(0, 0);
            }

            var rect = new Sprite(current, new Rectangle(p, imageSize), spriteOffset, channel, BlendMode.Alpha);

            p.X += imageSize.Width;

            return(rect);
        }
Exemple #6
0
        public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset, float scale = 1f)
        {
            if (imageSize.Width + p.X + margin > current.Size.Width)
            {
                p         = new int2(0, p.Y + rowHeight + margin);
                rowHeight = imageSize.Height;
            }

            if (imageSize.Height > rowHeight)
            {
                rowHeight = imageSize.Height;
            }

            if (p.Y + imageSize.Height + margin > current.Size.Height)
            {
                var next = NextChannel(channel);
                if (next == null)
                {
                    current.ReleaseBuffer();
                    current = allocateSheet();
                    sheets.Add(current);
                    channel = Type == SheetType.Indexed ? TextureChannel.Red : TextureChannel.RGBA;
                }
                else
                {
                    channel = next.Value;
                }

                rowHeight = imageSize.Height;
                p         = int2.Zero;
            }

            var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha, scale);

            p += new int2(imageSize.Width + margin, 0);

            return(rect);
        }
Exemple #7
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames  = frameCache[i];
                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
                    variants.Add(indices.Select(j =>
                    {
                        var f    = allFrames[j];
                        var tile = t.Value.Contains(j) ? t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp   = tile != null ? tile.ZRamp : 1f;
                        var offset  = new float3(f.Offset, zOffset);
                        var s       = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        Util.FastCopyIntoChannel(s, f.Data);

                        if (tileset.EnableDepth)
                        {
                            var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Exemple #8
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;
            var type      = tileset.EnableDepth ? SheetType.DualIndexed : SheetType.Indexed;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(type, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(type, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames  = frameCache[i];
                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
                    variants.Add(indices.Select(j =>
                    {
                        var f = allFrames[j];
                        var s = sheetBuilder.Allocate(f.Size, f.Offset);
                        Util.FastCopyIntoChannel(s, 0, f.Data);

                        if (tileset.EnableDepth)
                        {
                            Util.FastCopyIntoChannel(s, 1, allFrames[j + frameCount].Data);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Exemple #9
0
        public Theater(TileSet tileset, Action <uint, string> onMissingImage = null)
        {
            this.tileset = tileset;
            var allocated = false;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            random = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    ISpriteFrame[] allFrames;
                    if (onMissingImage != null)
                    {
                        try
                        {
                            allFrames = frameCache[i];
                        }
                        catch (FileNotFoundException)
                        {
                            onMissingImage(t.Key, i);
                            continue;
                        }
                    }
                    else
                    {
                        allFrames = frameCache[i];
                    }

                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Exts.MakeArray(t.Value.TilesCount, j => j);

                    var start = indices.Min();
                    var end   = indices.Max();
                    if (start < 0 || end >= frameCount)
                    {
                        throw new YamlException("Template `{0}` uses frames [{1}..{2}] of {3}, but only [0..{4}] actually exist"
                                                .F(t.Key, start, end, i, frameCount - 1));
                    }

                    variants.Add(indices.Select(j =>
                    {
                        var f    = allFrames[j];
                        var tile = t.Value.Contains(j) ? t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp   = tile != null ? tile.ZRamp : 1f;
                        var offset  = new float3(f.Offset, zOffset);
                        var type    = SheetBuilder.FrameTypeToSheetType(f.Type);

                        // Defer SheetBuilder creation until we know what type of frames we are loading!
                        // TODO: Support mixed indexed and BGRA frames
                        if (sheetBuilder == null)
                        {
                            sheetBuilder = new SheetBuilder(SheetBuilder.FrameTypeToSheetType(f.Type), allocate);
                        }
                        else if (type != sheetBuilder.Type)
                        {
                            throw new YamlException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA.");
                        }

                        var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        Util.FastCopyIntoChannel(s, f.Data);

                        if (tileset.EnableDepth)
                        {
                            var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, s.Sheet, ss.Bounds, ss.Channel);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));
                }

                if (onMissingImage != null && !variants.Any())
                {
                    continue;
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[sheetBuilder.Type == SheetType.BGRA ? 4 : 1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }