diff --git a/OpenRA.Game/Graphics/VoxelRenderer.cs b/OpenRA.Game/Graphics/VoxelRenderer.cs index 44c6c89a12..8c373b5c15 100644 --- a/OpenRA.Game/Graphics/VoxelRenderer.cs +++ b/OpenRA.Game/Graphics/VoxelRenderer.cs @@ -22,9 +22,9 @@ namespace OpenRA.Graphics public readonly Sprite Sprite; public readonly Sprite ShadowSprite; public readonly float ShadowDirection; - public readonly float2[] ProjectedShadowBounds; + public readonly float3[] ProjectedShadowBounds; - public VoxelRenderProxy(Sprite sprite, Sprite shadowSprite, float2[] projectedShadowBounds, float shadowDirection) + public VoxelRenderProxy(Sprite sprite, Sprite shadowSprite, float3[] projectedShadowBounds, float shadowDirection) { Sprite = sprite; ShadowSprite = shadowSprite; @@ -145,7 +145,7 @@ namespace OpenRA.Graphics var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform); var shadowGroundNormal = Util.MatrixVectorMultiply(shadowTransform, groundNormal); - var screenCorners = new float2[4]; + var screenCorners = new float3[4]; for (var j = 0; j < 4; j++) { // Project to ground plane @@ -154,7 +154,7 @@ namespace OpenRA.Graphics // Rotate to camera-space corners[j] = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]); - screenCorners[j] = new float2(corners[j][0], corners[j][1]); + screenCorners[j] = new float3(corners[j][0], corners[j][1], 0); } // Shadows are rendered at twice the resolution to reduce artifacts diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 06174d88c2..081150aab6 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -126,7 +126,10 @@ namespace OpenRA.Graphics return; if (devTrait.Value != null) + { Game.Renderer.WorldSpriteRenderer.SetDepthPreviewEnabled(devTrait.Value.ShowDepthPreview); + Game.Renderer.WorldRgbaSpriteRenderer.SetDepthPreviewEnabled(devTrait.Value.ShowDepthPreview); + } RefreshPalette(); diff --git a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs index 75bed0ed0d..f18388adb9 100644 --- a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Graphics; +using OpenRA.Primitives; namespace OpenRA.Mods.Common.Graphics { @@ -107,7 +108,12 @@ namespace OpenRA.Mods.Common.Graphics { var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length); var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f; - var pxOrigin = wr.ScreenPosition(voxel.pos); + var pxOrigin = wr.Screen3DPosition(voxel.pos); + + // HACK: We don't have enough texture channels to pass the depth data to the shader + // so for now just offset everything forward so that the back corner is rendered at pos. + pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Second.X); + var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1)); var psb = renderProxy.ProjectedShadowBounds; @@ -135,12 +141,13 @@ namespace OpenRA.Mods.Common.Graphics var c = Color.Purple; var psb = renderProxy.ProjectedShadowBounds; + // TODO: add float3 support to WorldRgbaColorRenderer Game.Renderer.WorldRgbaColorRenderer.DrawPolygon(new[] { - shadowOrigin + psb[1], - shadowOrigin + psb[3], - shadowOrigin + psb[0], - shadowOrigin + psb[2] + shadowOrigin + psb[1].XY, + shadowOrigin + psb[3].XY, + shadowOrigin + psb[0].XY, + shadowOrigin + psb[2].XY }, iz, c); // Draw voxel bounding box @@ -190,6 +197,11 @@ namespace OpenRA.Mods.Common.Graphics } public Rectangle ScreenBounds(WorldRenderer wr) + { + return Screen3DBounds(wr).First; + } + + Pair Screen3DBounds(WorldRenderer wr) { var pxOrigin = wr.ScreenPosition(voxel.pos); var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc()); @@ -198,8 +210,11 @@ namespace OpenRA.Mods.Common.Graphics var minX = float.MaxValue; var minY = float.MaxValue; + var minZ = float.MaxValue; var maxX = float.MinValue; var maxY = float.MinValue; + var maxZ = float.MinValue; + foreach (var v in draw) { var bounds = v.Voxel.Bounds(v.FrameFunc()); @@ -208,7 +223,7 @@ namespace OpenRA.Mods.Common.Graphics float sx, sy, sz; wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz); - var pxPos = pxOrigin + new float2(sx, sy); + var pxPos = pxOrigin + new float3(sx, sy, sz); var screenTransform = OpenRA.Graphics.Util.MatrixMultiply(cameraTransform, worldTransform); for (var i = 0; i < 8; i++) @@ -217,12 +232,14 @@ namespace OpenRA.Mods.Common.Graphics var screen = OpenRA.Graphics.Util.MatrixVectorMultiply(screenTransform, vec); minX = Math.Min(minX, pxPos.X + screen[0]); minY = Math.Min(minY, pxPos.Y + screen[1]); + minZ = Math.Min(minZ, pxPos.Z + screen[2]); maxX = Math.Max(maxX, pxPos.X + screen[0]); maxY = Math.Max(maxY, pxPos.Y + screen[1]); + maxZ = Math.Max(minZ, pxPos.Z + screen[2]); } } - return Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY); + return Pair.New(Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ)); } } } diff --git a/glsl/rgba.frag b/glsl/rgba.frag index b01e69da10..eced13e89f 100644 --- a/glsl/rgba.frag +++ b/glsl/rgba.frag @@ -1,7 +1,25 @@ uniform sampler2D DiffuseTexture; +uniform bool EnableDepthPreview; + varying vec4 vTexCoord; void main() { - gl_FragColor = texture2D(DiffuseTexture, vTexCoord.st); + vec4 c = texture2D(DiffuseTexture, vTexCoord.st); + // Discard any transparent fragments (both color and depth) + if (c.a == 0.0) + discard; + + float depth = gl_FragCoord.z; + + // Convert to window coords + gl_FragDepth = 0.5 * depth + 0.5; + + if (EnableDepthPreview) + { + // Front of the depth buffer is at 0, but we want to render it as bright + gl_FragColor = vec4(vec3(1.0 - gl_FragDepth), 1.0); + } + else + gl_FragColor = c; } \ No newline at end of file