From 8edd9de27816437b58349349fcdfbc92677170dd Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 11 Dec 2020 22:19:30 +0000 Subject: [PATCH] Replace ITintableRenderable with IModifyableRenderable. --- OpenRA.Game/Graphics/Animation.cs | 5 +- OpenRA.Game/Graphics/Renderable.cs | 18 +++++- OpenRA.Game/Graphics/SpriteRenderable.cs | 56 ++++++++++++------- .../Graphics/TeslaZapRenderable.cs | 3 +- OpenRA.Mods.Cnc/Traits/Minelayer.cs | 2 +- .../Traits/SupportPowers/ChronoshiftPower.cs | 8 +-- .../Graphics/ModelRenderable.cs | 45 +++++++++++---- OpenRA.Mods.Common/Traits/Buildings/Bridge.cs | 2 +- .../FootprintPlaceBuildingPreview.cs | 2 +- .../Traits/Render/DrawLineToTarget.cs | 2 +- .../Traits/Render/WithParachute.cs | 3 +- .../GrantExternalConditionPower.cs | 2 +- .../Traits/World/EditorCursorLayer.cs | 5 +- .../Traits/World/EditorSelectionLayer.cs | 4 +- .../D2kActorPreviewPlaceBuildingPreview.cs | 2 +- glsl/combined.frag | 14 ++++- 16 files changed, 117 insertions(+), 56 deletions(-) diff --git a/OpenRA.Game/Graphics/Animation.cs b/OpenRA.Game/Graphics/Animation.cs index fd9587568b..e419a1ee9e 100644 --- a/OpenRA.Game/Graphics/Animation.cs +++ b/OpenRA.Game/Graphics/Animation.cs @@ -54,12 +54,13 @@ namespace OpenRA.Graphics public IRenderable[] Render(WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale) { - var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration, CurrentSequence.IgnoreWorldTint); + var tintModifiers = CurrentSequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None; + var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration, tintModifiers); if (CurrentSequence.ShadowStart >= 0) { var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc()); - var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true, CurrentSequence.IgnoreWorldTint); + var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true, tintModifiers); return new IRenderable[] { shadowRenderable, imageRenderable }; } diff --git a/OpenRA.Game/Graphics/Renderable.cs b/OpenRA.Game/Graphics/Renderable.cs index 2497493f13..8935d05a7e 100644 --- a/OpenRA.Game/Graphics/Renderable.cs +++ b/OpenRA.Game/Graphics/Renderable.cs @@ -9,6 +9,7 @@ */ #endregion +using System; using OpenRA.Primitives; namespace OpenRA.Graphics @@ -32,9 +33,22 @@ namespace OpenRA.Graphics IPalettedRenderable WithPalette(PaletteReference newPalette); } - public interface ITintableRenderable + [Flags] + public enum TintModifiers { - IRenderable WithTint(in float3 newTint); + None = 0, + IgnoreWorldTint = 1, + ReplaceColor = 2 + } + + public interface IModifyableRenderable : IRenderable + { + float Alpha { get; } + float3 Tint { get; } + TintModifiers TintModifiers { get; } + + IModifyableRenderable WithAlpha(float newAlpha); + IModifyableRenderable WithTint(in float3 newTint, TintModifiers newTintModifiers); } public interface IFinalizedRenderable diff --git a/OpenRA.Game/Graphics/SpriteRenderable.cs b/OpenRA.Game/Graphics/SpriteRenderable.cs index 2432fe88ed..e81554e6e9 100644 --- a/OpenRA.Game/Graphics/SpriteRenderable.cs +++ b/OpenRA.Game/Graphics/SpriteRenderable.cs @@ -14,7 +14,7 @@ using OpenRA.Primitives; namespace OpenRA.Graphics { - public struct SpriteRenderable : IPalettedRenderable, ITintableRenderable, IFinalizedRenderable + public struct SpriteRenderable : IPalettedRenderable, IModifyableRenderable, IFinalizedRenderable { public static readonly IEnumerable None = new IRenderable[0]; @@ -25,16 +25,17 @@ namespace OpenRA.Graphics readonly PaletteReference palette; readonly float scale; readonly float3 tint; + readonly TintModifiers tintModifiers; + readonly float alpha; readonly bool isDecoration; - readonly bool ignoreWorldTint; public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration) - : this(sprite, pos, offset, zOffset, palette, scale, float3.Ones, isDecoration, false) { } + : this(sprite, pos, offset, zOffset, palette, scale, 1f, float3.Ones, TintModifiers.None, isDecoration) { } - public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration, bool ignoreWorldTint) - : this(sprite, pos, offset, zOffset, palette, scale, float3.Ones, isDecoration, ignoreWorldTint) { } + public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, bool isDecoration, TintModifiers tintModifiers) + : this(sprite, pos, offset, zOffset, palette, scale, 1f, float3.Ones, tintModifiers, isDecoration) { } - public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float3 tint, bool isDecoration, bool ignoreWorldTint) + public SpriteRenderable(Sprite sprite, WPos pos, WVec offset, int zOffset, PaletteReference palette, float scale, float alpha, float3 tint, TintModifiers tintModifiers, bool isDecoration) { this.sprite = sprite; this.pos = pos; @@ -44,7 +45,8 @@ namespace OpenRA.Graphics this.scale = scale; this.tint = tint; this.isDecoration = isDecoration; - this.ignoreWorldTint = ignoreWorldTint; + this.tintModifiers = tintModifiers; + this.alpha = alpha; } public WPos Pos { get { return pos + offset; } } @@ -53,12 +55,24 @@ namespace OpenRA.Graphics public int ZOffset { get { return zOffset; } } public bool IsDecoration { get { return isDecoration; } } - public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, tint, isDecoration, ignoreWorldTint); } - public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, tint, isDecoration, ignoreWorldTint); } - public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, tint, isDecoration, ignoreWorldTint); } - public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, tint, true, ignoreWorldTint); } + public float Alpha { get { return alpha; } } + public float3 Tint { get { return tint; } } + public TintModifiers TintModifiers { get { return tintModifiers; } } - public IRenderable WithTint(in float3 newTint) { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newTint, isDecoration, ignoreWorldTint); } + public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, alpha, tint, tintModifiers, isDecoration); } + public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, alpha, tint, tintModifiers, isDecoration); } + public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, alpha, tint, tintModifiers, isDecoration); } + public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, tint, tintModifiers, true); } + + public IModifyableRenderable WithAlpha(float newAlpha) + { + return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newAlpha, tint, tintModifiers, isDecoration); + } + + public IModifyableRenderable WithTint(in float3 newTint, TintModifiers newTintModifiers) + { + return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, alpha, newTint, newTintModifiers, isDecoration); + } float3 ScreenPosition(WorldRenderer wr) { @@ -72,16 +86,16 @@ namespace OpenRA.Graphics public void Render(WorldRenderer wr) { var wsr = Game.Renderer.WorldSpriteRenderer; - if (ignoreWorldTint) - wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size); - else - { - var t = tint; - if (wr.TerrainLighting != null) - t *= wr.TerrainLighting.TintAt(pos); + var t = alpha * tint; + if (wr.TerrainLighting != null && (tintModifiers & TintModifiers.IgnoreWorldTint) == 0) + t *= wr.TerrainLighting.TintAt(pos); - wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size, t, 1f); - } + // Shader interprets negative alpha as a flag to use the tint colour directly instead of multiplying the sprite colour + var a = alpha; + if ((tintModifiers & TintModifiers.ReplaceColor) != 0) + a *= -1; + + wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size, t, a); } public void RenderDebugGeometry(WorldRenderer wr) diff --git a/OpenRA.Mods.Cnc/Graphics/TeslaZapRenderable.cs b/OpenRA.Mods.Cnc/Graphics/TeslaZapRenderable.cs index 05e60e038c..d4949d27d1 100644 --- a/OpenRA.Mods.Cnc/Graphics/TeslaZapRenderable.cs +++ b/OpenRA.Mods.Cnc/Graphics/TeslaZapRenderable.cs @@ -148,7 +148,8 @@ namespace OpenRA.Mods.Cnc.Graphics .MinBy(t => Math.Abs(float2.Dot(z + new float2(t[0], t[1]), q) + c)); var pos = wr.ProjectedPosition((z + new float2(step[2], step[3])).ToInt2()); - rs.Add(new SpriteRenderable(s.GetSprite(step[4]), pos, WVec.Zero, 0, pal, 1f, true, s.IgnoreWorldTint).PrepareRender(wr)); + var tintModifiers = s.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None; + rs.Add(new SpriteRenderable(s.GetSprite(step[4]), pos, WVec.Zero, 0, pal, 1f, true, tintModifiers).PrepareRender(wr)); z += new float2(step[0], step[1]); if (rs.Count >= 1000) diff --git a/OpenRA.Mods.Cnc/Traits/Minelayer.cs b/OpenRA.Mods.Cnc/Traits/Minelayer.cs index 24eda42640..6d7f8539fd 100644 --- a/OpenRA.Mods.Cnc/Traits/Minelayer.cs +++ b/OpenRA.Mods.Cnc/Traits/Minelayer.cs @@ -287,7 +287,7 @@ namespace OpenRA.Mods.Cnc.Traits || !movement.CanEnterCell(c, null, BlockedByActor.Immovable) || (mobile != null && !mobile.CanStayInCell(c))) tile = tileBlocked; - yield return new SpriteRenderable(tile, world.Map.CenterOfCell(c), WVec.Zero, -511, pal, 1f, true, true); + yield return new SpriteRenderable(tile, world.Map.CenterOfCell(c), WVec.Zero, -511, pal, 1f, true, TintModifiers.IgnoreWorldTint); } } diff --git a/OpenRA.Mods.Cnc/Traits/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.Cnc/Traits/SupportPowers/ChronoshiftPower.cs index 4c8b33e577..993ef21ce7 100644 --- a/OpenRA.Mods.Cnc/Traits/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.Cnc/Traits/SupportPowers/ChronoshiftPower.cs @@ -203,7 +203,7 @@ namespace OpenRA.Mods.Cnc.Traits var tiles = power.CellsMatching(xy, footprint, dimensions); var palette = wr.Palette(((ChronoshiftPowerInfo)power.Info).TargetOverlayPalette); foreach (var t in tiles) - yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, true); + yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); } protected override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) @@ -288,7 +288,7 @@ namespace OpenRA.Mods.Cnc.Traits foreach (var t in power.CellsMatching(sourceLocation, footprint, dimensions)) { var tile = manager.Self.Owner.Shroud.IsExplored(t + delta) ? validTile : invalidTile; - yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t + delta), WVec.Zero, -511, palette, 1f, true, true); + yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t + delta), WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); } // Unit previews @@ -300,7 +300,7 @@ namespace OpenRA.Mods.Cnc.Traits var canEnter = manager.Self.Owner.Shroud.IsExplored(targetCell) && unit.Trait().CanChronoshiftTo(unit, targetCell); var tile = canEnter ? validTile : invalidTile; - yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(targetCell), WVec.Zero, -511, palette, 1f, true, true); + yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(targetCell), WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); } var offset = world.Map.CenterOfCell(xy) - world.Map.CenterOfCell(sourceLocation); @@ -330,7 +330,7 @@ namespace OpenRA.Mods.Cnc.Traits // Source tiles foreach (var t in power.CellsMatching(sourceLocation, footprint, dimensions)) - yield return new SpriteRenderable(sourceTile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, true); + yield return new SpriteRenderable(sourceTile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); } bool IsValidTarget(CPos xy) diff --git a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs index 4ec0bc5f3d..cb151e8c34 100644 --- a/OpenRA.Mods.Common/Graphics/ModelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/ModelRenderable.cs @@ -17,7 +17,7 @@ using OpenRA.Primitives; namespace OpenRA.Mods.Common.Graphics { - public struct ModelRenderable : IPalettedRenderable, ITintableRenderable + public struct ModelRenderable : IPalettedRenderable, IModifyableRenderable { readonly IEnumerable models; readonly WPos pos; @@ -30,7 +30,9 @@ namespace OpenRA.Mods.Common.Graphics readonly PaletteReference normalsPalette; readonly PaletteReference shadowPalette; readonly float scale; + readonly float alpha; readonly float3 tint; + readonly TintModifiers tintModifiers; public ModelRenderable( IEnumerable models, WPos pos, int zOffset, in WRot camera, float scale, @@ -38,14 +40,14 @@ namespace OpenRA.Mods.Common.Graphics PaletteReference color, PaletteReference normals, PaletteReference shadow) : this(models, pos, zOffset, camera, scale, lightSource, lightAmbientColor, lightDiffuseColor, - color, normals, shadow, - float3.Ones) { } + color, normals, shadow, 1f, + float3.Ones, TintModifiers.None) { } public ModelRenderable( IEnumerable models, WPos pos, int zOffset, in WRot camera, float scale, in WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadow, - in float3 tint) + float alpha, in float3 tint, TintModifiers tintModifiers) { this.models = models; this.pos = pos; @@ -58,7 +60,9 @@ namespace OpenRA.Mods.Common.Graphics palette = color; normalsPalette = normals; shadowPalette = shadow; + this.alpha = alpha; this.tint = tint; + this.tintModifiers = tintModifiers; } public WPos Pos { get { return pos; } } @@ -66,12 +70,16 @@ namespace OpenRA.Mods.Common.Graphics public int ZOffset { get { return zOffset; } } public bool IsDecoration { get { return false; } } + public float Alpha { get { return alpha; } } + public float3 Tint { get { return tint; } } + public TintModifiers TintModifiers { get { return tintModifiers; } } + public IPalettedRenderable WithPalette(PaletteReference newPalette) { return new ModelRenderable( models, pos, zOffset, camera, scale, lightSource, lightAmbientColor, lightDiffuseColor, - newPalette, normalsPalette, shadowPalette, tint); + newPalette, normalsPalette, shadowPalette, alpha, tint, tintModifiers); } public IRenderable WithZOffset(int newOffset) @@ -79,7 +87,7 @@ namespace OpenRA.Mods.Common.Graphics return new ModelRenderable( models, pos, newOffset, camera, scale, lightSource, lightAmbientColor, lightDiffuseColor, - palette, normalsPalette, shadowPalette, tint); + palette, normalsPalette, shadowPalette, alpha, tint, tintModifiers); } public IRenderable OffsetBy(WVec vec) @@ -87,17 +95,25 @@ namespace OpenRA.Mods.Common.Graphics return new ModelRenderable( models, pos + vec, zOffset, camera, scale, lightSource, lightAmbientColor, lightDiffuseColor, - palette, normalsPalette, shadowPalette, tint); + palette, normalsPalette, shadowPalette, alpha, tint, tintModifiers); } public IRenderable AsDecoration() { return this; } - public IRenderable WithTint(in float3 newTint) + public IModifyableRenderable WithAlpha(float newAlpha) { return new ModelRenderable( models, pos, zOffset, camera, scale, lightSource, lightAmbientColor, lightDiffuseColor, - palette, normalsPalette, shadowPalette, newTint); + palette, normalsPalette, shadowPalette, newAlpha, tint, tintModifiers); + } + + public IModifyableRenderable WithTint(in float3 newTint, TintModifiers newTintModifiers) + { + return new ModelRenderable( + models, pos, zOffset, camera, scale, + lightSource, lightAmbientColor, lightDiffuseColor, + palette, normalsPalette, shadowPalette, alpha, newTint, newTintModifiers); } // This will need generalizing once we support TS/RA2 terrain @@ -145,11 +161,16 @@ namespace OpenRA.Mods.Common.Graphics var wrsr = Game.Renderer.WorldRgbaSpriteRenderer; var t = model.tint; - if (wr.TerrainLighting != null) + if (wr.TerrainLighting != null && (model.tintModifiers & TintModifiers.IgnoreWorldTint) == 0) t *= wr.TerrainLighting.TintAt(model.pos); - wrsr.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd, t, 1f); - wrsr.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size, renderProxy.Sprite.Size, t, 1f); + // Shader interprets negative alpha as a flag to use the tint colour directly instead of multiplying the sprite colour + var a = model.alpha; + if ((model.tintModifiers & TintModifiers.ReplaceColor) != 0) + a *= -1; + + wrsr.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd, t, a); + wrsr.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size, renderProxy.Sprite.Size, t, a); } public void RenderDebugGeometry(WorldRenderer wr) diff --git a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs index 275efb3816..9263cdafde 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/Bridge.cs @@ -199,7 +199,7 @@ namespace OpenRA.Mods.Common.Traits return footprint.Select(c => (IRenderable)(new SpriteRenderable( wr.Theater.TileSprite(new TerrainTile(template, c.Value)), - wr.World.Map.CenterOfCell(c.Key), WVec.Zero, -offset, palette, 1f, true, false))).ToArray(); + wr.World.Map.CenterOfCell(c.Key), WVec.Zero, -offset, palette, 1f, true))).ToArray(); } bool initialized; diff --git a/OpenRA.Mods.Common/Traits/Buildings/FootprintPlaceBuildingPreview.cs b/OpenRA.Mods.Common/Traits/Buildings/FootprintPlaceBuildingPreview.cs index 6a83edd085..949d21bbb9 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/FootprintPlaceBuildingPreview.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/FootprintPlaceBuildingPreview.cs @@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits var pal = HasFlag(c.Value, PlaceBuildingCellType.LineBuild) ? linePalette : cellPalette; var pos = wr.World.Map.CenterOfCell(c.Key); var offset = new WVec(0, 0, topLeftPos.Z - pos.Z); - yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, true); + yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, TintModifiers.IgnoreWorldTint); } } diff --git a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs index 286368167e..c1216cc805 100644 --- a/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs +++ b/OpenRA.Mods.Common/Traits/Render/DrawLineToTarget.cs @@ -90,7 +90,7 @@ namespace OpenRA.Mods.Common.Traits if (!a.IsCanceling) foreach (var n in a.TargetLineNodes(self)) if (n.Tile != null && n.Target.Type != TargetType.Invalid) - yield return new SpriteRenderable(n.Tile, n.Target.CenterPosition, WVec.Zero, -511, pal, 1f, true, true); + yield return new SpriteRenderable(n.Tile, n.Target.CenterPosition, WVec.Zero, -511, pal, 1f, true, TintModifiers.IgnoreWorldTint); } bool IRenderAboveShroud.SpatiallyPartitionable { get { return false; } } diff --git a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs index 7b0d36f212..b4b0747615 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithParachute.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithParachute.cs @@ -176,7 +176,8 @@ namespace OpenRA.Mods.Common.Traits.Render var dat = self.World.Map.DistanceAboveTerrain(self.CenterPosition); var pos = self.CenterPosition - new WVec(0, 0, dat.Length); var palette = wr.Palette(info.ShadowPalette); - return new IRenderable[] { new SpriteRenderable(shadow.Image, pos, info.ShadowOffset, info.ShadowZOffset, palette, 1, true, shadow.CurrentSequence.IgnoreWorldTint) }; + var tintModifiers = shadow.CurrentSequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None; + return new IRenderable[] { new SpriteRenderable(shadow.Image, pos, info.ShadowOffset, info.ShadowZOffset, palette, 1, true, tintModifiers) }; } IEnumerable IRender.ScreenBounds(Actor self, WorldRenderer wr) diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/GrantExternalConditionPower.cs b/OpenRA.Mods.Common/Traits/SupportPowers/GrantExternalConditionPower.cs index 460dd79c6f..1621cd9ea1 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/GrantExternalConditionPower.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/GrantExternalConditionPower.cs @@ -161,7 +161,7 @@ namespace OpenRA.Mods.Common.Traits var pal = wr.Palette(TileSet.TerrainPaletteInternalName); foreach (var t in power.CellsMatching(xy, footprint, dimensions)) - yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true, true); + yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true, TintModifiers.IgnoreWorldTint); } protected override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) diff --git a/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs index aff10d8da4..fc3d11cac3 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorCursorLayer.cs @@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits var offset = world.Map.Offset(new CVec(x, y), tileInfo.Height); var palette = wr.Palette(TerrainTemplate.Palette ?? TileSet.TerrainPaletteInternalName); - terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, offset, 0, palette, 1, false, false)); + terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, offset, 0, palette, 1, false)); } } } @@ -96,7 +96,8 @@ namespace OpenRA.Mods.Common.Traits var sprite = sequence.GetSprite(Resource.MaxDensity - 1); var palette = wr.Palette(Resource.Palette); - terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, WVec.Zero, 0, palette, 1, false, sequence.IgnoreWorldTint)); + var tintModifiers = sequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None; + terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, WVec.Zero, 0, palette, 1, false, tintModifiers)); } } } diff --git a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs index 6fe1fb3122..52522dd53f 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs @@ -89,12 +89,12 @@ namespace OpenRA.Mods.Common.Traits if (CopyRegion != null) foreach (var c in CopyRegion) yield return new SpriteRenderable(copySprite, wr.World.Map.CenterOfCell(c), - WVec.Zero, -511, palette, 1f, true, true); + WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); if (PasteRegion != null) foreach (var c in PasteRegion) yield return new SpriteRenderable(pasteSprite, wr.World.Map.CenterOfCell(c), - WVec.Zero, -511, palette, 1f, true, true); + WVec.Zero, -511, palette, 1f, true, TintModifiers.IgnoreWorldTint); } bool IRenderAboveShroud.SpatiallyPartitionable { get { return false; } } diff --git a/OpenRA.Mods.D2k/Traits/Buildings/D2kActorPreviewPlaceBuildingPreview.cs b/OpenRA.Mods.D2k/Traits/Buildings/D2kActorPreviewPlaceBuildingPreview.cs index df233d26a1..8829a0ea05 100644 --- a/OpenRA.Mods.D2k/Traits/Buildings/D2kActorPreviewPlaceBuildingPreview.cs +++ b/OpenRA.Mods.D2k/Traits/Buildings/D2kActorPreviewPlaceBuildingPreview.cs @@ -89,7 +89,7 @@ namespace OpenRA.Mods.D2k.Traits var pal = HasFlag(c.Value, PlaceBuildingCellType.LineBuild) ? linePalette : cellPalette; var pos = wr.World.Map.CenterOfCell(c.Key); var offset = new WVec(0, 0, topLeftPos.Z - pos.Z); - yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, true); + yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, TintModifiers.IgnoreWorldTint); } } } diff --git a/glsl/combined.frag b/glsl/combined.frag index 9c868845de..01eb15cf4a 100644 --- a/glsl/combined.frag +++ b/glsl/combined.frag @@ -228,9 +228,17 @@ void main() #endif } else - #if __VERSION__ == 120 - gl_FragColor = c * vTint; + { + // A negative tint alpha indicates that the tint should replace the colour instead of multiplying it + if (vTint.a < 0.0) + c = vec4(vTint.rgb, -vTint.a); + else + c *= vTint; + + #if __VERSION__ == 120 + gl_FragColor = c; #else - fragColor = c * vTint; + fragColor = c; #endif + } }