From 7e6ef65eb3c03b6c0aef34770cb16b9fd6f9827d Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Wed, 12 Oct 2016 16:54:41 -0300 Subject: [PATCH] Improved LOS effect It's pretty inefficient (I need to figure out how to set up new shaders), and it might let the player see too much, but it looks way better than pure black. --- Subsurface/Source/Characters/CharacterHUD.cs | 2 +- Subsurface/Source/Map/Lights/LightManager.cs | 14 ++++-- Subsurface/Source/Map/Submarine.cs | 14 ++++-- Subsurface/Source/Screens/GameScreen.cs | 50 ++++++++++++++++++-- 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/Subsurface/Source/Characters/CharacterHUD.cs b/Subsurface/Source/Characters/CharacterHUD.cs index 7cd1f09b9..2f11dab6b 100644 --- a/Subsurface/Source/Characters/CharacterHUD.cs +++ b/Subsurface/Source/Characters/CharacterHUD.cs @@ -18,7 +18,7 @@ namespace Barotrauma private static GUIProgressBar drowningBar, healthBar; - private static float damageOverlayTimer; + public static float damageOverlayTimer { get; private set; } public static void Reset() { diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index 71d658f7b..3fd45ac65 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -366,15 +366,15 @@ namespace Barotrauma.Lights spriteBatch.End(); } - public void DrawLOS(SpriteBatch spriteBatch, Effect effect) + public void DrawLOS(SpriteBatch spriteBatch, Effect effect,bool renderingBackground) { if (!LosEnabled || ViewTarget == null) return; - - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative, null, null, null, effect); + + spriteBatch.Begin(SpriteSortMode.Deferred, renderingBackground ? CustomBlendStates.LOS : CustomBlendStates.Multiplicative, null, null, null, effect); spriteBatch.Draw(losTexture, Vector2.Zero, Color.White); spriteBatch.End(); - ObstructVision = false; + if (!renderingBackground) ObstructVision = false; } public void ClearLights() @@ -399,10 +399,16 @@ namespace Barotrauma.Lights MultiplyWithAlpha = new BlendState(); MultiplyWithAlpha.ColorDestinationBlend = MultiplyWithAlpha.AlphaDestinationBlend = Blend.One; MultiplyWithAlpha.ColorSourceBlend = MultiplyWithAlpha.AlphaSourceBlend = Blend.DestinationAlpha; + + LOS = new BlendState(); + LOS.ColorSourceBlend = LOS.AlphaSourceBlend = Blend.Zero; + LOS.ColorDestinationBlend = LOS.AlphaDestinationBlend = Blend.InverseSourceColor; + LOS.ColorBlendFunction = LOS.AlphaBlendFunction = BlendFunction.Add; } public static BlendState Multiplicative { get; private set; } public static BlendState WriteToAlpha { get; private set; } public static BlendState MultiplyWithAlpha { get; private set; } + public static BlendState LOS { get; private set; } } } diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 42ed37efd..3a51cc0e6 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -307,15 +307,23 @@ namespace Barotrauma if (MapEntity.mapEntityList[i].DrawDamageEffect) MapEntity.mapEntityList[i].DrawDamage(spriteBatch, damageEffect); } - damageEffect.Parameters["aCutoff"].SetValue(0.0f); - damageEffect.Parameters["cCutoff"].SetValue(0.0f); + if (damageEffect != null) + { + damageEffect.Parameters["aCutoff"].SetValue(0.0f); + damageEffect.Parameters["cCutoff"].SetValue(0.0f); + } } - public static void DrawBack(SpriteBatch spriteBatch, bool editing = false) + public static void DrawBack(SpriteBatch spriteBatch, bool editing = false, Predicate predicate = null) { for (int i = 0; i < MapEntity.mapEntityList.Count; i++) { + if (predicate != null) + { + if (!predicate(MapEntity.mapEntityList[i])) continue; + } + if (MapEntity.mapEntityList[i].DrawBelowWater) MapEntity.mapEntityList[i].Draw(spriteBatch, editing, true); } diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 1d741e248..3f419f320 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -12,6 +12,7 @@ namespace Barotrauma { Camera cam; + readonly RenderTarget2D renderTargetBackground; readonly RenderTarget2D renderTarget; readonly RenderTarget2D renderTargetWater; readonly RenderTarget2D renderTargetAir; @@ -33,7 +34,8 @@ namespace Barotrauma { cam = new Camera(); cam.Translate(new Vector2(-10.0f, 50.0f)); - + + renderTargetBackground = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTargetWater = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); @@ -221,7 +223,7 @@ namespace Barotrauma //1. draw the background, characters and the parts of the submarine that are behind them //---------------------------------------------------------------------------------------- - graphics.SetRenderTarget(renderTarget); + graphics.SetRenderTarget(renderTargetBackground); if (Level.Loaded == null) { @@ -237,7 +239,23 @@ namespace Barotrauma null, null, null, null, cam.Transform); - Submarine.DrawBack(spriteBatch); + Submarine.DrawBack(spriteBatch,false,s => s is Structure); + + spriteBatch.End(); + + graphics.SetRenderTarget(renderTarget); + + spriteBatch.Begin(SpriteSortMode.Deferred, + BlendState.Opaque); + spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.BackToFront, + BlendState.AlphaBlend, + null, null, null, null, + cam.Transform); + + Submarine.DrawBack(spriteBatch, false, s => !(s is Structure)); foreach (Character c in Character.CharacterList) c.Draw(spriteBatch); @@ -303,6 +321,23 @@ namespace Barotrauma GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive); spriteBatch.End(); + if (Character.Controlled != null) + { + graphics.SetRenderTarget(renderTarget); + spriteBatch.Begin(SpriteSortMode.Deferred, + BlendState.Opaque, null, null, null, lightBlur.Effect); + spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.BackToFront, + BlendState.AlphaBlend, SamplerState.LinearWrap, + null, null, null, + cam.Transform); + Submarine.DrawDamageable(spriteBatch, null); + spriteBatch.End(); + + GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect, true); + } graphics.SetRenderTarget(null); @@ -359,7 +394,14 @@ namespace Barotrauma if (Character.Controlled != null) { - GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect); + GameMain.LightManager.DrawLOS(spriteBatch, lightBlur.Effect,false); + + spriteBatch.Begin(SpriteSortMode.Immediate, + BlendState.AlphaBlend); + float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.03f, 0.04f); + spriteBatch.Draw(renderTarget, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), + new Color(0.04f + r, Math.Max(0.04f-r,0.0f), Math.Max(0.045f - r, 0.0f), 1.0f)); + spriteBatch.End(); } }