From 47f9900fdc7c7a3bddca61ff1319a78db49adec0 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 11 Jan 2018 11:23:55 +0200 Subject: [PATCH] Lighting fixes: - Re-enabled lightsprites (glowing lamp sprites on lamps). - Limb sprites use lightsprites instead of overriding the texture (positioned correctly now). - Fixed lights that don't cast shadows not being rendered. --- .../Source/Characters/Limb.cs | 1 + .../Source/Map/Lights/LightSource.cs | 126 ++++++++---------- .../Content/Characters/Carrier/carrier.xml | 4 +- .../Content/Characters/Watcher/watcher.xml | 4 +- .../Content/Items/Electricity/lights.xml | 4 +- .../Items/Components/Signal/LightComponent.cs | 8 -- 6 files changed, 59 insertions(+), 88 deletions(-) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs index 5f17afa4e..c75c13e07 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Limb.cs @@ -81,6 +81,7 @@ namespace Barotrauma if (LightSource != null) { LightSource.Position = body.DrawPosition; + LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically; } foreach (WearableSprite wearable in wearingItems) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightSource.cs b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightSource.cs index 77a8881ad..5033b30da 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightSource.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightSource.cs @@ -20,8 +20,16 @@ namespace Barotrauma.Lights public Sprite overrideLightTexture; public Texture2D texture; + //Additional sprite drawn on top of the lightsource. Ignores shadows. + //Can be used to make lamp sprites glow for example. public Sprite LightSprite; + //Override the alpha value of the light sprite (if not set, the alpha of the light color is used) + //Can be used to make lamp sprites glow at full brightness even if the light itself is dim. + public float? OverrideLightSpriteAlpha; + + public SpriteEffects LightSpriteEffect; + public Submarine ParentSub; public bool CastShadows; @@ -125,6 +133,7 @@ namespace Barotrauma.Lights color = new Color(element.GetAttributeVector4("color", Vector4.One)); CastShadows = element.GetAttributeBool("castshadows", true); + foreach (XElement subElement in element.Elements()) { @@ -132,6 +141,12 @@ namespace Barotrauma.Lights { case "sprite": LightSprite = new Sprite(subElement); + + float spriteAlpha = subElement.GetAttributeFloat("alpha", -1.0f); + if (spriteAlpha >= 0.0f) + { + OverrideLightSpriteAlpha = spriteAlpha; + } break; case "lighttexture": overrideLightTexture = new Sprite(subElement); @@ -158,34 +173,6 @@ namespace Barotrauma.Lights if (addLight) GameMain.LightManager.AddLight(this); } - - /*public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform) - { - if (!CastShadows) return; - if (range < 1.0f || color.A < 0.01f) return; - - foreach (Submarine sub in Submarine.Loaded) - { - var hulls = GetHullsInRange(sub); - - if (hulls == null) continue; - - foreach ( ConvexHull ch in hulls) - { - ch.DrawShadows(graphics, cam, this, shadowTransform, false); - } - } - - var outsideHulls = GetHullsInRange(null); - - NeedsHullUpdate = false; - - if (outsideHulls == null) return; - foreach (ConvexHull ch in outsideHulls) - { - ch.DrawShadows(graphics, cam, this, shadowTransform, false); - } - }*/ /// /// Update the contents of ConvexHullList and check if we need to recalculate vertices @@ -310,7 +297,10 @@ namespace Barotrauma.Lights private List FindRaycastHits() { - if (!CastShadows) return null; + if (!CastShadows) + { + return null; + } if (range < 1.0f || color.A < 0.01f) return null; Vector2 drawPos = position; @@ -359,7 +349,7 @@ namespace Barotrauma.Lights points.AddRange(boundaryCorners); //visibleSegments.Clear(); - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { visibleSegments.Add(new Segment(boundaryCorners[i], boundaryCorners[(i + 1) % 4])); } @@ -396,8 +386,8 @@ namespace Barotrauma.Lights foreach (SegmentPoint p in points) { Vector2 dir = Vector2.Normalize(p.WorldPos - drawPos); - Vector2 dirNormal = new Vector2(-dir.Y, dir.X)*3; - + Vector2 dirNormal = new Vector2(-dir.Y, dir.X) * 3; + //do two slightly offset raycasts to hit the segment itself and whatever's behind it Pair intersection1 = RayCast(drawPos, drawPos + dir * bounds * 2 - dirNormal, visibleSegments); Pair intersection2 = RayCast(drawPos, drawPos + dir * bounds * 2 + dirNormal, visibleSegments); @@ -580,7 +570,10 @@ namespace Barotrauma.Lights public void Draw(SpriteBatch spriteBatch, BasicEffect lightEffect, Matrix transform) { - CheckHullsInRange(); + if (CastShadows) + { + CheckHullsInRange(); + } Vector3 offset = ParentSub == null ? Vector3.Zero : new Vector3(ParentSub.DrawPosition.X, ParentSub.DrawPosition.Y, 0.0f); @@ -592,28 +585,31 @@ namespace Barotrauma.Lights drawPos.Y = -drawPos.Y; - /*if (range > 1.0f) - { - if (overrideLightTexture == null) - { - Vector2 center = new Vector2(LightTexture.Width / 2, LightTexture.Height / 2); - float scale = range / (lightTexture.Width / 2.0f); - - spriteBatch.Draw(lightTexture, drawPos, null, color * (color.A / 255.0f), 0, center, scale, SpriteEffects.None, 1); - } - else - { - overrideLightTexture.Draw(spriteBatch, - drawPos, color * (color.A / 255.0f), - overrideLightTexture.Origin, -Rotation, - new Vector2(overrideLightTexture.size.X / overrideLightTexture.SourceRect.Width, overrideLightTexture.size.Y / overrideLightTexture.SourceRect.Height)); - } - } - if (LightSprite != null) { - LightSprite.Draw(spriteBatch, drawPos, Color, LightSprite.Origin, -Rotation, 1); - }*/ + Vector2 origin = LightSprite.Origin; + if (LightSpriteEffect == SpriteEffects.FlipHorizontally) origin.X = LightSprite.SourceRect.Width - origin.X; + if (LightSpriteEffect == SpriteEffects.FlipVertically) origin.Y = LightSprite.SourceRect.Height - origin.Y; + + LightSprite.Draw( + spriteBatch, drawPos, + new Color(Color, OverrideLightSpriteAlpha ?? Color.A / 255.0f), + origin, -Rotation, 1, LightSpriteEffect); + } + + //if the light doesn't cast shadows, we can simply render the texture without having to calculate the light volume + if (!CastShadows) + { + Texture2D currentTexture = texture ?? LightTexture; + if (overrideLightTexture != null) currentTexture = overrideLightTexture.Texture; + + Vector2 center = new Vector2(currentTexture.Width / 2, currentTexture.Height / 2); + float scale = range / (currentTexture.Width / 2.0f); + + spriteBatch.Draw(currentTexture, drawPos, null, color * (color.A / 255.0f), 0, center, scale, SpriteEffects.None, 1); + + return; + } if (NeedsRecalculation) { @@ -626,14 +622,14 @@ namespace Barotrauma.Lights if (vertexCount == 0) return; - lightEffect.DiffuseColor = (new Vector3(color.R, color.G, color.B) * (color.A / 255.0f)) / 255.0f;// color.ToVector3(); + lightEffect.DiffuseColor = (new Vector3(color.R, color.G, color.B) * (color.A / 255.0f)) / 255.0f; if (overrideLightTexture != null) { lightEffect.Texture = overrideLightTexture.Texture; } else { - lightEffect.Texture = texture??LightTexture; + lightEffect.Texture = texture ?? LightTexture; } lightEffect.CurrentTechnique.Passes[0].Apply(); @@ -642,28 +638,10 @@ namespace Barotrauma.Lights GameMain.Instance.GraphicsDevice.DrawIndexedPrimitives ( - //PrimitiveType.LineList, 0, 0, indexCount / 2 PrimitiveType.TriangleList, 0, 0, indexCount / 3 ); } - - /*public void FlipX() - { - if (LightSprite != null) - { - Vector2 lightOrigin = LightSprite.Origin; - lightOrigin.X = LightSprite.SourceRect.Width - lightOrigin.X; - LightSprite.Origin = lightOrigin; - } - - if (overrideLightTexture != null) - { - Vector2 lightOrigin = overrideLightTexture.Origin; - lightOrigin.X = overrideLightTexture.SourceRect.Width - lightOrigin.X; - overrideLightTexture.Origin = lightOrigin; - } - }*/ - + public void Remove() { if (LightSprite != null) LightSprite.Remove(); diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml b/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml index 5678f0bd5..3446ecb5c 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml @@ -27,8 +27,8 @@ - - + + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml b/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml index d89840630..9d47023d1 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml @@ -33,8 +33,8 @@ - - + + diff --git a/Barotrauma/BarotraumaShared/Content/Items/Electricity/lights.xml b/Barotrauma/BarotraumaShared/Content/Items/Electricity/lights.xml index b3a87ee2f..9cc412b86 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Electricity/lights.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Electricity/lights.xml @@ -11,7 +11,7 @@ - + @@ -31,7 +31,7 @@ - + diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index 8a0168313..9bef9f2a4 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -120,14 +120,6 @@ namespace Barotrauma.Items.Components #endif IsActive = IsOn; - - //foreach (XElement subElement in element.Elements()) - //{ - // if (subElement.Name.ToString().ToLowerInvariant() != "sprite") continue; - - // light.LightSprite = new Sprite(subElement); - // break; - //} } public override void Update(float deltaTime, Camera cam)