diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 054a142a7b..e6b3c196a6 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -156,7 +156,7 @@ namespace OpenRA using (new PerfTimer("NewWorld")) OrderManager.World = new World(map, OrderManager, type); - worldRenderer = new WorldRenderer(OrderManager.World); + worldRenderer = new WorldRenderer(ModData, OrderManager.World); using (new PerfTimer("LoadComplete")) OrderManager.World.LoadComplete(worldRenderer); diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/IGraphicsDevice.cs index 27c41814b8..bd788c2338 100644 --- a/OpenRA.Game/Graphics/IGraphicsDevice.cs +++ b/OpenRA.Game/Graphics/IGraphicsDevice.cs @@ -70,6 +70,7 @@ namespace OpenRA void EnableDepthBuffer(); void DisableDepthBuffer(); + void ClearDepthBuffer(); void SetBlendMode(BlendMode mode); diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 45cee3134c..129c2ce34c 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -34,8 +34,9 @@ namespace OpenRA.Graphics readonly TerrainRenderer terrainRenderer; readonly Lazy devTrait; readonly Func createPaletteReference; + readonly bool enableDepthBuffer; - internal WorldRenderer(World world) + internal WorldRenderer(ModData modData, World world) { World = world; TileSize = World.Map.Grid.TileSize; @@ -43,6 +44,9 @@ namespace OpenRA.Graphics createPaletteReference = CreatePaletteReference; + var mapGrid = modData.Manifest.Get(); + enableDepthBuffer = mapGrid.EnableDepthBuffer; + foreach (var pal in world.TraitDict.ActorsWithTrait()) pal.Trait.LoadPalettes(this); @@ -133,18 +137,27 @@ namespace OpenRA.Graphics var bounds = Viewport.GetScissorBounds(World.Type != WorldType.Editor); Game.Renderer.EnableScissor(bounds); + if (enableDepthBuffer) + Game.Renderer.Device.EnableDepthBuffer(); + terrainRenderer.Draw(this, Viewport); Game.Renderer.Flush(); for (var i = 0; i < renderables.Count; i++) renderables[i].Render(this); + if (enableDepthBuffer) + Game.Renderer.ClearDepthBuffer(); + foreach (var a in World.ActorsWithTrait()) if (a.Actor.IsInWorld && !a.Actor.Disposed) a.Trait.RenderAfterWorld(this, a.Actor); var renderShroud = World.RenderPlayer != null ? World.RenderPlayer.Shroud : null; + if (enableDepthBuffer) + Game.Renderer.ClearDepthBuffer(); + foreach (var a in World.ActorsWithTrait()) a.Trait.RenderShroud(this, renderShroud); @@ -152,6 +165,9 @@ namespace OpenRA.Graphics for (var i = 0; i < renderables.Count; i++) renderables[i].RenderDebugGeometry(this); + if (enableDepthBuffer) + Game.Renderer.Device.DisableDepthBuffer(); + Game.Renderer.DisableScissor(); var overlayRenderables = World.Selection.Actors.Where(a => !a.Disposed) @@ -209,6 +225,12 @@ namespace OpenRA.Graphics return new float2(TileSize.Width * pos.X / 1024f, TileSize.Height * (pos.Y - pos.Z) / 1024f); } + public float3 Screen3DPosition(WPos pos) + { + var z = ZPosition(pos, 0) * TileSize.Height / 1024f; + return new float3(TileSize.Width * pos.X / 1024f, TileSize.Height * (pos.Y - pos.Z) / 1024f, z); + } + public int2 ScreenPxPosition(WPos pos) { // Round to nearest pixel diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index 266fa714d7..5aab34bdc0 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -255,6 +255,12 @@ namespace OpenRA Device.DisableDepthBuffer(); } + public void ClearDepthBuffer() + { + Flush(); + Device.ClearDepthBuffer(); + } + public void GrabWindowMouseFocus() { Device.GrabWindowMouseFocus(); diff --git a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs index f5356eebe8..fec2a467d5 100644 --- a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs +++ b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs @@ -213,7 +213,7 @@ namespace OpenRA.Platforms.Default VerifyThreadAffinity(); OpenGL.glClearColor(0, 0, 0, 1); OpenGL.CheckGLError(); - OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT); + OpenGL.glClear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); OpenGL.CheckGLError(); } @@ -235,6 +235,13 @@ namespace OpenRA.Platforms.Default OpenGL.CheckGLError(); } + public void ClearDepthBuffer() + { + VerifyThreadAffinity(); + OpenGL.glClear(OpenGL.GL_DEPTH_BUFFER_BIT); + OpenGL.CheckGLError(); + } + public void SetBlendMode(BlendMode mode) { VerifyThreadAffinity(); diff --git a/glsl/shp.frag b/glsl/shp.frag index df27bb2284..8f0b102384 100644 --- a/glsl/shp.frag +++ b/glsl/shp.frag @@ -17,25 +17,20 @@ void main() if (c.a == 0.0) discard; - if (EnableDepthPreview && length(vDepthMask) > 0.0) - { - if (abs(DepthTextureScale) > 0.0) - { - // Preview vertex aware depth - float depth = gl_FragCoord.z + DepthTextureScale * dot(x, vDepthMask); + float depth = gl_FragCoord.z; + if (length(vDepthMask) > 0.0) + { + // Preview vertex aware depth + depth = depth + DepthTextureScale * dot(x, vDepthMask); + } - // Convert to window coords - depth = 0.5 * depth + 0.5; + // Convert to window coords + gl_FragDepth = 0.5 * depth + 0.5; - // Front of the depth buffer is at 0, but we want to render it as bright - gl_FragColor = vec4(vec3(1.0 - depth), 1.0); - } - else - { - // Preview boring sprite-only depth - float depth = dot(x, vDepthMask); - gl_FragColor = vec4(depth, depth, depth, 1.0); - } + 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;