1 #region Copyright & License Information
2 /*
3  * Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
4  * This file is part of OpenRA, which is free software. It is made
5  * available to you under the terms of the GNU General Public License
6  * as published by the Free Software Foundation, either version 3 of
7  * the License, or (at your option) any later version. For more
8  * information, see COPYING.
9  */
10 #endregion
11 
12 using System.Collections.Generic;
13 using OpenRA.Primitives;
14 
15 namespace OpenRA.Graphics
16 {
17 	public struct SpriteRenderable : IRenderable, IFinalizedRenderable
18 	{
19 		public static readonly IEnumerable<IRenderable> None = new IRenderable[0];
20 
21 		readonly Sprite sprite;
22 		readonly WPos pos;
23 		readonly WVec offset;
24 		readonly int zOffset;
25 		readonly PaletteReference palette;
26 		readonly float scale;
27 		readonly bool isDecoration;
28 
SpriteRenderableOpenRA.Graphics.SpriteRenderable29 		public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration)
30 		{
31 			this.sprite = sprite;
32 			this.pos = pos;
33 			this.offset = offset;
34 			this.zOffset = zOffset;
35 			this.palette = palette;
36 			this.scale = scale;
37 			this.isDecoration = isDecoration;
38 		}
39 
40 		public WPos Pos { get { return pos + offset; } }
41 		public WVec Offset { get { return offset; } }
42 		public PaletteReference Palette { get { return palette; } }
43 		public int ZOffset { get { return zOffset; } }
44 		public bool IsDecoration { get { return isDecoration; } }
45 
WithPaletteOpenRA.Graphics.SpriteRenderable46 		public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, isDecoration); }
WithZOffsetOpenRA.Graphics.SpriteRenderable47 		public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, isDecoration); }
OffsetByOpenRA.Graphics.SpriteRenderable48 		public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, isDecoration); }
AsDecorationOpenRA.Graphics.SpriteRenderable49 		public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, true); }
50 
ScreenPositionOpenRA.Graphics.SpriteRenderable51 		float3 ScreenPosition(WorldRenderer wr)
52 		{
53 			var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f * scale * sprite.Size.XY).ToInt2();
54 
55 			// HACK: The z offset needs to be applied somewhere, but this probably is the wrong place.
56 			return new float3(xy, sprite.Offset.Z + wr.ScreenZPosition(pos, 0) - 0.5f * scale * sprite.Size.Z);
57 		}
58 
PrepareRenderOpenRA.Graphics.SpriteRenderable59 		public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
RenderOpenRA.Graphics.SpriteRenderable60 		public void Render(WorldRenderer wr)
61 		{
62 			Game.Renderer.WorldSpriteRenderer.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size);
63 		}
64 
RenderDebugGeometryOpenRA.Graphics.SpriteRenderable65 		public void RenderDebugGeometry(WorldRenderer wr)
66 		{
67 			var pos = ScreenPosition(wr) + sprite.Offset;
68 			var tl = wr.Viewport.WorldToViewPx(pos);
69 			var br = wr.Viewport.WorldToViewPx(pos + sprite.Size);
70 			Game.Renderer.RgbaColorRenderer.DrawRect(tl, br, 1, Color.Red);
71 		}
72 
ScreenBoundsOpenRA.Graphics.SpriteRenderable73 		public Rectangle ScreenBounds(WorldRenderer wr)
74 		{
75 			var screenOffset = ScreenPosition(wr) + sprite.Offset;
76 			return new Rectangle((int)screenOffset.X, (int)screenOffset.Y, (int)sprite.Size.X, (int)sprite.Size.Y);
77 		}
78 	}
79 }
80