diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index d3fec144f..0834ecf4e 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -279,7 +279,6 @@ - diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index 4ffff9d67..42dcea3e4 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -71,22 +71,6 @@ namespace ClassicalSharp { return obj; } - public bool ReplaceComponent(ref T old, T obj) where T : IGameComponent { - for (int i = 0; i < Components.Count; i++) { - if (!object.ReferenceEquals(Components[i], old)) continue; - old.Dispose(); - - Components[i] = obj; - old = obj; - obj.Init(this); - return true; - } - - Components.Add(obj); - obj.Init(this); - return false; - } - public void SetViewDistance(float distance, bool userDist) { if (userDist) { UserViewDistance = distance; @@ -427,18 +411,13 @@ namespace ClassicalSharp { MapBordersRenderer.UseLegacyMode(legacy); } - if (minimal) { - if (EnvRenderer == null) - EnvRenderer = AddComponent(new MinimalEnvRenderer()); - else - ReplaceComponent(ref EnvRenderer, new MinimalEnvRenderer()); - } else if (EnvRenderer == null) { + if (EnvRenderer == null) { EnvRenderer = AddComponent(new StandardEnvRenderer()); - ((StandardEnvRenderer)EnvRenderer).legacy = legacy; + EnvRenderer.legacy = legacy; + EnvRenderer.minimal = minimal; } else { - if (!(EnvRenderer is StandardEnvRenderer)) - ReplaceComponent(ref EnvRenderer, new StandardEnvRenderer()); - ((StandardEnvRenderer)EnvRenderer).UseLegacyMode(legacy); + EnvRenderer.UseLegacyMode(legacy); + EnvRenderer.UseMinimalMode(minimal); } } diff --git a/ClassicalSharp/Game/GuiInterface.cs b/ClassicalSharp/Game/GuiInterface.cs index 44f7db240..2f2e41d75 100644 --- a/ClassicalSharp/Game/GuiInterface.cs +++ b/ClassicalSharp/Game/GuiInterface.cs @@ -109,7 +109,7 @@ namespace ClassicalSharp { public void Render(double delta) { - gfx.Mode2D(game.Width, game.Height, game.EnvRenderer is StandardEnvRenderer); + gfx.Mode2D(game.Width, game.Height, !game.EnvRenderer.minimal); if (activeScreen == null || !activeScreen.HidesHud) fpsScreen.Render(delta); @@ -122,7 +122,7 @@ namespace ClassicalSharp { if (overlays.Count > 0) overlays[0].Render(delta); - gfx.Mode3D(game.EnvRenderer is StandardEnvRenderer); + gfx.Mode3D(!game.EnvRenderer.minimal); } internal void OnResize() { diff --git a/ClassicalSharp/Rendering/Env/EnvRenderer.cs b/ClassicalSharp/Rendering/Env/EnvRenderer.cs index 6e3c4140e..98a88ac7b 100644 --- a/ClassicalSharp/Rendering/Env/EnvRenderer.cs +++ b/ClassicalSharp/Rendering/Env/EnvRenderer.cs @@ -18,6 +18,7 @@ namespace ClassicalSharp.Renderers { protected World map; protected Game game; protected IGraphicsApi gfx; + protected internal bool legacy, minimal; public virtual void Init(Game game) { this.game = game; @@ -28,6 +29,11 @@ namespace ClassicalSharp.Renderers { public virtual void UseLegacyMode(bool legacy) { } + /// Sets mode to minimal environment rendering. + /// - only sets the background/clear colour to blended fog colour. + /// (no smooth fog, clouds, or proper overhead sky) + public virtual void UseMinimalMode(bool minimal) { } + public void Ready(Game game) { } public virtual void Reset(Game game) { OnNewMap(game); } diff --git a/ClassicalSharp/Rendering/Env/MinimalEnvRenderer.cs b/ClassicalSharp/Rendering/Env/MinimalEnvRenderer.cs deleted file mode 100644 index a474ca1e2..000000000 --- a/ClassicalSharp/Rendering/Env/MinimalEnvRenderer.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 -using ClassicalSharp.Events; -using System; - -#if USE16_BIT -using BlockID = System.UInt16; -#else -using BlockID = System.Byte; -#endif - -namespace ClassicalSharp.Renderers { - /// Minimialistic environment renderer - /// - only sets the background/clear colour to blended fog colour. - /// (no smooth fog, clouds, or proper overhead sky) - public class MinimalEnvRenderer : EnvRenderer { - - public override void Init(Game game) { - base.Init(game); - gfx.Fog = false; - gfx.ClearColour(map.Env.SkyCol); - } - - public override void Render(double deltaTime) { - if (map.blocks == null) return; - FastColour fogCol = FastColour.White; - float fogDensity = 0; - BlockID block = BlockOn(out fogDensity, out fogCol); - gfx.ClearColour(fogCol); - - // TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often - if (fogDensity != 0) { - // Exp fog mode: f = e^(-density*coord) - // Solve for f = 0.05 to figure out coord (good approx for fog end) - float dist = (float)Math.Log(0.05) / -fogDensity; - game.SetViewDistance(dist, false); - } else { - game.SetViewDistance(game.UserViewDistance, false); - } - } - - public override void OnNewMap(Game game) { } - public override void OnNewMapLoaded(Game game) { } - protected override void EnvVariableChanged(object sender, EnvVarEventArgs e) { } - } -} diff --git a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs index 9fdcdd393..191602b7a 100644 --- a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs +++ b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs @@ -13,7 +13,7 @@ namespace ClassicalSharp.Renderers { const int count = 6 * 4; public bool ShouldRender { - get { return tex > 0 && !(game.EnvRenderer is MinimalEnvRenderer); } + get { return tex > 0 && !(game.EnvRenderer.minimal); } } public void Init(Game game) { diff --git a/ClassicalSharp/Rendering/Env/StandardEnvRenderer.cs b/ClassicalSharp/Rendering/Env/StandardEnvRenderer.cs index cf8947043..e4041f9c0 100644 --- a/ClassicalSharp/Rendering/Env/StandardEnvRenderer.cs +++ b/ClassicalSharp/Rendering/Env/StandardEnvRenderer.cs @@ -15,20 +15,111 @@ namespace ClassicalSharp.Renderers { public unsafe class StandardEnvRenderer : EnvRenderer { int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices; - internal bool legacy; public override void UseLegacyMode(bool legacy) { this.legacy = legacy; ContextRecreated(); } + public override void UseMinimalMode(bool minimal) { + this.minimal = minimal; + ContextRecreated(); + } + public override void Render(double deltaTime) { + if (minimal) { RenderMinimal(deltaTime); return; } + if (skyVb == -1 || cloudsVb == -1) return; - if (!game.SkyboxRenderer.ShouldRender) - RenderMainEnv(deltaTime); + if (!game.SkyboxRenderer.ShouldRender) RenderMainEnv(deltaTime); UpdateFog(); } + protected override void EnvVariableChanged(object sender, EnvVarEventArgs e) { + if (minimal) return; + + if (e.Var == EnvVar.SkyColour) { + ResetSky(); + } else if (e.Var == EnvVar.FogColour) { + UpdateFog(); + } else if (e.Var == EnvVar.CloudsColour) { + ResetClouds(); + } else if (e.Var == EnvVar.CloudsLevel) { + ResetSky(); + ResetClouds(); + } + } + + public override void Init(Game game) { + base.Init(game); + ResetAllEnv(null, null); + + game.Events.ViewDistanceChanged += ResetAllEnv; + game.Graphics.ContextLost += ContextLost; + game.Graphics.ContextRecreated += ContextRecreated; + game.SetViewDistance(game.UserViewDistance, false); + } + + public override void OnNewMap(Game game) { + gfx.Fog = false; + gfx.DeleteVb(ref skyVb); + gfx.DeleteVb(ref cloudsVb); + } + + public override void OnNewMapLoaded(Game game) { + gfx.Fog = !minimal; + ResetAllEnv(null, null); + } + + void ResetAllEnv(object sender, EventArgs e) { + UpdateFog(); + ContextRecreated(); + } + + public override void Dispose() { + base.Dispose(); + ContextLost(); + + game.Events.ViewDistanceChanged -= ResetAllEnv; + game.Graphics.ContextLost -= ContextLost; + game.Graphics.ContextRecreated -= ContextRecreated; + } + + void ContextLost() { + game.Graphics.DeleteVb(ref skyVb); + game.Graphics.DeleteVb(ref cloudsVb); + } + + void ContextRecreated() { + ContextLost(); + gfx.Fog = !minimal; + + if (minimal) { + gfx.ClearColour(map.Env.SkyCol); + } else { + gfx.SetFogStart(0); + ResetClouds(); + ResetSky(); + } + } + + void RenderMinimal(double deltaTime) { + if (map.blocks == null) return; + FastColour fogCol = FastColour.White; + float fogDensity = 0; + BlockID block = BlockOn(out fogDensity, out fogCol); + gfx.ClearColour(fogCol); + + // TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often + if (fogDensity != 0) { + // Exp fog mode: f = e^(-density*coord) + // Solve for f = 0.05 to figure out coord (good approx for fog end) + float dist = (float)Math.Log(0.05) / -fogDensity; + game.SetViewDistance(dist, false); + } else { + game.SetViewDistance(game.UserViewDistance, false); + } + } + void RenderMainEnv(double deltaTime) { Vector3 pos = game.CurrentCameraPos; float normalY = map.Height + 8; @@ -50,56 +141,6 @@ namespace ClassicalSharp.Renderers { RenderClouds(deltaTime); } - protected override void EnvVariableChanged(object sender, EnvVarEventArgs e) { - if (e.Var == EnvVar.SkyColour) { - ResetSky(); - } else if (e.Var == EnvVar.FogColour) { - UpdateFog(); - } else if (e.Var == EnvVar.CloudsColour) { - ResetClouds(); - } else if (e.Var == EnvVar.CloudsLevel) { - ResetSky(); - ResetClouds(); - } - } - - public override void Init(Game game) { - base.Init(game); - gfx.SetFogStart(0); - gfx.Fog = true; - ResetAllEnv(null, null); - - game.Events.ViewDistanceChanged += ResetAllEnv; - game.Graphics.ContextLost += ContextLost; - game.Graphics.ContextRecreated += ContextRecreated; - game.SetViewDistance(game.UserViewDistance, false); - } - - public override void OnNewMap(Game game) { - gfx.Fog = false; - gfx.DeleteVb(ref skyVb); - gfx.DeleteVb(ref cloudsVb); - } - - public override void OnNewMapLoaded(Game game) { - gfx.Fog = true; - ResetAllEnv(null, null); - } - - void ResetAllEnv(object sender, EventArgs e) { - UpdateFog(); - ContextRecreated(); - } - - public override void Dispose() { - base.Dispose(); - ContextLost(); - - game.Events.ViewDistanceChanged -= ResetAllEnv; - game.Graphics.ContextLost -= ContextLost; - game.Graphics.ContextRecreated -= ContextRecreated; - } - void RenderClouds(double delta) { if (game.World.Env.CloudHeight < -2000) return; double time = game.accumulator; @@ -124,7 +165,7 @@ namespace ClassicalSharp.Renderers { } void UpdateFog() { - if (map.blocks == null) return; + if (map.blocks == null || minimal) return; FastColour fogCol = FastColour.White; float fogDensity = 0; BlockID block = BlockOn(out fogDensity, out fogCol); @@ -162,17 +203,6 @@ namespace ClassicalSharp.Renderers { RebuildSky((int)game.ViewDistance, legacy ? 128 : 65536); } - void ContextLost() { - game.Graphics.DeleteVb(ref skyVb); - game.Graphics.DeleteVb(ref cloudsVb); - } - - void ContextRecreated() { - ResetClouds(); - ResetSky(); - } - - void RebuildClouds(int extent, int axisSize) { extent = Utils.AdjViewDist(extent); int x1 = -extent, x2 = map.Width + extent;