Build 0.18.2.0
This commit is contained in:
@@ -11,6 +11,18 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
class LightManager
|
||||
{
|
||||
/// <summary>
|
||||
/// How many light sources are allowed to recalculate their light volumes per frame.
|
||||
/// Pending calculations will be done on subsequent frames, starting from the light sources that have been waiting for a recalculation the longest.
|
||||
/// </summary>
|
||||
const int MaxLightVolumeRecalculationsPerFrame = 5;
|
||||
|
||||
/// <summary>
|
||||
/// If zoomed further out than this, characters no longer obstruct lights behind them.
|
||||
/// Improves performance, and isn't very noticeable if we do it after zoomed far out enough.
|
||||
/// </summary>
|
||||
const float ObstructLightsBehindCharactersZoomThreshold = 0.5f;
|
||||
|
||||
public static Entity ViewTarget { get; set; }
|
||||
|
||||
private float currLightMapScale;
|
||||
@@ -59,6 +71,8 @@ namespace Barotrauma.Lights
|
||||
|
||||
private Vector2 losOffset;
|
||||
|
||||
private int recalculationCount;
|
||||
|
||||
public IEnumerable<LightSource> Lights
|
||||
{
|
||||
get { return lights; }
|
||||
@@ -151,6 +165,9 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
private readonly List<LightSource> activeLights = new List<LightSource>(capacity: 100);
|
||||
private readonly List<LightSource> activeLightsWithLightVolume = new List<LightSource>(capacity: 100);
|
||||
|
||||
public static int ActiveLightCount { get; private set; }
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
@@ -180,11 +197,13 @@ namespace Barotrauma.Lights
|
||||
Rectangle viewRect = cam.WorldView;
|
||||
viewRect.Y -= cam.WorldView.Height;
|
||||
//check which lights need to be drawn
|
||||
recalculationCount = 0;
|
||||
activeLights.Clear();
|
||||
foreach (LightSource light in lights)
|
||||
{
|
||||
if (!light.Enabled) { continue; }
|
||||
if ((light.Color.A < 1 || light.Range < 1.0f) && !light.LightSourceParams.OverrideLightSpriteAlpha.HasValue) { continue; }
|
||||
|
||||
if (light.ParentBody != null)
|
||||
{
|
||||
light.ParentBody.UpdateDrawPosition();
|
||||
@@ -205,8 +224,44 @@ namespace Barotrauma.Lights
|
||||
range = Math.Max(Math.Max(spriteRange, targetSize), range);
|
||||
}
|
||||
if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, range, viewRect)) { continue; }
|
||||
activeLights.Add(light);
|
||||
|
||||
light.Priority = lightPriority(range, light);
|
||||
|
||||
int i = 0;
|
||||
while (i < activeLights.Count && light.Priority < activeLights[i].Priority)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
activeLights.Insert(i, light);
|
||||
}
|
||||
ActiveLightCount = activeLights.Count;
|
||||
|
||||
float lightPriority(float range, LightSource light)
|
||||
{
|
||||
return
|
||||
range *
|
||||
((Character.Controlled?.Submarine != null && light.ParentSub == Character.Controlled?.Submarine) ? 2.0f : 1.0f) *
|
||||
(light.CastShadows ? 10.0f : 1.0f) *
|
||||
(light.LightSourceParams.OverrideLightSpriteAlpha ?? (light.Color.A / 255.0f));
|
||||
}
|
||||
|
||||
//find the lights with an active light volume
|
||||
activeLightsWithLightVolume.Clear();
|
||||
foreach (var activeLight in activeLights)
|
||||
{
|
||||
if (activeLight.Range < 1.0f || activeLight.Color.A < 1 || activeLight.CurrentBrightness <= 0.0f) { continue; }
|
||||
activeLightsWithLightVolume.Add(activeLight);
|
||||
}
|
||||
|
||||
//remove some lights with a light volume if there's too many of them
|
||||
if (activeLightsWithLightVolume.Count > GameSettings.CurrentConfig.Graphics.VisibleLightLimit)
|
||||
{
|
||||
for (int i = GameSettings.CurrentConfig.Graphics.VisibleLightLimit; i < activeLightsWithLightVolume.Count; i++)
|
||||
{
|
||||
activeLights.Remove(activeLightsWithLightVolume[i]);
|
||||
}
|
||||
}
|
||||
activeLights.Sort((l1, l2) => l1.LastRecalculationTime.CompareTo(l2.LastRecalculationTime));
|
||||
|
||||
//draw light sprites attached to characters
|
||||
//render into a separate rendertarget using alpha blending (instead of on top of everything else with alpha blending)
|
||||
@@ -235,7 +290,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (!light.IsBackground || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
light.DrawSprite(spriteBatch, cam);
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform, recalculationCount < MaxLightVolumeRecalculationsPerFrame, ref recalculationCount);
|
||||
}
|
||||
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
|
||||
spriteBatch.End();
|
||||
@@ -243,14 +298,6 @@ namespace Barotrauma.Lights
|
||||
//draw a black rectangle on hulls to hide background lights behind subs
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
/*if (backgroundObstructor != null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
spriteBatch.Draw(backgroundObstructor, new Rectangle(0, 0,
|
||||
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.Black);
|
||||
spriteBatch.End();
|
||||
}*/
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, transformMatrix: spriteBatchTransform);
|
||||
Dictionary<Hull, Rectangle> visibleHulls = GetVisibleHulls(cam);
|
||||
foreach (KeyValuePair<Hull, Rectangle> hull in visibleHulls)
|
||||
@@ -292,41 +339,44 @@ namespace Barotrauma.Lights
|
||||
|
||||
//draw characters to obstruct the highlighted items/characters and light sprites
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidVertexColor"];
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
if (cam.Zoom > ObstructLightsBehindCharactersZoomThreshold)
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidVertexColor"];
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, effect: SolidColorEffect, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (limb.DeformSprite != null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.DeformSprite != null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
spriteBatch.End();
|
||||
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidVertexColor"];
|
||||
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidVertexColor"];
|
||||
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform);
|
||||
foreach (Character character in Character.CharacterList)
|
||||
{
|
||||
if (limb.DeformSprite == null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.DeformSprite == null) { continue; }
|
||||
limb.Draw(spriteBatch, cam, lightColor);
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShader"];
|
||||
graphics.BlendState = BlendState.Additive;
|
||||
|
||||
@@ -344,7 +394,7 @@ namespace Barotrauma.Lights
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (light.IsBackground || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform, recalculationCount < MaxLightVolumeRecalculationsPerFrame, ref recalculationCount);
|
||||
}
|
||||
|
||||
lightEffect.World = transform;
|
||||
|
||||
Reference in New Issue
Block a user