public TerrainSpriteLayer(World world, WorldRenderer wr, Sheet sheet, BlendMode blendMode, PaletteReference palette, bool restrictToBounds)
        {
            worldRenderer = wr;
            this.restrictToBounds = restrictToBounds;
            Sheet = sheet;
            BlendMode = blendMode;
            paletteIndex = palette.TextureIndex;

            map = world.Map;
            rowStride = 4 * map.MapSize.X;

            vertices = new Vertex[rowStride * map.MapSize.Y];
            vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
            emptySprite = new Sprite(sheet, Rectangle.Empty, TextureChannel.Alpha);

            wr.PaletteInvalidated += () =>
            {
                paletteIndex = palette.TextureIndex;

                // Everything in the layer uses the same palette,
                // so we can fix the indices in one pass
                for (var i = 0; i < vertices.Length; i++)
                {
                    var v = vertices[i];
                    vertices[i] = new Vertex(v.X, v.Y, v.Z, v.U, v.V, paletteIndex, v.C);
                }

                for (var row = 0; row < map.MapSize.Y; row++)
                    dirtyRows.Add(row);
            };
        }
Beispiel #2
0
 public static void FastCreateQuad(Vertex[] vertices, float2 o, Sprite r, int palette, int nv, float2 size)
 {
     var b = new float2(o.X + size.X, o.Y);
     var c = new float2(o.X + size.X, o.Y + size.Y);
     var d = new float2(o.X, o.Y + size.Y);
     FastCreateQuad(vertices, o, b, c, d, r, palette, nv);
 }
Beispiel #3
0
        public void DrawLine(float2 start, float2 end, float width, Color startColor, Color endColor)
        {
            renderer.CurrentBatchRenderer = this;

            if (nv + 6 > renderer.TempBufferSize)
                Flush();

            var delta = (end - start) / (end - start).Length;
            var corner = width / 2 * new float2(-delta.Y, delta.X);

            startColor = Util.PremultiplyAlpha(startColor);
            var sr = startColor.R / 255.0f;
            var sg = startColor.G / 255.0f;
            var sb = startColor.B / 255.0f;
            var sa = startColor.A / 255.0f;

            endColor = Util.PremultiplyAlpha(endColor);
            var er = endColor.R / 255.0f;
            var eg = endColor.G / 255.0f;
            var eb = endColor.B / 255.0f;
            var ea = endColor.A / 255.0f;

            vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa);
            vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa);
            vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea);
            vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea);
            vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea);
            vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa);
        }
Beispiel #4
0
		public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, int palette, int nv)
		{
			var attrib = new float2(palette / (float)HardwarePalette.MaxPalettes, channelSelect[(int)r.channel]);

			vertices[nv] = new Vertex(a, r.FastMapTextureCoords(0), attrib);
			vertices[nv + 1] = new Vertex(b, r.FastMapTextureCoords(1), attrib);
			vertices[nv + 2] = new Vertex(c, r.FastMapTextureCoords(3), attrib);
			vertices[nv + 3] = new Vertex(d, r.FastMapTextureCoords(2), attrib);
		}
Beispiel #5
0
        public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, int palette, int nv)
        {
            var attribP = palette / (float)HardwarePalette.MaxPalettes;
            var attribC = channelSelect[(int)r.channel];

            vertices[nv] = new Vertex(a, r.left, r.top, attribP, attribC);
            vertices[nv + 1] = new Vertex(b, r.right, r.top, attribP, attribC);
            vertices[nv + 2] = new Vertex(c, r.right, r.bottom, attribP, attribC);
            vertices[nv + 3] = new Vertex(d, r.left, r.bottom, attribP, attribC);
        }
Beispiel #6
0
		public static void FastCreateQuad(Vertex[] vertices, float2 a, float2 b, float2 c, float2 d, Sprite r, float paletteTextureIndex, int nv)
		{
			var attribC = ChannelSelect[(int)r.Channel];
			if (r.Sheet.Type == SheetType.DualIndexed)
				attribC *= -1;

			vertices[nv] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC);
			vertices[nv + 1] = new Vertex(b, r.Right, r.Top, paletteTextureIndex, attribC);
			vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC);
			vertices[nv + 3] = new Vertex(d, r.Left, r.Bottom, paletteTextureIndex, attribC);
		}
Beispiel #7
0
		void UpdatePaletteIndices()
		{
			// Everything in the layer uses the same palette,
			// so we can fix the indices in one pass
			for (var i = 0; i < vertices.Length; i++)
			{
				var v = vertices[i];
				vertices[i] = new Vertex(v.X, v.Y, v.Z, v.U, v.V, palette.TextureIndex, v.C);
			}

			for (var row = 0; row < map.MapSize.Y; row++)
				dirtyRows.Add(row);
		}
Beispiel #8
0
		public void FillRect(RectangleF r, Color color)
		{
			Renderer.CurrentBatchRenderer = this;

			if (nv + 4 > Renderer.TempBufferSize)
				Flush();

			vertices[nv] = new Vertex(new float2(r.Left, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
			vertices[nv + 1] = new Vertex(new float2(r.Right, r.Top), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
			vertices[nv + 2] = new Vertex(new float2(r.Right, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));
			vertices[nv + 3] = new Vertex(new float2(r.Left, r.Bottom), new float2(color.R / 255.0f, color.G / 255.0f), new float2(color.B / 255.0f, color.A / 255.0f));

			nv += 4;
		}
Beispiel #9
0
        public void DrawLine(float2 start, float2 end, Color color)
        {
            renderer.CurrentBatchRenderer = this;

            if (nv + 2 > renderer.TempBufferSize)
                Flush();

            color = Util.PremultiplyAlpha(color);
            var r = color.R / 255.0f;
            var g = color.G / 255.0f;
            var b = color.B / 255.0f;
            var a = color.A / 255.0f;
            vertices[nv++] = new Vertex(start + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(end + Offset, r, g, b, a);
        }
Beispiel #10
0
		public void DrawLine(float2 start, float2 end, Color startColor, Color endColor)
		{
			Renderer.CurrentBatchRenderer = this;

			if (nv + 2 > Renderer.TempBufferSize)
				Flush();

			vertices[nv++] = new Vertex(start + offset,
				new float2(startColor.R / 255.0f, startColor.G / 255.0f),
				new float2(startColor.B / 255.0f, startColor.A / 255.0f));

			vertices[nv++] = new Vertex(end + offset,
				new float2(endColor.R / 255.0f, endColor.G / 255.0f),
				new float2(endColor.B / 255.0f, endColor.A / 255.0f));
		}
Beispiel #11
0
        public void FillRect(RectangleF rect, Color color)
        {
            Renderer.CurrentBatchRenderer = this;

            if (nv + 4 > Renderer.TempBufferSize)
                Flush();

            var r = color.R / 255.0f;
            var g = color.G / 255.0f;
            var b = color.B / 255.0f;
            var a = color.A / 255.0f;
            vertices[nv] = new Vertex(new float2(rect.Left, rect.Top), r, g, b, a);
            vertices[nv + 1] = new Vertex(new float2(rect.Right, rect.Top), r, g, b, a);
            vertices[nv + 2] = new Vertex(new float2(rect.Right, rect.Bottom), r, g, b, a);
            vertices[nv + 3] = new Vertex(new float2(rect.Left, rect.Bottom), r, g, b, a);

            nv += 4;
        }
Beispiel #12
0
		public TerrainRenderer(World world, WorldRenderer wr)
		{
			this.world = world;
			this.map = world.Map;

			var terrainPalette = wr.Palette("terrain").Index;
			var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width];
			var nv = 0;

			foreach (var cell in map.Cells)
			{
				var tile = wr.Theater.TileSprite(map.MapTiles.Value[cell]);
				var pos = wr.ScreenPosition(map.CenterOfCell(cell)) - 0.5f * tile.size;
				Util.FastCreateQuad(vertices, pos, tile, terrainPalette, nv, tile.size);
				nv += 4;
			}

			vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
			vertexBuffer.SetData(vertices, nv);
		}
Beispiel #13
0
        public TerrainRenderer(World world, WorldRenderer wr)
        {
            this.world = world;
            this.map = world.Map;

            var terrainPalette = wr.Palette("terrain").Index;
            var vertices = new Vertex[4 * map.Bounds.Height * map.Bounds.Width];
            int nv = 0;

            for (var j = map.Bounds.Top; j < map.Bounds.Bottom; j++)
            {
                for (var i = map.Bounds.Left; i < map.Bounds.Right; i++)
                {
                    var tile = wr.Theater.TileSprite(map.MapTiles.Value[i, j]);
                    var pos = wr.ScreenPosition(new CPos(i, j).CenterPosition) - 0.5f * tile.size;
                    Util.FastCreateQuad(vertices, pos, tile, terrainPalette, nv, tile.size);
                    nv += 4;
                }
            }

            vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length);
            vertexBuffer.SetData(vertices, nv);
        }
Beispiel #14
0
        public void FillRect(float2 a, float2 b, float2 c, float2 d, Color color)
        {
            renderer.CurrentBatchRenderer = this;

            if (nv + 6 > renderer.TempBufferSize)
                Flush();

            color = Util.PremultiplyAlpha(color);
            var cr = color.R / 255.0f;
            var cg = color.G / 255.0f;
            var cb = color.B / 255.0f;
            var ca = color.A / 255.0f;

            vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca);
            vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca);
            vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca);
            vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca);
            vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca);
            vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca);
        }
Beispiel #15
0
        public void DrawLineStrip(IEnumerable<float2> points, Color color)
        {
            renderer.CurrentBatchRenderer = this;

            color = Util.PremultiplyAlpha(color);
            var r = color.R / 255.0f;
            var g = color.G / 255.0f;
            var b = color.B / 255.0f;
            var a = color.A / 255.0f;

            var first = true;
            var prev = new Vertex();
            foreach (var point in points)
            {
                if (first)
                {
                    first = false;
                    prev = new Vertex(point + Offset, r, g, b, a);
                    continue;
                }

                if (nv + 2 > renderer.TempBufferSize)
                    Flush();

                vertices[nv++] = prev;
                prev = new Vertex(point + Offset, r, g, b, a);
                vertices[nv++] = prev;
            }
        }
Beispiel #16
0
        public void DrawLine(float2 start, float2 end, float width, Color color)
        {
            renderer.CurrentBatchRenderer = this;

            if (nv + 6 > renderer.TempBufferSize)
                Flush();

            var delta = (end - start) / (end - start).Length;
            var corner = width / 2 * new float2(-delta.Y, delta.X);

            color = Util.PremultiplyAlpha(color);
            var r = color.R / 255.0f;
            var g = color.G / 255.0f;
            var b = color.B / 255.0f;
            var a = color.A / 255.0f;

            vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a);
            vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a);
        }
Beispiel #17
0
        Sprite CacheTile(MPos uv, int offset, Edges edges, TileInfo tileInfo,
			Sprite[] sprites, Vertex[] vertices, PaletteReference palette, CellLayer<Sprite> spriteLayer)
        {
            var sprite = GetSprite(sprites, edges, tileInfo.Variant);
            if (sprite != null)
            {
                var size = sprite.Size;
                var location = tileInfo.ScreenPosition - 0.5f * size;
                OpenRA.Graphics.Util.FastCreateQuad(
                    vertices, location + sprite.FractionalOffset * size,
                    sprite, palette.TextureIndex, offset, size);
            }

            spriteLayer[uv] = sprite;
            return sprite;
        }
Beispiel #18
0
 void RenderCachedTile(Sprite sprite, Vertex[] vertices, int offset)
 {
     if (sprite != null)
         Game.Renderer.WorldSpriteRenderer.DrawSprite(sprite, vertices, offset);
 }
Beispiel #19
0
 void GenerateTileVertices(Vertex[] vertices, int offset, CPos cell)
 {
     var tile = theater.TileSprite(mapTiles[cell]);
     var pos = worldRenderer.ScreenPosition(map.CenterOfCell(cell)) + tile.Offset - 0.5f * tile.Size;
     Util.FastCreateQuad(vertices, pos, tile, terrainPaletteIndex, offset, tile.Size);
 }
Beispiel #20
0
        void UpdateMap()
        {
            var nv = 0;
            var vertices = new Vertex[rowStride * map.Bounds.Height];
            foreach (var cell in map.Cells)
            {
                GenerateTileVertices(vertices, nv, cell);
                nv += 4;
            }

            vertexBuffer.SetData(vertices, nv);
        }
Beispiel #21
0
        void DrawConnectedLine(float2[] points, float width, Color color, bool closed)
        {
            // Not a line
            if (points.Length < 2)
                return;

            // Single segment
            if (points.Length == 2)
            {
                DrawLine(points[0], points[1], width, color);
                return;
            }

            renderer.CurrentBatchRenderer = this;
            color = Util.PremultiplyAlpha(color);
            var r = color.R / 255.0f;
            var g = color.G / 255.0f;
            var b = color.B / 255.0f;
            var a = color.A / 255.0f;

            var start = points[0];
            var end = points[1];
            var dir = (end - start) / (end - start).Length;
            var corner = width / 2 * new float2(-dir.Y, dir.X);

            // Corners for start of line segment
            var ca = start - corner;
            var cb = start + corner;

            // Segment is part of closed loop
            if (closed)
            {
                var prev = points[points.Length - 1];
                var prevDir = (start - prev) / (start - prev).Length;
                var prevCorner = width / 2 * new float2(-prevDir.Y, prevDir.X);
                ca = IntersectionOf(start - prevCorner, prevDir, start - corner, dir);
                cb = IntersectionOf(start + prevCorner, prevDir, start + corner, dir);
            }

            var limit = closed ? points.Length : points.Length - 1;
            for (var i = 0; i < limit; i++)
            {
                var next = points[(i + 2) % points.Length];
                var nextDir = (next - end) / (next - end).Length;
                var nextCorner = width / 2 * new float2(-nextDir.Y, nextDir.X);

                // Vertices for the corners joining start-end to end-next
                var cc = closed || i < limit ? IntersectionOf(end + corner, dir, end + nextCorner, nextDir) : end + corner;
                var cd = closed || i < limit ? IntersectionOf(end - corner, dir, end - nextCorner, nextDir) : end - corner;

                // Fill segment
                if (nv + 6 > renderer.TempBufferSize)
                    Flush();

                vertices[nv++] = new Vertex(ca + Offset, r, g, b, a);
                vertices[nv++] = new Vertex(cb + Offset, r, g, b, a);
                vertices[nv++] = new Vertex(cc + Offset, r, g, b, a);
                vertices[nv++] = new Vertex(cc + Offset, r, g, b, a);
                vertices[nv++] = new Vertex(cd + Offset, r, g, b, a);
                vertices[nv++] = new Vertex(ca + Offset, r, g, b, a);

                // Advance line segment
                end = next;
                dir = nextDir;
                corner = nextCorner;

                ca = cd;
                cb = cc;
            }
        }
Beispiel #22
0
 public void DrawSprite(Sprite s, Vertex[] sourceVertices, int offset)
 {
     SetRenderStateForSprite(s);
     Array.Copy(sourceVertices, offset, vertices, nv, 6);
     nv += 6;
 }
Beispiel #23
0
        void RenderDirtyTile(MPos uv, int offset, Func<MPos, bool> isVisible,
			Sprite[] sprites, Vertex[] vertices, PaletteReference palette, CellLayer<Sprite> spriteLayer)
        {
            var tile = tileInfos[uv];
            var edges = GetEdges(uv, isVisible);
            var sprite = CacheTile(uv, offset, edges, tile, sprites, vertices, palette, spriteLayer);
            RenderCachedTile(sprite, vertices, offset);
        }
Beispiel #24
0
        public ShroudRenderer(World world, ShroudRendererInfo info)
        {
            if (info.ShroudVariants.Length != info.FogVariants.Length)
                throw new ArgumentException("ShroudRenderer must define the same number of shroud and fog variants!", "info");

            if ((info.OverrideFullFog == null) ^ (info.OverrideFullShroud == null))
                throw new ArgumentException("ShroudRenderer cannot define overrides for only one of shroud or fog!", "info");

            if (info.ShroudVariants.Length > byte.MaxValue)
                throw new ArgumentException("ShroudRenderer cannot define this many shroud and fog variants.", "info");

            if (info.Index.Length >= byte.MaxValue)
                throw new ArgumentException("ShroudRenderer cannot define this many indexes for shroud directions.", "info");

            this.info = info;
            map = world.Map;

            tileInfos = new CellLayer<TileInfo>(map);
            shroudDirty = new CellLayer<bool>(map);
            cellsDirty = new HashSet<CPos>();
            cellsAndNeighborsDirty = new HashSet<CPos>();
            var verticesLength = map.MapSize.X * map.MapSize.Y * 4;
            fogVertices = new Vertex[verticesLength];
            shroudVertices = new Vertex[verticesLength];
            fogSpriteLayer = new CellLayer<Sprite>(map);
            shroudSpriteLayer = new CellLayer<Sprite>(map);

            // Load sprite variants
            var variantCount = info.ShroudVariants.Length;
            variantStride = (byte)(info.Index.Length + (info.OverrideFullShroud != null ? 1 : 0));
            shroudSprites = new Sprite[variantCount * variantStride];
            fogSprites = new Sprite[variantCount * variantStride];

            for (var j = 0; j < variantCount; j++)
            {
                var shroud = map.SequenceProvider.GetSequence(info.Sequence, info.ShroudVariants[j]);
                var fog = map.SequenceProvider.GetSequence(info.Sequence, info.FogVariants[j]);
                for (var i = 0; i < info.Index.Length; i++)
                {
                    shroudSprites[j * variantStride + i] = shroud.GetSprite(i);
                    fogSprites[j * variantStride + i] = fog.GetSprite(i);
                }

                if (info.OverrideFullShroud != null)
                {
                    var i = (j + 1) * variantStride - 1;
                    shroudSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullShroud).GetSprite(0);
                    fogSprites[i] = map.SequenceProvider.GetSequence(info.Sequence, info.OverrideFullFog).GetSprite(0);
                }
            }

            // Mapping of shrouded directions -> sprite index
            edgesToSpriteIndexOffset = new byte[(byte)(info.UseExtendedIndex ? Edges.All : Edges.AllCorners) + 1];
            for (var i = 0; i < info.Index.Length; i++)
                edgesToSpriteIndexOffset[info.Index[i]] = (byte)i;

            if (info.OverrideFullShroud != null)
                edgesToSpriteIndexOffset[info.OverrideShroudIndex] = (byte)(variantStride - 1);

            notVisibleEdges = info.UseExtendedIndex ? Edges.AllSides : Edges.AllCorners;
        }