diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index c4c48d9c9..cb3b9d7a5 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -985,7 +985,12 @@ - + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/Subsurface/Content/Content.mgcb b/Subsurface/Content/Content.mgcb index 9b8588c71..e7b71d44b 100644 --- a/Subsurface/Content/Content.mgcb +++ b/Subsurface/Content/Content.mgcb @@ -37,3 +37,9 @@ /processorParam:DebugMode=Auto /build:watershader.fx +#begin blurshader.fx +/importer:EffectImporter +/processor:EffectProcessor +/processorParam:DebugMode=Auto +/build:blurshader.fx + diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index 9c3245dc4..38f7b2f41 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -109,7 +109,6 @@ - - - + + diff --git a/Subsurface/Content/Items/Diving/scooter.ogg b/Subsurface/Content/Items/Diving/scooter.ogg index 523b453f7..232faa71c 100644 Binary files a/Subsurface/Content/Items/Diving/scooter.ogg and b/Subsurface/Content/Items/Diving/scooter.ogg differ diff --git a/Subsurface/Content/Items/Tools/tools.png b/Subsurface/Content/Items/Tools/tools.png index 2df75e002..55f741a6b 100644 Binary files a/Subsurface/Content/Items/Tools/tools.png and b/Subsurface/Content/Items/Tools/tools.png differ diff --git a/Subsurface/Content/Items/Tools/tools.xml b/Subsurface/Content/Items/Tools/tools.xml index 4f05e60dc..74b1236f6 100644 --- a/Subsurface/Content/Items/Tools/tools.xml +++ b/Subsurface/Content/Items/Tools/tools.xml @@ -191,7 +191,7 @@ pickdistance="200" price="10"> - + @@ -213,4 +213,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Subsurface/Content/blurshader.fx b/Subsurface/Content/blurshader.fx new file mode 100644 index 000000000..45c4cd015 --- /dev/null +++ b/Subsurface/Content/blurshader.fx @@ -0,0 +1,33 @@ +// Pixel shader applies a one dimensional gaussian blur filter. +// This is used twice by the bloom postprocess, first to +// blur horizontally, and then again to blur vertically. + +sampler TextureSampler : register(s0); + +#define SAMPLE_COUNT 15 + +float2 SampleOffsets[SAMPLE_COUNT]; +float SampleWeights[SAMPLE_COUNT]; + + +float4 PixelShaderF(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 +{ + float4 c = 0; + + // Combine a number of weighted image filter taps. + for (int i = 0; i < SAMPLE_COUNT; i++) + { + c += tex2D(TextureSampler, texCoord + SampleOffsets[i]) * SampleWeights[i]; + } + + return c; +} + + +technique GaussianBlur +{ + pass Pass1 + { + PixelShader = compile ps_4_0_level_9_1 PixelShaderF(); + } +} \ No newline at end of file diff --git a/Subsurface/Content/blurshader.xnb b/Subsurface/Content/blurshader.xnb new file mode 100644 index 000000000..111241629 Binary files /dev/null and b/Subsurface/Content/blurshader.xnb differ diff --git a/Subsurface/Source/GameMain.cs b/Subsurface/Source/GameMain.cs index a693c25e8..45aacb904 100644 --- a/Subsurface/Source/GameMain.cs +++ b/Subsurface/Source/GameMain.cs @@ -237,7 +237,7 @@ namespace Barotrauma TitleScreen.LoadState = 80.0f; yield return CoroutineStatus.Running; - GameScreen = new GameScreen(Graphics.GraphicsDevice); + GameScreen = new GameScreen(Graphics.GraphicsDevice, Content); TitleScreen.LoadState = 90.0f; yield return CoroutineStatus.Running; diff --git a/Subsurface/Source/Items/Components/Signal/LightComponent.cs b/Subsurface/Source/Items/Components/Signal/LightComponent.cs index fda6b782f..d30ec168e 100644 --- a/Subsurface/Source/Items/Components/Signal/LightComponent.cs +++ b/Subsurface/Source/Items/Components/Signal/LightComponent.cs @@ -90,8 +90,9 @@ namespace Barotrauma.Items.Components set { - if (base.IsActive == value) return; base.IsActive = value; + + if (light == null) return; light.Color = value ? lightColor : Color.Transparent; if (!value) lightBrightness = 0.0f; } @@ -105,7 +106,7 @@ namespace Barotrauma.Items.Components light.Position = item.Position; light.CastShadows = castShadows; - IsActive = true; + IsActive = IsOn; //foreach (XElement subElement in element.Elements()) //{ @@ -157,6 +158,8 @@ namespace Barotrauma.Items.Components else { lightBrightness = MathHelper.Lerp(lightBrightness, Math.Min(voltage, 1.0f), 0.1f); + + ApplyStatusEffects(ActionType.OnActive, deltaTime); } light.Color = lightColor * lightBrightness * (1.0f-Rand.Range(0.0f,Flicker)); @@ -165,6 +168,11 @@ namespace Barotrauma.Items.Components voltage = 0.0f; } + public override bool Use(float deltaTime, Character character = null) + { + return true; + } + public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, bool editing = false) { if (light.LightSprite != null && (item.body == null || item.body.Enabled)) diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 5ad1fd552..32e2e6633 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -673,7 +673,7 @@ namespace Barotrauma } ic.WasUsed = false; - if (Container != null) ic.ApplyStatusEffects(ActionType.OnContained, deltaTime); + if (parentInventory!=null) ic.ApplyStatusEffects(ActionType.OnContained, deltaTime); if (!ic.IsActive) continue; @@ -795,7 +795,6 @@ namespace Barotrauma { if (prefab.ResizeHorizontal || prefab.ResizeVertical) { - prefab.sprite.DrawTiled(spriteBatch, new Vector2(DrawPosition.X-rect.Width/2, -(DrawPosition.Y+rect.Height/2)), new Vector2(rect.Width, rect.Height), color); } else diff --git a/Subsurface/Source/Map/Lights/ConvexHull.cs b/Subsurface/Source/Map/Lights/ConvexHull.cs index 0f39b9b32..0866532e9 100644 --- a/Subsurface/Source/Map/Lights/ConvexHull.cs +++ b/Subsurface/Source/Map/Lights/ConvexHull.cs @@ -13,9 +13,9 @@ namespace Barotrauma.Lights public Vector2 LightPos; - public int ShadowVertexCount, PenumbraVertexCount; + public int ShadowVertexCount;//, PenumbraVertexCount; - public CachedShadow(VertexPositionColor[] shadowVertices, VertexPositionTexture[] penumbraVertices, Vector2 lightPos, int shadowVertexCount, int penumbraVertexCount) + public CachedShadow(VertexPositionColor[] shadowVertices, Vector2 lightPos, int shadowVertexCount, int penumbraVertexCount) { //var ShadowVertices = new VertexPositionColor [shadowVertices.Count()]; //shadowVertices.CopyTo(ShadowVertices, 0); @@ -24,7 +24,7 @@ namespace Barotrauma.Lights ShadowBuffer.SetData(shadowVertices, 0, shadowVertices.Length); ShadowVertexCount = shadowVertexCount; - PenumbraVertexCount = penumbraVertexCount; + //PenumbraVertexCount = penumbraVertexCount; LightPos = lightPos; } @@ -46,17 +46,18 @@ namespace Barotrauma.Lights { public static List list = new List(); static BasicEffect shadowEffect; - static BasicEffect penumbraEffect; + //static BasicEffect penumbraEffect; private Dictionary cachedShadows; private Vector2[] vertices; + private Vector2[] losVertices; private int primitiveCount; private bool[] backFacing; private VertexPositionColor[] shadowVertices; - private VertexPositionTexture[] penumbraVertices; + // private VertexPositionTexture[] penumbraVertices; int shadowVertexCount; @@ -88,26 +89,26 @@ namespace Barotrauma.Lights shadowEffect = new BasicEffect(GameMain.CurrGraphicsDevice); shadowEffect.VertexColorEnabled = true; } - if (penumbraEffect == null) - { - penumbraEffect = new BasicEffect(GameMain.CurrGraphicsDevice); - penumbraEffect.TextureEnabled = true; - //shadowEffect.VertexColorEnabled = true; - penumbraEffect.LightingEnabled = false; - penumbraEffect.Texture = TextureLoader.FromFile("Content/Lights/penumbra.png"); - } + //if (penumbraEffect == null) + //{ + // penumbraEffect = new BasicEffect(GameMain.CurrGraphicsDevice); + // penumbraEffect.TextureEnabled = true; + // //shadowEffect.VertexColorEnabled = true; + // penumbraEffect.LightingEnabled = false; + // penumbraEffect.Texture = TextureLoader.FromFile("Content/Lights/penumbra.png"); + //} parentEntity = parent; cachedShadows = new Dictionary(); shadowVertices = new VertexPositionColor[6 * 2]; - penumbraVertices = new VertexPositionTexture[6]; + //penumbraVertices = new VertexPositionTexture[6]; - vertices = points; - primitiveCount = vertices.Length; - - CalculateDimensions(); + //vertices = points; + primitiveCount = points.Length; + SetVertices(points); + //CalculateDimensions(); backFacing = new bool[primitiveCount]; @@ -139,6 +140,7 @@ namespace Barotrauma.Lights for (int i = 0; i < vertices.Count(); i++) { vertices[i] += amount; + losVertices[i] += amount; } CalculateDimensions(); @@ -149,6 +151,26 @@ namespace Barotrauma.Lights ClearCachedShadows(); vertices = points; + losVertices = points; + + int margin = 7; + + if (Math.Abs(points[0].X - points[2].X) < Math.Abs(points[0].Y - points[1].Y)) + { + losVertices = new Vector2[] { + new Vector2(points[0].X+margin, points[0].Y), + new Vector2(points[1].X+margin, points[1].Y), + new Vector2(points[2].X-margin, points[2].Y), + new Vector2(points[3].X-margin, points[3].Y)}; + } + else + { + losVertices = new Vector2[] { + new Vector2(points[0].X, points[0].Y +margin), + new Vector2(points[1].X, points[1].Y - margin), + new Vector2(points[2].X, points[2].Y - margin), + new Vector2(points[3].X, points[3].Y + margin)}; + } CalculateDimensions(); } @@ -191,6 +213,8 @@ namespace Barotrauma.Lights { shadowVertexCount = 0; + var vertices = los ? losVertices : this.vertices; + //compute facing of each edge, using N*L for (int i = 0; i < primitiveCount; i++) { @@ -205,7 +229,7 @@ namespace Barotrauma.Lights -(secondVertex.Y - firstVertex.Y), secondVertex.X - firstVertex.X); - backFacing[i] = (Vector2.Dot(N, L) < 0); + backFacing[i] = (Vector2.Dot(N, L) < 0) == los; } //find beginning and ending vertices which @@ -239,70 +263,76 @@ namespace Barotrauma.Lights { Vector3 vertexPos = new Vector3(vertices[currentIndex], 0.0f); + int i = los ? svCount : svCount + 1; + int j = los ? svCount + 1 : svCount; + //one vertex on the hull - shadowVertices[svCount] = new VertexPositionColor(); - shadowVertices[svCount].Color = los ? Color.Black : Color.Transparent; - shadowVertices[svCount].Position = vertexPos; + shadowVertices[i] = new VertexPositionColor(); + shadowVertices[i].Color = los ? Color.Black : Color.Transparent; + shadowVertices[i].Position = vertexPos; //one extruded by the light direction - shadowVertices[svCount + 1] = new VertexPositionColor(); - shadowVertices[svCount + 1].Color = los ? Color.Black : Color.Transparent; + shadowVertices[j] = new VertexPositionColor(); + shadowVertices[j].Color = shadowVertices[i].Color; + + Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0); L2P.Normalize(); - shadowVertices[svCount + 1].Position = new Vector3(lightSourcePos, 0) + L2P * 9000; + + shadowVertices[j].Position = new Vector3(lightSourcePos, 0) + L2P * 9000; svCount += 2; currentIndex = (currentIndex + 1) % primitiveCount; } - if (los) - { - CalculatePenumbraVertices(startingIndex, endingIndex, lightSourcePos, los); - } + //if (los) + //{ + // CalculatePenumbraVertices(startingIndex, endingIndex, lightSourcePos, los); + //} } - private void CalculatePenumbraVertices(int startingIndex, int endingIndex, Vector2 lightSourcePos, bool los) - { - for (int n = 0; n < 4; n += 3) - { - Vector3 penumbraStart = new Vector3((n == 0) ? vertices[startingIndex] : vertices[endingIndex], 0.0f); + //private void CalculatePenumbraVertices(int startingIndex, int endingIndex, Vector2 lightSourcePos, bool los) + //{ + // for (int n = 0; n < 4; n += 3) + // { + // Vector3 penumbraStart = new Vector3((n == 0) ? vertices[startingIndex] : vertices[endingIndex], 0.0f); - penumbraVertices[n] = new VertexPositionTexture(); - penumbraVertices[n].Position = penumbraStart; - penumbraVertices[n].TextureCoordinate = new Vector2(0.0f, 1.0f); - //penumbraVertices[0].te = fow ? Color.Black : Color.Transparent; + // penumbraVertices[n] = new VertexPositionTexture(); + // penumbraVertices[n].Position = penumbraStart; + // penumbraVertices[n].TextureCoordinate = new Vector2(0.0f, 1.0f); + // //penumbraVertices[0].te = fow ? Color.Black : Color.Transparent; - for (int i = 0; i < 2; i++) - { - penumbraVertices[n + i + 1] = new VertexPositionTexture(); - Vector3 vertexDir = penumbraStart - new Vector3(lightSourcePos, 0); - vertexDir.Normalize(); + // for (int i = 0; i < 2; i++) + // { + // penumbraVertices[n + i + 1] = new VertexPositionTexture(); + // Vector3 vertexDir = penumbraStart - new Vector3(lightSourcePos, 0); + // vertexDir.Normalize(); - Vector3 normal = (i == 0) ? new Vector3(-vertexDir.Y, vertexDir.X, 0.0f) : new Vector3(vertexDir.Y, -vertexDir.X, 0.0f) * 0.05f; - if (n > 0) normal = -normal; + // Vector3 normal = (i == 0) ? new Vector3(-vertexDir.Y, vertexDir.X, 0.0f) : new Vector3(vertexDir.Y, -vertexDir.X, 0.0f) * 0.05f; + // if (n > 0) normal = -normal; - vertexDir = penumbraStart - (new Vector3(lightSourcePos, 0) - normal * 20.0f); - vertexDir.Normalize(); - penumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000; + // vertexDir = penumbraStart - (new Vector3(lightSourcePos, 0) - normal * 20.0f); + // vertexDir.Normalize(); + // penumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000; - if (los) - { - penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(0.05f, 0.0f) : new Vector2(1.0f, 0.0f); - } - else - { - penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(1.0f, 0.0f) : Vector2.Zero; - } - } + // if (los) + // { + // penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(0.05f, 0.0f) : new Vector2(1.0f, 0.0f); + // } + // else + // { + // penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(1.0f, 0.0f) : Vector2.Zero; + // } + // } - if (n > 0) - { - var temp = penumbraVertices[4]; - penumbraVertices[4] = penumbraVertices[5]; - penumbraVertices[5] = temp; - } - } - } + // if (n > 0) + // { + // var temp = penumbraVertices[4]; + // penumbraVertices[4] = penumbraVertices[5]; + // penumbraVertices[5] = temp; + // } + // } + //} public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, LightSource light, Matrix transform, bool los = true) { @@ -335,7 +365,7 @@ namespace Barotrauma.Lights } else { - cachedShadow = new CachedShadow(shadowVertices, penumbraVertices, lightSourcePos, shadowVertexCount, 0); + cachedShadow = new CachedShadow(shadowVertices, lightSourcePos, shadowVertexCount, 0); RemoveCachedShadow(light); cachedShadows.Add(light, cachedShadow); } @@ -386,15 +416,15 @@ namespace Barotrauma.Lights } - if (los) - { - penumbraEffect.World = shadowEffect.World; - penumbraEffect.CurrentTechnique.Passes[0].Apply(); +// if (los && false) +// { +// penumbraEffect.World = shadowEffect.World; +// penumbraEffect.CurrentTechnique.Passes[0].Apply(); -#if WINDOWS - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, penumbraVertices, 0, 2, VertexPositionTexture.VertexDeclaration); -#endif - } +//#if WINDOWS +// graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, 0, 2, VertexPositionTexture.VertexDeclaration); +//#endif +// } } diff --git a/Subsurface/Source/Map/Lights/LightManager.cs b/Subsurface/Source/Map/Lights/LightManager.cs index 994ecb146..e47e52ac2 100644 --- a/Subsurface/Source/Map/Lights/LightManager.cs +++ b/Subsurface/Source/Map/Lights/LightManager.cs @@ -69,30 +69,42 @@ namespace Barotrauma.Lights lights.Remove(light); } - public void DrawLOS(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam) + public void DrawLOS(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Effect effect) { - if (!LosEnabled || ViewTarget==null) return; + //if (!LosEnabled || ViewTarget==null) return; - Vector2 pos = ViewTarget.WorldPosition; + //Vector2 pos = ViewTarget.WorldPosition; - Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height); + //Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height); - Matrix shadowTransform = cam.ShaderTransform - * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; + //Matrix shadowTransform = cam.ShaderTransform + // * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; - foreach (ConvexHull convexHull in ConvexHull.list) - { - if (!convexHull.Intersects(camView)) continue; - //if (!camView.Intersects(convexHull.BoundingBox)) continue; + //graphics.SetRenderTarget(losTexture); + //graphics.Clear(Color.Transparent); - convexHull.DrawShadows(graphics, cam, pos, shadowTransform); - } + //foreach (ConvexHull convexHull in ConvexHull.list) + //{ + // if (!convexHull.Intersects(camView)) continue; + // //if (!camView.Intersects(convexHull.BoundingBox)) continue; + + // convexHull.DrawShadows(graphics, cam, pos, shadowTransform); + //} + + //graphics.SetRenderTarget(null); - if (!ObstructVision) return; + //if (!ObstructVision) return; - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative); - spriteBatch.Draw(losTexture, Vector2.Zero); - spriteBatch.End(); + //spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative); + //spriteBatch.Draw(losTexture, Vector2.Zero); + //spriteBatch.End(); + + + + spriteBatch.Begin(SpriteSortMode.Deferred, ObstructVision ? CustomBlendStates.Multiplicative : BlendState.AlphaBlend, null, null, null, effect); + //effect.CurrentTechnique.Passes[0].Apply(); + spriteBatch.Draw(losTexture, Vector2.Zero, Color.White); + spriteBatch.End(); ObstructVision = false; @@ -148,9 +160,14 @@ namespace Barotrauma.Lights spriteBatch.End(); } + ClearAlphaToOne(graphics, spriteBatch); + + spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform); + GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive); + foreach (LightSource light in lights) { if (light.hullsInRange.Any() || light.Color.A < 0.01f) continue; @@ -163,37 +180,59 @@ namespace Barotrauma.Lights //clear alpha, to avoid messing stuff up later ClearAlphaToOne(graphics, spriteBatch); + graphics.SetRenderTarget(null); } public void UpdateObstructVision(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Vector2 lookAtPosition) { + if (!LosEnabled && !ObstructVision) return; - if (!ObstructVision) return; - graphics.SetRenderTarget(losTexture); - graphics.Clear(Color.Black); - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, cam.Transform); + if (ObstructVision) + { + graphics.Clear(Color.Black); - Vector2 diff = lookAtPosition - ViewTarget.WorldPosition; - diff.Y = -diff.Y; - float rotation = MathUtils.VectorToAngle(diff); + spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, cam.Transform); + + Vector2 diff = lookAtPosition - ViewTarget.WorldPosition; + diff.Y = -diff.Y; + float rotation = MathUtils.VectorToAngle(diff); - Vector2 scale = new Vector2(MathHelper.Clamp(diff.Length()/256.0f, 2.0f, 5.0f), 2.0f); + Vector2 scale = new Vector2(MathHelper.Clamp(diff.Length()/256.0f, 2.0f, 5.0f), 2.0f); - spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation, - new Vector2(LightSource.LightTexture.Width*0.2f, LightSource.LightTexture.Height/2), scale, SpriteEffects.None, 0.0f); - spriteBatch.End(); + spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation, + new Vector2(LightSource.LightTexture.Width*0.2f, LightSource.LightTexture.Height/2), scale, SpriteEffects.None, 0.0f); + spriteBatch.End(); - //ClearAlphaToOne(graphics, spriteBatch); + } + else + { + graphics.Clear(Color.Transparent); + } - graphics.SetRenderTarget(null); + //-------------------------------------- - //spriteBatch.Begin(); - //spriteBatch.Draw(lightMap, Vector2.Zero, Color.White); - //spriteBatch.End(); - + if (LosEnabled && ViewTarget != null) + { + Vector2 pos = ViewTarget.WorldPosition; + + Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height); + + Matrix shadowTransform = cam.ShaderTransform + * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; + + foreach (ConvexHull convexHull in ConvexHull.list) + { + if (!convexHull.Intersects(camView)) continue; + //if (!camView.Intersects(convexHull.BoundingBox)) continue; + + convexHull.DrawShadows(graphics, cam, pos, shadowTransform); + } + } + + graphics.SetRenderTarget(null); } private void ClearAlphaToOne(GraphicsDevice graphics, SpriteBatch spriteBatch) @@ -203,16 +242,18 @@ namespace Barotrauma.Lights spriteBatch.End(); } - public void DrawLightMap(SpriteBatch spriteBatch, Camera cam) + public void DrawLightMap(SpriteBatch spriteBatch, Camera cam, Effect effect) { if (!LightingEnabled) return; - - //multiply scene with lightmap - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative); - spriteBatch.Draw(lightMap, Vector2.Zero, Color.White); - spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative, null, null, null, effect); + //effect.CurrentTechnique.Passes[0].Apply(); + spriteBatch.Draw(lightMap, Vector2.Zero, Color.White); + spriteBatch.End(); } + + public void ClearLights() { lights.Clear(); diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 9540a0275..afa829ef8 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -4,6 +4,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Barotrauma.Lights; using System.Diagnostics; +using Microsoft.Xna.Framework.Content; namespace Barotrauma { @@ -15,6 +16,8 @@ namespace Barotrauma readonly RenderTarget2D renderTargetWater; readonly RenderTarget2D renderTargetAir; + Effect blurEffect; + public BackgroundCreatureManager BackgroundCreatureManager; public Camera Cam @@ -22,7 +25,7 @@ namespace Barotrauma get { return cam; } } - public GameScreen(GraphicsDevice graphics) + public GameScreen(GraphicsDevice graphics, ContentManager content) { cam = new Camera(); cam.Translate(new Vector2(-10.0f, 50.0f)); @@ -32,6 +35,9 @@ namespace Barotrauma renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml"); + + blurEffect = content.Load("blurshader"); + SetBlurEffectParameters(0.001f, 0.001f); } public override void Select() @@ -47,7 +53,6 @@ namespace Barotrauma cam.Position = Submarine.Loaded.WorldPosition; } - foreach (MapEntity entity in MapEntity.mapEntityList) entity.IsHighlighted = false; } @@ -200,7 +205,6 @@ namespace Barotrauma Level.Loaded.DrawBack(graphics, spriteBatch, cam, BackgroundCreatureManager); } - spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, @@ -212,8 +216,6 @@ namespace Barotrauma spriteBatch.End(); - GameMain.LightManager.DrawLightMap(spriteBatch, cam); - //---------------------------------------------------------------------------------------- //draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater graphics.SetRenderTarget(renderTargetWater); @@ -304,12 +306,18 @@ namespace Barotrauma foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch); Submarine.DrawFront(spriteBatch); + + if (Level.Loaded!=null) Level.Loaded.DrawFront(spriteBatch); spriteBatch.End(); - GameMain.LightManager.DrawLOS(graphics, spriteBatch, cam); + + GameMain.LightManager.DrawLightMap(spriteBatch, cam, blurEffect); + + GameMain.LightManager.DrawLOS(graphics, spriteBatch, cam, blurEffect); + } private void DrawSubmarineIndicator(SpriteBatch spriteBatch, Submarine submarine) @@ -331,5 +339,78 @@ namespace Barotrauma GUI.Arrow.Draw(spriteBatch, iconPos + arrowOffset, Color.LightBlue * 0.5f, MathUtils.VectorToAngle(arrowOffset) + MathHelper.PiOver2); } } + + /// + /// Computes sample weightings and texture coordinate offsets + /// for one pass of a separable gaussian blur filter. + /// + void SetBlurEffectParameters(float dx, float dy) + { + EffectParameter weightsParameter = blurEffect.Parameters["SampleWeights"]; + EffectParameter offsetsParameter = blurEffect.Parameters["SampleOffsets"]; + + // Look up how many samples our gaussian blur effect supports. + int sampleCount = weightsParameter.Elements.Count; + + // Create temporary arrays for computing our filter settings. + float[] sampleWeights = new float[sampleCount]; + Vector2[] sampleOffsets = new Vector2[sampleCount]; + + sampleWeights[0] = ComputeGaussian(0); + sampleOffsets[0] = new Vector2(0); + + float totalWeights = sampleWeights[0]; + + // Add pairs of additional sample taps, positioned + // along a line in both directions from the center. + for (int i = 0; i < sampleCount / 2; i++) + { + // Store weights for the positive and negative taps. + float weight = ComputeGaussian(i + 1); + + sampleWeights[i * 2 + 1] = weight; + sampleWeights[i * 2 + 2] = weight; + + totalWeights += weight * 2; + + // To get the maximum amount of blurring from a limited number of + // pixel shader samples, we take advantage of the bilinear filtering + // hardware inside the texture fetch unit. If we position our texture + // coordinates exactly halfway between two texels, the filtering unit + // will average them for us, giving two samples for the price of one. + // This allows us to step in units of two texels per sample, rather + // than just one at a time. The 1.5 offset kicks things off by + // positioning us nicely in between two texels. + float sampleOffset = i * 2 + 1.5f; + + Vector2 delta = new Vector2(dx, dy) * sampleOffset; + + // Store texture coordinate offsets for the positive and negative taps. + sampleOffsets[i * 2 + 1] = delta; + sampleOffsets[i * 2 + 2] = -delta; + } + + // Normalize the list of sample weightings, so they will always sum to one. + for (int i = 0; i < sampleWeights.Length; i++) + { + sampleWeights[i] /= totalWeights; + } + + weightsParameter.SetValue(sampleWeights); + offsetsParameter.SetValue(sampleOffsets); + } + + + /// + /// Evaluates a single point on the gaussian falloff curve. + /// Used for setting up the blur filter weightings. + /// + float ComputeGaussian(float n) + { + float theta = 4.0f; + + return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) * + Math.Exp(-(n * n) / (2 * theta * theta))); + } } }