Ejemplo n.º 1
0
        public virtual TileMeshDraw Build(TileGridBlock block, ITileDefinitionSource tileDefinitionSource, GraphicsContext graphicsContext, ref Vector2 cellSize)
        {
            TileMeshDraw tileMeshDraw = null;

            AggregateTiles(block, tileDefinitionSource, graphicsContext, ref cellSize);
            CompleteBuild(graphicsContext, block.BlockSize * block.BlockSize, ref tileMeshDraw);

            return(tileMeshDraw);
        }
Ejemplo n.º 2
0
        public void Draw(TileMeshDraw tileMeshDraw)
        {
            CheckBeginHasBeenCalled();
            GraphicsContext.CommandList.SetVertexBuffer(0, tileMeshDraw.VertexBuffer.Buffer, tileMeshDraw.VertexBuffer.Offset, tileMeshDraw.VertexBuffer.Stride);
            GraphicsContext.CommandList.SetIndexBuffer(tileMeshDraw.IndexBuffer.Buffer, 0, tileMeshDraw.IndexBuffer.Is32Bit);

            foreach (var range in tileMeshDraw.Ranges)
            {
                if (textureUpdater.HasValue)
                {
                    Parameters.Set(textureUpdater.Value, range.Texture);
                }

                Effect.Apply(GraphicsContext);

                GraphicsContext.CommandList.DrawIndexed(range.IndexCount, range.StartIndex);
            }
        }
Ejemplo n.º 3
0
        private static TileMeshDraw New <TVertex, TIndex>(GraphicsDevice graphicsDevice, VertexDeclaration layout, TVertex[] vertexBuffer, TIndex[] indexBuffer, IEnumerable <DrawRange> ranges)
            where TVertex : struct, IVertex
            where TIndex : struct
        {
            if (graphicsDevice == null)
            {
                throw new ArgumentNullException(nameof(graphicsDevice));
            }

            if (layout == null)
            {
                throw new ArgumentNullException(nameof(layout));
            }

            if (vertexBuffer == null)
            {
                throw new ArgumentNullException(nameof(vertexBuffer));
            }

            if (indexBuffer == null)
            {
                throw new ArgumentNullException(nameof(indexBuffer));
            }

            if (ranges == null)
            {
                throw new ArgumentNullException(nameof(ranges));
            }

            var batch = new TileMeshDraw()
            {
                VertexBuffer = new VertexBufferBinding(Buffer.Vertex.New <TVertex>(graphicsDevice, vertexBuffer, GraphicsResourceUsage.Default), layout, vertexBuffer.Length),
                IndexBuffer  = new IndexBufferBinding(Buffer.Index.New(graphicsDevice, indexBuffer, GraphicsResourceUsage.Default), Utilities.SizeOf <TIndex>() == sizeof(Int32), indexBuffer.Length),
                Ranges       = new List <DrawRange>(ranges),
            };

            return(batch);
        }
Ejemplo n.º 4
0
        public void GetTileMeshDraws(IList <TileGridBlock> blocks, GraphicsContext graphicsContext, ref Vector2 cellSize, IList <TileMeshDraw> tileMeshDrawsOut)
        {
            if (blocks == null)
            {
                throw new ArgumentNullException(nameof(blocks));
            }

            if (graphicsContext == null)
            {
                throw new ArgumentNullException(nameof(graphicsContext));
            }

            if (tileMeshDrawsOut == null)
            {
                throw new ArgumentNullException(nameof(tileMeshDrawsOut));
            }


            if (tileMeshDrawBuilder == null)
            {
                return;
            }



            for (int i = 0; i < blocks.Count; i++)
            {
                var          currentBlock = blocks[i];
                TileMeshDraw tileMeshDraw = null;

                if (previousTileMeshDraws.TryGetValue(currentBlock.Location, out tileMeshDraw))
                {
                    if (currentBlock.VisualyInvalidated)
                    {
                        pendingBlocks.Add(currentBlock);
                        tileMeshDrawsForRecycle.Add(tileMeshDraw);
                    }
                    else
                    {
                        tileMeshDraws[currentBlock.Location] = tileMeshDraw;
                        tileMeshDrawsOut.Add(tileMeshDraw);
                    }

                    previousTileMeshDraws.Remove(currentBlock.Location);
                }
                else
                {
                    pendingBlocks.Add(currentBlock);
                }
            }

            if (pendingBlocks.Count > 0)
            {
                for (int i = 0; i < pendingBlocks.Count; i++)
                {
                    var currentBlock = pendingBlocks[i];

                    TileMeshDraw tileMeshDraw = null;

                    if (tileMeshDrawsForRecycle.Count > 0)
                    {
                        var lastIndex = tileMeshDrawsForRecycle.Count - 1;
                        tileMeshDraw = tileMeshDrawsForRecycle[lastIndex];
                        tileMeshDrawsForRecycle.RemoveAt(lastIndex);

                        tileMeshDrawBuilder.Recycle(tileMeshDraw, currentBlock, tileDefinitionSource, graphicsContext, ref cellSize);
                    }
                    else
                    {
                        tileMeshDraw = tileMeshDrawBuilder.Build(currentBlock, tileDefinitionSource, graphicsContext, ref cellSize);
                    }

                    tileMeshDraws[currentBlock.Location] = tileMeshDraw;
                    currentBlock.VisualyInvalidated      = false;
                    tileMeshDrawsOut.Add(tileMeshDraw);
                }
            }

            tileMeshDrawsForRecycle.AddRange(previousTileMeshDraws.Values);
            previousTileMeshDraws.Clear();
            pendingBlocks.Clear();
            Utilities.Swap(ref tileMeshDraws, ref previousTileMeshDraws);

            //Reduce cache.
            while (tileMeshDrawsForRecycle.Count > 4) //Should be configurable. Yes it should.
            {
                var lastIndex = tileMeshDrawsForRecycle.Count - 1;
                tileMeshDrawsForRecycle[lastIndex].Dispose();
                tileMeshDrawsForRecycle.RemoveAt(lastIndex);
            }
        }
Ejemplo n.º 5
0
 public virtual void Recycle(TileMeshDraw tileMeshDraw, TileGridBlock block, ITileDefinitionSource tileDefinitionSource, GraphicsContext graphicsContext, ref Vector2 cellSize)
 {
     AggregateTiles(block, tileDefinitionSource, graphicsContext, ref cellSize);
     CompleteBuild(graphicsContext, block.BlockSize * block.BlockSize, ref tileMeshDraw);
 }
Ejemplo n.º 6
0
        protected virtual void CompleteBuild(GraphicsContext graphicsContext, int maxTileCount, ref TileMeshDraw tileMeshDraw)
        {
            var  indexBufferLength = maxTileCount * IndiciesPerTile;
            bool updateIndexBuffer = false;

            if (indexBuffer == null || indexBuffer.Length != indexBufferLength)
            {
                indexBuffer = new short[indexBufferLength];
                BuildIndicies(indexBuffer, maxTileCount);
                updateIndexBuffer = true;
            }


            var vertexBufferLength = maxTileCount * VerticiesPerTile;

            if (vertexBuffer == null || vertexBuffer.Length != vertexBufferLength)
            {
                vertexBuffer = new TVertex[vertexBufferLength];
            }

            tileMeshDraw?.Ranges.Clear();

            var ranges = tileMeshDraw?.Ranges ?? new List <TileMeshDraw.DrawRange>();

            int tileCount   = 0;
            int vertexIndex = 0;

            foreach (var tileGroup in tilesByTexture)
            {
                var textureWidth  = tileGroup.Key.Width;
                var textureHeight = tileGroup.Key.Height;

                foreach (var tile in tileGroup.Value)
                {
                    var source = tile.Item1;
                    var dest   = tile.Item2;

                    BuildTile(vertexBuffer, ref vertexIndex, textureWidth, textureHeight, source, dest);
                }

                ranges.Add(new TileMeshDraw.DrawRange
                {
                    Texture    = tileGroup.Key,
                    StartIndex = tileCount * IndiciesPerTile,
                    IndexCount = tileGroup.Value.Count * IndiciesPerTile
                });

                tileCount += tileGroup.Value.Count;
            }

            if (tileMeshDraw == null)
            {
                tileMeshDraw = TileMeshDraw.New <TVertex>(graphicsContext.CommandList.GraphicsDevice, layout, vertexBuffer, indexBuffer, ranges);
            }
            else
            {
                tileMeshDraw.VertexBuffer = UpdateVertexBuffer(graphicsContext, tileMeshDraw.VertexBuffer);

                if (updateIndexBuffer)
                {
                    tileMeshDraw.IndexBuffer = UpdateIndexBuffer(graphicsContext, tileMeshDraw.IndexBuffer);
                }
            }

            tilesByTexture.Clear();
        }