Add support for rendering tinted artwork.

This commit is contained in:
Paul Chote
2020-07-09 17:40:14 +01:00
committed by abcdefg30
parent baf58f53b3
commit ac7eda8ca2
29 changed files with 167 additions and 49 deletions

View File

@@ -54,12 +54,12 @@ 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);
var imageRenderable = new SpriteRenderable(Image, pos, offset, CurrentSequence.ZOffset + zOffset, palette, scale, IsDecoration, CurrentSequence.IgnoreWorldTint);
if (CurrentSequence.ShadowStart >= 0)
{
var shadow = CurrentSequence.GetShadow(CurrentFrame, facingFunc());
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true);
var shadowRenderable = new SpriteRenderable(shadow, pos, offset, CurrentSequence.ShadowZOffset + zOffset, palette, scale, true, CurrentSequence.IgnoreWorldTint);
return new IRenderable[] { shadowRenderable, imageRenderable };
}

View File

@@ -28,6 +28,11 @@ namespace OpenRA.Graphics
IFinalizedRenderable PrepareRender(WorldRenderer wr);
}
public interface ITintableRenderable
{
IRenderable WithTint(float3 newTint);
}
public interface IFinalizedRenderable
{
void Render(WorldRenderer wr);

View File

@@ -45,5 +45,21 @@ namespace OpenRA.Graphics
parent.DrawSprite(s, a, b, c, d);
}
public void DrawSpriteWithTint(Sprite s, float3 location, float3 size, float3 tint)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSpriteWithTint(s, location, 0, size, tint);
}
public void DrawSpriteWithTint(Sprite s, float3 a, float3 b, float3 c, float3 d, float3 tint)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSpriteWithTint(s, a, b, c, d, tint);
}
}
}

View File

@@ -32,6 +32,7 @@ namespace OpenRA.Graphics
int ShadowZOffset { get; }
int[] Frames { get; }
Rectangle Bounds { get; }
bool IgnoreWorldTint { get; }
Sprite GetSprite(int frame);
Sprite GetSprite(int frame, WAngle facing);

View File

@@ -14,7 +14,7 @@ using OpenRA.Primitives;
namespace OpenRA.Graphics
{
public struct SpriteRenderable : IRenderable, IFinalizedRenderable
public struct SpriteRenderable : IRenderable, ITintableRenderable, IFinalizedRenderable
{
public static readonly IEnumerable<IRenderable> None = new IRenderable[0];
@@ -24,9 +24,17 @@ namespace OpenRA.Graphics
readonly int zOffset;
readonly PaletteReference palette;
readonly float scale;
readonly float3 tint;
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) { }
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, float3 tint, bool isDecoration, bool ignoreWorldTint)
{
this.sprite = sprite;
this.pos = pos;
@@ -34,7 +42,9 @@ namespace OpenRA.Graphics
this.zOffset = zOffset;
this.palette = palette;
this.scale = scale;
this.tint = tint;
this.isDecoration = isDecoration;
this.ignoreWorldTint = ignoreWorldTint;
}
public WPos Pos { get { return pos + offset; } }
@@ -43,10 +53,12 @@ namespace OpenRA.Graphics
public int ZOffset { get { return zOffset; } }
public bool IsDecoration { get { return isDecoration; } }
public IRenderable WithPalette(PaletteReference newPalette) { return new SpriteRenderable(sprite, pos, offset, zOffset, newPalette, scale, isDecoration); }
public IRenderable WithZOffset(int newOffset) { return new SpriteRenderable(sprite, pos, offset, newOffset, palette, scale, isDecoration); }
public IRenderable OffsetBy(WVec vec) { return new SpriteRenderable(sprite, pos + vec, offset, zOffset, palette, scale, isDecoration); }
public IRenderable AsDecoration() { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, true); }
public IRenderable 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 IRenderable WithTint(float3 newTint) { return new SpriteRenderable(sprite, pos, offset, zOffset, palette, scale, newTint, isDecoration, ignoreWorldTint); }
float3 ScreenPosition(WorldRenderer wr)
{
@@ -59,7 +71,11 @@ namespace OpenRA.Graphics
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr)
{
Game.Renderer.WorldSpriteRenderer.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size);
var wsr = Game.Renderer.WorldSpriteRenderer;
if (ignoreWorldTint)
wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size);
else
wsr.DrawSpriteWithTint(sprite, ScreenPosition(wr), palette, scale * sprite.Size, tint);
}
public void RenderDebugGeometry(WorldRenderer wr)

View File

@@ -107,7 +107,7 @@ namespace OpenRA.Graphics
internal void DrawSprite(Sprite s, float3 location, float paletteTextureIndex, float3 size)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, float3.Ones);
nv += 6;
}
@@ -124,7 +124,26 @@ namespace OpenRA.Graphics
public void DrawSprite(Sprite s, float3 a, float3 b, float3 c, float3 d)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, nv);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, float3.Ones, nv);
nv += 6;
}
internal void DrawSpriteWithTint(Sprite s, float3 location, float paletteTextureIndex, float3 size, float3 tint)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, tint);
nv += 6;
}
public void DrawSpriteWithTint(Sprite s, float3 location, PaletteReference pal, float3 size, float3 tint)
{
DrawSpriteWithTint(s, location, pal.TextureIndex, size, tint);
}
public void DrawSpriteWithTint(Sprite s, float3 a, float3 b, float3 c, float3 d, float3 tint)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, tint, nv);
nv += 6;
}

View File

@@ -59,7 +59,7 @@ namespace OpenRA.Graphics
for (var i = 0; i < vertices.Length; i++)
{
var v = vertices[i];
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C);
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C, new float3(v.R, v.G, v.B));
}
for (var row = 0; row < map.MapSize.Y; row++)
@@ -96,7 +96,7 @@ namespace OpenRA.Graphics
return;
var offset = rowStride * uv.V + 6 * uv.U;
Util.FastCreateQuad(vertices, pos, sprite, int2.Zero, palette.TextureIndex, offset, sprite.Size);
Util.FastCreateQuad(vertices, pos, sprite, int2.Zero, palette.TextureIndex, offset, sprite.Size, float3.Ones);
dirtyRows.Add(uv.V);
}

View File

@@ -20,15 +20,18 @@ namespace OpenRA.Graphics
// yes, our channel order is nuts.
static readonly int[] ChannelMasks = { 2, 1, 0, 3 };
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, float3 size)
public static void FastCreateQuad(Vertex[] vertices, float3 o, Sprite r, int2 samplers, float paletteTextureIndex, int nv, float3 size, float3 tint)
{
var b = new float3(o.X + size.X, o.Y, o.Z);
var c = new float3(o.X + size.X, o.Y + size.Y, o.Z + size.Z);
var d = new float3(o.X, o.Y + size.Y, o.Z + size.Z);
FastCreateQuad(vertices, o, b, c, d, r, samplers, paletteTextureIndex, nv);
FastCreateQuad(vertices, o, b, c, d, r, samplers, paletteTextureIndex, tint, nv);
}
public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, int2 samplers, float paletteTextureIndex, int nv)
public static void FastCreateQuad(Vertex[] vertices,
float3 a, float3 b, float3 c, float3 d,
Sprite r, int2 samplers, float paletteTextureIndex,
float3 tint, int nv)
{
float sl = 0;
float st = 0;
@@ -51,12 +54,12 @@ namespace OpenRA.Graphics
}
var fAttribC = (float)attribC;
vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, fAttribC);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, fAttribC);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC);
vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC, tint);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, fAttribC, tint);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, fAttribC, tint);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, fAttribC, tint);
}
public static void FastCopyIntoChannel(Sprite dest, byte[] src)

View File

@@ -16,17 +16,34 @@ namespace OpenRA.Graphics
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public readonly float X, Y, Z, S, T, U, V, P, C;
// 3d position
public readonly float X, Y, Z;
// Primary and secondary texture coordinates or RGBA color
public readonly float S, T, U, V;
// Palette and channel flags
public readonly float P, C;
// Color tint
public readonly float R, G, B;
public Vertex(float3 xyz, float s, float t, float u, float v, float p, float c)
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c) { }
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c, float3.Ones) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c)
public Vertex(float3 xyz, float s, float t, float u, float v, float p, float c, float3 tint)
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c, tint.X, tint.Y, tint.Z) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c, float3 tint)
: this(x, y, z, s, t, u, v, p, c, tint.X, tint.Y, tint.Z) { }
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c, float r, float g, float b)
{
X = x; Y = y; Z = z;
S = s; T = t;
U = u; V = v;
P = p; C = c;
R = r; G = g; B = b;
}
}
}

View File

@@ -62,5 +62,6 @@ namespace OpenRA
public override string ToString() { return "{0},{1},{2}".F(X, Y, Z); }
public static readonly float3 Zero = new float3(0, 0, 0);
public static readonly float3 Ones = new float3(1, 1, 1);
}
}

View File

@@ -148,7 +148,7 @@ 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).PrepareRender(wr));
rs.Add(new SpriteRenderable(s.GetSprite(step[4]), pos, WVec.Zero, 0, pal, 1f, true, s.IgnoreWorldTint).PrepareRender(wr));
z += new float2(step[0], step[1]);
if (rs.Count >= 1000)

View File

@@ -244,8 +244,7 @@ namespace OpenRA.Mods.Cnc.Traits
else if (!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);
yield return new SpriteRenderable(tile, world.Map.CenterOfCell(c), WVec.Zero, -511, pal, 1f, true, true);
}
}

View File

@@ -205,7 +205,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);
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, true);
}
protected override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi)
@@ -290,7 +290,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);
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t + delta), WVec.Zero, -511, palette, 1f, true, true);
}
// Unit previews
@@ -302,7 +302,7 @@ namespace OpenRA.Mods.Cnc.Traits
var canEnter = manager.Self.Owner.Shroud.IsExplored(targetCell) &&
unit.Trait<Chronoshiftable>().CanChronoshiftTo(unit, targetCell);
var tile = canEnter ? validTile : invalidTile;
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(targetCell), WVec.Zero, -511, palette, 1f, true);
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(targetCell), WVec.Zero, -511, palette, 1f, true, true);
}
var offset = world.Map.CenterOfCell(xy) - world.Map.CenterOfCell(sourceLocation);
@@ -332,7 +332,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);
yield return new SpriteRenderable(sourceTile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, palette, 1f, true, true);
}
bool IsValidTarget(CPos xy)

View File

@@ -112,6 +112,7 @@ namespace OpenRA.Mods.Common.Graphics
public int ShadowZOffset { get; private set; }
public int[] Frames { get; private set; }
public Rectangle Bounds { get; private set; }
public bool IgnoreWorldTint { get; private set; }
public readonly uint[] EmbeddedPalette;
@@ -156,6 +157,7 @@ namespace OpenRA.Mods.Common.Graphics
Tick = LoadField(d, "Tick", 40);
transpose = LoadField(d, "Transpose", false);
Frames = LoadField<int[]>(d, "Frames", null);
IgnoreWorldTint = LoadField(d, "IgnoreWorldTint", false);
var flipX = LoadField(d, "FlipX", false);
var flipY = LoadField(d, "FlipY", false);

View File

@@ -17,7 +17,7 @@ using OpenRA.Primitives;
namespace OpenRA.Mods.Common.Graphics
{
public struct ModelRenderable : IRenderable
public struct ModelRenderable : IRenderable, ITintableRenderable
{
readonly IEnumerable<ModelAnimation> models;
readonly WPos pos;
@@ -30,11 +30,22 @@ namespace OpenRA.Mods.Common.Graphics
readonly PaletteReference normalsPalette;
readonly PaletteReference shadowPalette;
readonly float scale;
readonly float3 tint;
public ModelRenderable(
IEnumerable<ModelAnimation> models, WPos pos, int zOffset, WRot camera, float scale,
WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
PaletteReference color, PaletteReference normals, PaletteReference shadow)
: this(models, pos, zOffset, camera, scale,
lightSource, lightAmbientColor, lightDiffuseColor,
color, normals, shadow,
float3.Ones) { }
public ModelRenderable(
IEnumerable<ModelAnimation> models, WPos pos, int zOffset, WRot camera, float scale,
WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor,
PaletteReference color, PaletteReference normals, PaletteReference shadow,
float3 tint)
{
this.models = models;
this.pos = pos;
@@ -47,6 +58,7 @@ namespace OpenRA.Mods.Common.Graphics
palette = color;
normalsPalette = normals;
shadowPalette = shadow;
this.tint = tint;
}
public WPos Pos { get { return pos; } }
@@ -59,7 +71,7 @@ namespace OpenRA.Mods.Common.Graphics
return new ModelRenderable(
models, pos, zOffset, camera, scale,
lightSource, lightAmbientColor, lightDiffuseColor,
newPalette, normalsPalette, shadowPalette);
newPalette, normalsPalette, shadowPalette, tint);
}
public IRenderable WithZOffset(int newOffset)
@@ -67,7 +79,7 @@ namespace OpenRA.Mods.Common.Graphics
return new ModelRenderable(
models, pos, newOffset, camera, scale,
lightSource, lightAmbientColor, lightDiffuseColor,
palette, normalsPalette, shadowPalette);
palette, normalsPalette, shadowPalette, tint);
}
public IRenderable OffsetBy(WVec vec)
@@ -75,11 +87,19 @@ namespace OpenRA.Mods.Common.Graphics
return new ModelRenderable(
models, pos + vec, zOffset, camera, scale,
lightSource, lightAmbientColor, lightDiffuseColor,
palette, normalsPalette, shadowPalette);
palette, normalsPalette, shadowPalette, tint);
}
public IRenderable AsDecoration() { return this; }
public IRenderable WithTint(float3 newTint)
{
return new ModelRenderable(
models, pos, zOffset, camera, scale,
lightSource, lightAmbientColor, lightDiffuseColor,
palette, normalsPalette, shadowPalette, newTint);
}
// This will need generalizing once we support TS/RA2 terrain
static readonly float[] GroundNormal = new float[] { 0, 0, 1, 1 };
public IFinalizedRenderable PrepareRender(WorldRenderer wr)
@@ -122,8 +142,11 @@ namespace OpenRA.Mods.Common.Graphics
var sb = shadowOrigin + psb[2];
var sc = shadowOrigin + psb[1];
var sd = shadowOrigin + psb[3];
Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd);
Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size);
var wrsr = Game.Renderer.WorldRgbaSpriteRenderer;
var ti = model.tint;
wrsr.DrawSpriteWithTint(renderProxy.ShadowSprite, sa, sb, sc, sd, ti);
wrsr.DrawSpriteWithTint(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size, renderProxy.Sprite.Size, ti);
}
public void RenderDebugGeometry(WorldRenderer wr)

View File

@@ -200,7 +200,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))).ToArray();
wr.World.Map.CenterOfCell(c.Key), WVec.Zero, -offset, palette, 1f, true, false))).ToArray();
}
bool initialized;

View File

@@ -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);
yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, true);
}
}

View File

@@ -80,7 +80,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);
yield return new SpriteRenderable(n.Tile, n.Target.CenterPosition, WVec.Zero, -511, pal, 1f, true, true);
}
bool IRenderAboveShroud.SpatiallyPartitionable { get { return false; } }

View File

@@ -177,7 +177,7 @@ 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) };
return new IRenderable[] { new SpriteRenderable(shadow.Image, pos, info.ShadowOffset, info.ShadowZOffset, palette, 1, true, shadow.CurrentSequence.IgnoreWorldTint) };
}
IEnumerable<Rectangle> IRender.ScreenBounds(Actor self, WorldRenderer wr)

View File

@@ -167,7 +167,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);
yield return new SpriteRenderable(tile, wr.World.Map.CenterOfCell(t), WVec.Zero, -511, pal, 1f, true, true);
}
protected override string GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi)

View File

@@ -88,7 +88,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));
terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, offset, 0, palette, 1, false, false));
}
}
}
@@ -99,7 +99,7 @@ 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));
terrainOrResourcePreview.Add(new SpriteRenderable(sprite, pos, WVec.Zero, 0, palette, 1, false, sequence.IgnoreWorldTint));
}
}
}

View File

@@ -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);
WVec.Zero, -511, palette, 1f, true, true);
if (PasteRegion != null)
foreach (var c in PasteRegion)
yield return new SpriteRenderable(pasteSprite, wr.World.Map.CenterOfCell(c),
WVec.Zero, -511, palette, 1f, true);
WVec.Zero, -511, palette, 1f, true, true);
}
bool IRenderAboveShroud.SpatiallyPartitionable { get { return false; } }

View File

@@ -82,7 +82,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);
yield return new SpriteRenderable(tile, pos, offset, -511, pal, 1f, true, true);
}
}
}

View File

@@ -53,6 +53,8 @@ namespace OpenRA.Platforms.Default
OpenGL.CheckGLError();
OpenGL.glEnableVertexAttribArray(Shader.TexMetadataAttributeIndex);
OpenGL.CheckGLError();
OpenGL.glEnableVertexAttribArray(Shader.TintAttributeIndex);
OpenGL.CheckGLError();
}
public IVertexBuffer<Vertex> CreateVertexBuffer(int size)

View File

@@ -21,6 +21,7 @@ namespace OpenRA.Platforms.Default
public const int VertexPosAttributeIndex = 0;
public const int TexCoordAttributeIndex = 1;
public const int TexMetadataAttributeIndex = 2;
public const int TintAttributeIndex = 3;
readonly Dictionary<string, int> samplers = new Dictionary<string, int>();
readonly Dictionary<int, int> legacySizeUniforms = new Dictionary<int, int>();
@@ -83,6 +84,8 @@ namespace OpenRA.Platforms.Default
OpenGL.CheckGLError();
OpenGL.glBindAttribLocation(program, TexMetadataAttributeIndex, "aVertexTexMetadata");
OpenGL.CheckGLError();
OpenGL.glBindAttribLocation(program, TintAttributeIndex, "aVertexTint");
OpenGL.CheckGLError();
if (OpenGL.Profile != GLProfile.Legacy)
{

View File

@@ -101,6 +101,8 @@ namespace OpenRA.Platforms.Default
OpenGL.CheckGLError();
OpenGL.glVertexAttribPointer(Shader.TexMetadataAttributeIndex, 2, OpenGL.GL_FLOAT, false, VertexSize, new IntPtr(28));
OpenGL.CheckGLError();
OpenGL.glVertexAttribPointer(Shader.TintAttributeIndex, 3, OpenGL.GL_FLOAT, false, VertexSize, new IntPtr(36));
OpenGL.CheckGLError();
}
public void Dispose()

View File

@@ -26,6 +26,7 @@ varying vec2 vTexSampler;
varying vec4 vColorFraction;
varying vec4 vRGBAFraction;
varying vec4 vPalettedFraction;
varying vec4 vTint;
uniform vec2 Texture0Size;
uniform vec2 Texture1Size;
@@ -46,6 +47,7 @@ in vec2 vTexSampler;
in vec4 vColorFraction;
in vec4 vRGBAFraction;
in vec4 vPalettedFraction;
in vec4 vTint;
out vec4 fragColor;
#endif
@@ -227,8 +229,8 @@ void main()
}
else
#if __VERSION__ == 120
gl_FragColor = c;
gl_FragColor = c * vTint;
#else
fragColor = c;
fragColor = c * vTint;
#endif
}

View File

@@ -7,6 +7,7 @@ uniform vec3 r1, r2;
attribute vec4 aVertexPosition;
attribute vec4 aVertexTexCoord;
attribute vec2 aVertexTexMetadata;
attribute vec3 aVertexTint;
varying vec4 vTexCoord;
varying vec2 vTexMetadata;
@@ -17,10 +18,12 @@ varying vec2 vTexSampler;
varying vec4 vColorFraction;
varying vec4 vRGBAFraction;
varying vec4 vPalettedFraction;
varying vec4 vTint;
#else
in vec4 aVertexPosition;
in vec4 aVertexTexCoord;
in vec2 aVertexTexMetadata;
in vec3 aVertexTint;
out vec4 vTexCoord;
out vec2 vTexMetadata;
@@ -31,6 +34,7 @@ out vec2 vTexSampler;
out vec4 vColorFraction;
out vec4 vRGBAFraction;
out vec4 vPalettedFraction;
out vec4 vTint;
#endif
vec4 UnpackChannelAttributes(float x)
@@ -123,4 +127,5 @@ void main()
vPalettedFraction = SelectPalettedFraction(attrib.s);
vDepthMask = SelectChannelMask(attrib.t);
vTexSampler = attrib.pq;
vTint = vec4(aVertexTint, 1.0);
}

View File

@@ -7,6 +7,7 @@ uniform mat4 TransformMatrix;
attribute vec4 aVertexPosition;
attribute vec4 aVertexTexCoord;
attribute vec2 aVertexTexMetadata;
attribute vec3 aVertexTint;
varying vec4 vTexCoord;
varying vec4 vChannelMask;
varying vec4 vNormalsMask;
@@ -14,6 +15,7 @@ varying vec4 vNormalsMask;
in vec4 aVertexPosition;
in vec4 aVertexTexCoord;
in vec2 aVertexTexMetadata;
in vec3 aVertexTint;
out vec4 vTexCoord;
out vec4 vChannelMask;
out vec4 vNormalsMask;