diff --git a/OpenRA.Game/Graphics/Sprite.cs b/OpenRA.Game/Graphics/Sprite.cs index 4608e5cb75..103c1192ab 100644 --- a/OpenRA.Game/Graphics/Sprite.cs +++ b/OpenRA.Game/Graphics/Sprite.cs @@ -48,6 +48,24 @@ namespace OpenRA.Graphics } } + public class SpriteWithSecondaryData : Sprite + { + public readonly Rectangle SecondaryBounds; + public readonly TextureChannel SecondaryChannel; + public readonly float SecondaryTop, SecondaryLeft, SecondaryBottom, SecondaryRight; + + public SpriteWithSecondaryData(Sprite s, Rectangle secondaryBounds, TextureChannel secondaryChannel) + : base(s.Sheet, s.Bounds, s.ZRamp, s.Offset, s.Channel, s.BlendMode) + { + SecondaryBounds = secondaryBounds; + SecondaryChannel = secondaryChannel; + SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width; + SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height; + SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width; + SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height; + } + } + public enum TextureChannel : byte { Red = 0, diff --git a/OpenRA.Game/Graphics/Theater.cs b/OpenRA.Game/Graphics/Theater.cs index f98ba533a6..543fe7762c 100644 --- a/OpenRA.Game/Graphics/Theater.cs +++ b/OpenRA.Game/Graphics/Theater.cs @@ -43,7 +43,6 @@ namespace OpenRA.Graphics { this.tileset = tileset; var allocated = false; - var type = tileset.EnableDepth ? SheetType.DualIndexed : SheetType.Indexed; Func allocate = () => { @@ -51,10 +50,10 @@ namespace OpenRA.Graphics throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter."); allocated = true; - return new Sheet(type, new Size(tileset.SheetSize, tileset.SheetSize)); + return new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize)); }; - sheetBuilder = new SheetBuilder(type, allocate); + sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate); random = new MersenneTwister(); var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders); @@ -71,10 +70,17 @@ namespace OpenRA.Graphics { var f = allFrames[j]; var s = sheetBuilder.Allocate(f.Size, f.Offset); - Util.FastCopyIntoChannel(s, 0, f.Data); + Util.FastCopyIntoChannel(s, f.Data); if (tileset.EnableDepth) - Util.FastCopyIntoChannel(s, 1, allFrames[j + frameCount].Data); + { + var ss = sheetBuilder.Allocate(f.Size, f.Offset); + Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data); + + // s and ss are guaranteed to use the same sheet + // because of the custom terrain sheet allocation + s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel); + } return s; }).ToArray()); diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 90b28c856d..85e66a1747 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -31,16 +31,28 @@ namespace OpenRA.Graphics public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, float paletteTextureIndex, int nv) { + float sl = 0; + float st = 0; + float sr = 0; + float sb = 0; var attribC = ChannelSelect[(int)r.Channel]; - if (r.Sheet.Type == SheetType.DualIndexed) - attribC *= -1; - vertices[nv] = new Vertex(a, r.Left, r.Top, 0, 0, paletteTextureIndex, attribC); - vertices[nv + 1] = new Vertex(b, r.Right, r.Top, 0, 0, paletteTextureIndex, attribC); - vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, 0, 0, paletteTextureIndex, attribC); - vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, 0, 0, paletteTextureIndex, attribC); - vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, 0, 0, paletteTextureIndex, attribC); - vertices[nv + 5] = new Vertex(a, r.Left, r.Top, 0, 0, paletteTextureIndex, attribC); + var ss = r as SpriteWithSecondaryData; + if (ss != null) + { + sl = ss.SecondaryLeft; + st = ss.SecondaryTop; + sr = ss.SecondaryRight; + sb = ss.SecondaryBottom; + attribC = -(attribC + ChannelSelect[(int)ss.Channel] / 10); + } + + vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC); + vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, attribC); + vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC); + vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC); + vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, attribC); + vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC); } public static void FastCopyIntoChannel(Sprite dest, byte[] src) { FastCopyIntoChannel(dest, 0, src); } diff --git a/glsl/shp.frag b/glsl/shp.frag index 17fba1bb96..b167d55721 100644 --- a/glsl/shp.frag +++ b/glsl/shp.frag @@ -21,8 +21,8 @@ void main() float depth = gl_FragCoord.z; if (length(vDepthMask) > 0.0) { - // Preview vertex aware depth - depth = depth + DepthTextureScale * dot(x, vDepthMask); + vec4 y = texture2D(DiffuseTexture, vTexCoord.pq); + depth = depth + DepthTextureScale * dot(y, vDepthMask); } // Convert to window coords diff --git a/glsl/shp.vert b/glsl/shp.vert index bd1cae3d2e..87c0ca1b62 100644 --- a/glsl/shp.vert +++ b/glsl/shp.vert @@ -11,36 +11,27 @@ varying vec4 vDepthMask; vec4 DecodeChannelMask(float x) { - float y = abs(x); - if (y > 0.7) + if (x > 0.7) return vec4(0,0,0,1); - if (y > 0.5) + if (x > 0.5) return vec4(0,0,1,0); - if (y > 0.3) + if (x > 0.3) return vec4(0,1,0,0); else return vec4(1,0,0,0); } -vec4 DecodeDepthChannelMask(float x) -{ - if (x > 0.0) - return vec4(0,0,0,0); - if (x < -0.7) - return vec4(1,0,0,0); - if (x < -0.5) - return vec4(0,0,0,1); - if (x < -0.3) - return vec4(0,0,1,0); - else - return vec4(0,1,0,0); -} - void main() { gl_Position = vec4((aVertexPosition.xyz - Scroll.xyz) * r1 + r2, 1); vTexCoord = aVertexTexCoord; vTexMetadata = aVertexTexMetadata; - vChannelMask = DecodeChannelMask(aVertexTexMetadata.t); - vDepthMask = DecodeDepthChannelMask(aVertexTexMetadata.t); + vChannelMask = DecodeChannelMask(abs(aVertexTexMetadata.t)); + if (aVertexTexMetadata.t < 0.0) + { + float x = -aVertexTexMetadata.t * 10.0; + vDepthMask = DecodeChannelMask(x - floor(x)); + } + else + vDepthMask = vec4(0,0,0,0); }