From d35fbb0bb3e2842f8d33b48d621bed7563a0db60 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 19 Oct 2021 22:24:21 +0200 Subject: [PATCH] New configs --- .../bufferBuilding/LodBufferBuilder.java | 4 +- .../bufferBuilding/lodTemplates/Box.java | 2 +- .../lod/builders/lodBuilding/LodBuilder.java | 2 +- .../worldGeneration/LodNodeGenWorker.java | 4 +- .../worldGeneration/LodWorldGenerator.java | 2 +- .../java/com/seibel/lod/config/LodConfig.java | 739 +++++++++--------- .../com/seibel/lod/enums/DetailDropOff.java | 35 - .../seibel/lod/mixin/MixinWorldRenderer.java | 2 +- .../com/seibel/lod/objects/LodDimension.java | 2 +- .../com/seibel/lod/objects/LodRegion.java | 31 +- .../com/seibel/lod/proxy/ClientProxy.java | 16 +- .../com/seibel/lod/render/LodRenderer.java | 74 +- .../seibel/lod/util/DetailDistanceUtil.java | 30 +- .../java/com/seibel/lod/util/LodUtil.java | 7 +- 14 files changed, 463 insertions(+), 487 deletions(-) delete mode 100644 src/main/java/com/seibel/lod/enums/DetailDropOff.java diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java index 609c9b5ea..e1e2a4ae5 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java @@ -67,7 +67,7 @@ public class LodBufferBuilder /** The thread used to generate new LODs off the main thread. */ public static final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(LodBufferBuilder.class.getSimpleName() + " - main")); /** The threads used to generate buffers. */ - public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfBufferBuilderThreads.get(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); + public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfBufferBuilderThreads.get(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); /** * When uploading to a buffer that is too small, @@ -393,7 +393,7 @@ public class LodBufferBuilder if (DataPointUtil.isVoid(data) || !DataPointUtil.doesItExist(data)) break; - LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, + LodConfig.CLIENT.graphics.advancedOption.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, detailLevel, posX, posZ, box, renderer.previousDebugMode, renderer.lightMap, adjShadeDisabled); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java index a9e3ccd30..56c135d95 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java @@ -218,7 +218,7 @@ public class Box */ public int getColor(Direction direction) { - if (LodConfig.CLIENT.debugging.debugMode.get() != DebugMode.SHOW_DETAIL) + if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != DebugMode.SHOW_DETAIL) return colorMap[DIRECTION_INDEX.get(direction)]; else return ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientWorld().getShade(direction, true)); diff --git a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java index ea77b7af9..ef70eb793 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -213,7 +213,7 @@ public class LodBuilder // determine how many LODs to generate vertically - VerticalQuality verticalQuality = LodConfig.CLIENT.worldGenerator.verticalQuality.get(); + VerticalQuality verticalQuality = LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); byte detailLevel = detail.detailLevel; diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java index 63f24bb6c..2a133a813 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java @@ -75,7 +75,7 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker; */ public class LodNodeGenWorker implements IWorker { - public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); + public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); private boolean threadStarted = false; private final LodChunkGenThread thread; @@ -679,7 +679,7 @@ public class LodNodeGenWorker implements IWorker { genThreads.shutdownNow(); } - genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); + genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); } diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java index 01724ba5a..0339cbdf8 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -80,7 +80,7 @@ public class LodWorldGenerator generatorThreadRunning = true; // just in case the config changed - maxChunkGenRequests = LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get() * 8; + maxChunkGenRequests = LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get() * 8; Thread generatorThread = new Thread(() -> { diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index da252ca30..a2cf9bccf 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -47,9 +47,7 @@ public class LodConfig { public final Graphics graphics; public final WorldGenerator worldGenerator; - public final Threading threading; - public final Debugging debugging; - public final Buffers buffers; + public final AdvancedModOptions advancedModOptions; public Client(ForgeConfigSpec.Builder builder) { @@ -57,376 +55,415 @@ public class LodConfig { graphics = new Graphics(builder); worldGenerator = new WorldGenerator(builder); - threading = new Threading(builder); - debugging = new Debugging(builder); - buffers = new Buffers(builder); + advancedModOptions = new AdvancedModOptions(builder); } builder.pop(); } - } - - //================// - // Client Configs // - //================// - - public static class Graphics - { - public final ForgeConfigSpec.EnumValue fogDistance; - public final ForgeConfigSpec.EnumValue fogDrawOverride; - public final ForgeConfigSpec.EnumValue lodTemplate; + //================// + // Client Configs // + //================// - public final ForgeConfigSpec.EnumValue drawResolution; - - public final ForgeConfigSpec.EnumValue detailDropOff; - - public final ForgeConfigSpec.IntValue lodChunkRenderDistance; - - public final ForgeConfigSpec.BooleanValue disableDirectionalCulling; - - public final ForgeConfigSpec.BooleanValue alwaysDrawAtMaxQuality; - - public final ForgeConfigSpec.BooleanValue drawLods; - - public final ForgeConfigSpec.EnumValue vanillaOverdraw; - - Graphics(ForgeConfigSpec.Builder builder) + public static class Graphics { - builder.comment("These settings control how the LODs look.").push(this.getClass().getSimpleName()); - drawLods = builder - .comment("\n\n" - + " If true, the mod is enabled and LODs will be drawn. \n" - + " If false, the mod will still generate LODs, \n" - + " but they won't be rendered. \n") - .define("Draw LODs", true); + public final QualityOption qualityOption; + public final FogQualityOption fogQualityOption; + public final AdvancedOption advancedOption; - fogDistance = builder - .comment("\n\n" - + " At what distance should Fog be drawn on the LODs? \n" - + " If the fog cuts off abruptly or you are using Optifine's \"fast\" fog option \n" - + " set this to " + FogDistance.NEAR + " or " + FogDistance.FAR + ". \n") - .defineEnum("Fog Distance", FogDistance.NEAR_AND_FAR); + Graphics(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings control how LODs will look in game").push(this.getClass().getSimpleName()); + { + qualityOption = new QualityOption(builder); + fogQualityOption = new FogQualityOption(builder); + advancedOption = new AdvancedOption(builder); + } + builder.pop(); + } - fogDrawOverride = builder - .comment("\n\n" - + " When should fog be drawn? \n" - + " " + FogDrawOverride.USE_OPTIFINE_FOG_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ". \n" - + " " + FogDrawOverride.NEVER_DRAW_FOG + ": Never draw fog on the LODs \n" - + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FAST + ": Always draw fast fog on the LODs \n" - + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n") - .defineEnum("Fog Draw Override", FogDrawOverride.ALWAYS_DRAW_FOG_FANCY); + public static class QualityOption + { + public final ForgeConfigSpec.EnumValue drawResolution; + + public final ForgeConfigSpec.IntValue lodChunkRenderDistance; + + public final ForgeConfigSpec.EnumValue verticalQuality; + + public final ForgeConfigSpec.EnumValue horizontalScale; + + public final ForgeConfigSpec.EnumValue horizontalQuality; + + + QualityOption(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings control how the LODs look.").push(this.getClass().getSimpleName()); + + verticalQuality = builder + .comment("\n\n" + + " This indicates how detailed LODs will represent \n" + + " overhangs, caves, floating islands, ect. \n" + + " Higher options will use more memory and increase GPU usage. \n" + + " " + VerticalQuality.LOW + ": uses at max 2 columns per position. \n" + + " " + VerticalQuality.MEDIUM + ": uses at max 4 columns per position. \n" + + " " + VerticalQuality.HIGH + ": uses at max 8 columns per position. \n") + .defineEnum("Vertical Quality", VerticalQuality.MEDIUM); + + + horizontalScale = builder + .comment("\n\n" + + " This indicates how quickly LODs drop off in quality. \n" + + " " + HorizontalScale.LOW + ": quality drops every " + HorizontalScale.LOW.distanceUnit / 16 + " chunks. \n" + + " " + HorizontalScale.MEDIUM + ": quality drops every " + HorizontalScale.MEDIUM.distanceUnit / 16 + " chunks. \n" + + " " + HorizontalScale.HIGH + ": quality drops every " + HorizontalScale.HIGH.distanceUnit / 16 + " chunks. \n") + .defineEnum("Horizontal Scale", HorizontalScale.MEDIUM); + + horizontalQuality = builder + .comment("\n\n" + + " This indicates the exponential base of the quadratic drop-off \n" + + " " + HorizontalQuality.LOWEST + ": base " + HorizontalQuality.LOWEST.quadraticBase + ". \n" + + " " + HorizontalQuality.LOW + ": base " + HorizontalQuality.LOW.quadraticBase + ". \n" + + " " + HorizontalQuality.MEDIUM + ": base " + HorizontalQuality.MEDIUM.quadraticBase + ". \n" + + " " + HorizontalQuality.HIGH + ": base " + HorizontalQuality.HIGH.quadraticBase + ". \n") + .defineEnum("Horizontal Quality", HorizontalQuality.MEDIUM); + + drawResolution = builder + .comment("\n\n" + + " What is the maximum detail LODs should be drawn at? \n" + + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n" + + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n" + + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n" + + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n" + + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n") + .defineEnum("Block size", HorizontalResolution.BLOCK); + + lodChunkRenderDistance = builder + .comment("\n\n" + + " The mod's render distance, measured in chunks. \n") + .defineInRange("Lod Render Distance", 64, 32, 1024); + + builder.pop(); + } + } - lodTemplate = builder - .comment("\n\n" - + " How should the LODs be drawn? \n" - + " NOTE: Currently only " + LodTemplate.CUBIC + " is implemented! \n" - + " \n" - + " " + LodTemplate.CUBIC + ": LOD Chunks are drawn as rectangular prisms (boxes). \n" - + " " + LodTemplate.TRIANGULAR + ": LOD Chunks smoothly transition between other. \n" - + " " + LodTemplate.DYNAMIC + ": LOD Chunks smoothly transition between each other, \n" - + " " + " unless a neighboring chunk is at a significantly different height. \n") - .defineEnum("LOD Template", LodTemplate.CUBIC); + public static class FogQualityOption + { + public final ForgeConfigSpec.EnumValue fogDistance; + + public final ForgeConfigSpec.EnumValue fogDrawOverride; + + FogQualityOption(ForgeConfigSpec.Builder builder) + { + + builder.comment("These settings control the fog quality.").push(this.getClass().getSimpleName()); + + fogDistance = builder + .comment("\n\n" + + " At what distance should Fog be drawn on the LODs? \n" + + " If the fog cuts off abruptly or you are using Optifine's \"fast\" fog option \n" + + " set this to " + FogDistance.NEAR + " or " + FogDistance.FAR + ". \n") + .defineEnum("Fog Distance", FogDistance.NEAR_AND_FAR); + + fogDrawOverride = builder + .comment("\n\n" + + " When should fog be drawn? \n" + + " " + FogDrawOverride.USE_OPTIFINE_FOG_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ". \n" + + " " + FogDrawOverride.NEVER_DRAW_FOG + ": Never draw fog on the LODs \n" + + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FAST + ": Always draw fast fog on the LODs \n" + + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n") + .defineEnum("Fog Draw Override", FogDrawOverride.ALWAYS_DRAW_FOG_FANCY); + builder.pop(); + } + } - detailDropOff = builder - .comment("\n\n" - + " How smooth should the detail transition for LODs be? \n" - + DetailDropOff.FANCY + ": quality is determined per-chunk (best quality option, may cause stuttering when moving)\n" - + DetailDropOff.FAST + ": quality is determined per-region \n") - .defineEnum("Detail DropOff", DetailDropOff.FANCY); - - drawResolution = builder - .comment("\n\n" - + " What is the maximum detail LODs should be drawn at? \n" - + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n" - + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n" - + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n" - + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n" - + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n") - .defineEnum("Draw resolution", HorizontalResolution.BLOCK); - - lodChunkRenderDistance = builder - .comment("\n\n" - + " The mod's render distance, measured in chunks. \n") - .defineInRange("Lod Render Distance", 64, 32, 1024); - - disableDirectionalCulling = builder - .comment("\n\n" - + " If false LODs that are behind the player's camera \n" - + " aren't drawn, increasing performance. \n\n" - + "" - + " If true all LODs are drawn, even those behind \n" - + " the player's camera, decreasing performance. \n\n" - + "" - + " Disable this if you see LODs disappearing. \n" - + " (Which may happen if you are using a camera mod) \n") - .define("Disable Directional Culling", false); - - alwaysDrawAtMaxQuality = builder - .comment("\n\n" - + " Disable LOD quality falloff, \n" - + " all LODs will be drawn at the highest \n" - + " available detail level. \n\n" - + " " - + " WARNING: \n" - + " This could cause a Out Of Memory crash on render \n" - + " distances higher than 128 \n") - .define("Always Use Max Quality", false); - - vanillaOverdraw = builder - .comment("\n\n" - + " How often should LODs be drawn on top of regular chunks? \n" - + " HALF and ALWAYS will prevent holes in the world, but may look odd for transparent blocks or in caves. \n\n" - + " " + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n" - + " " + VanillaOverdraw.DYNAMIC + ": LODs will render on top of distant vanilla chunks to hide delayed loading. \n" - + " " + " More effective on higher render distances. \n" - + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " \n" - + " " + " " + VanillaOverdraw.NEVER + " or " + VanillaOverdraw.ALWAYS + " may be used depending on the dimension. \n" - + " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n") - .defineEnum("Vanilla Overdraw", VanillaOverdraw.DYNAMIC); - - builder.pop(); + public static class AdvancedOption + { + public final ForgeConfigSpec.EnumValue lodTemplate; + + public final ForgeConfigSpec.BooleanValue disableDirectionalCulling; + + public final ForgeConfigSpec.BooleanValue alwaysDrawAtMaxQuality; + + public final ForgeConfigSpec.EnumValue vanillaOverdraw; + + AdvancedOption(ForgeConfigSpec.Builder builder) + { + + lodTemplate = builder + .comment("\n\n" + + " How should the LODs be drawn? \n" + + " NOTE: Currently only " + LodTemplate.CUBIC + " is implemented! \n" + + " \n" + + " " + LodTemplate.CUBIC + ": LOD Chunks are drawn as rectangular prisms (boxes). \n" + + " " + LodTemplate.TRIANGULAR + ": LOD Chunks smoothly transition between other. \n" + + " " + LodTemplate.DYNAMIC + ": LOD Chunks smoothly transition between each other, \n" + + " " + " unless a neighboring chunk is at a significantly different height. \n") + .defineEnum("LOD Template", LodTemplate.CUBIC); + + disableDirectionalCulling = builder + .comment("\n\n" + + " If false LODs that are behind the player's camera \n" + + " aren't drawn, increasing performance. \n\n" + + "" + + " If true all LODs are drawn, even those behind \n" + + " the player's camera, decreasing performance. \n\n" + + "" + + " Disable this if you see LODs disappearing. \n" + + " (Which may happen if you are using a camera mod) \n") + .define("Disable Directional Culling", false); + + alwaysDrawAtMaxQuality = builder + .comment("\n\n" + + " Disable LOD quality falloff, \n" + + " all LODs will be drawn at the highest \n" + + " available detail level. \n\n" + + " " + + " WARNING: \n" + + " This could cause a Out Of Memory crash on render \n" + + " distances higher than 128 \n") + .define("Always Use Max Quality", false); + + vanillaOverdraw = builder + .comment("\n\n" + + " How often should LODs be drawn on top of regular chunks? \n" + + " HALF and ALWAYS will prevent holes in the world, but may look odd for transparent blocks or in caves. \n\n" + + " " + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n" + + " " + VanillaOverdraw.DYNAMIC + ": LODs will render on top of distant vanilla chunks to hide delayed loading. \n" + + " " + " More effective on higher render distances. \n" + + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " \n" + + " " + " " + VanillaOverdraw.NEVER + " or " + VanillaOverdraw.ALWAYS + " may be used depending on the dimension. \n" + + " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n") + .defineEnum("Vanilla Overdraw", VanillaOverdraw.DYNAMIC); + builder.pop(); + } + } } - } - - public static class WorldGenerator - { - public final ForgeConfigSpec.EnumValue verticalQuality; - public final ForgeConfigSpec.EnumValue generationResolution; - public final ForgeConfigSpec.EnumValue distanceGenerationMode; - public final ForgeConfigSpec.EnumValue generationPriority; - public final ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration; - public final ForgeConfigSpec.EnumValue horizontalScale; - public final ForgeConfigSpec.EnumValue horizontalQuality; - public final ForgeConfigSpec.EnumValue blockToAvoid; - //public final ForgeConfigSpec.BooleanValue useExperimentalPreGenLoading; - WorldGenerator(ForgeConfigSpec.Builder builder) + public static class WorldGenerator { - builder.comment("These settings control how LODs outside your normal view range are generated.").push(this.getClass().getSimpleName()); + public final ForgeConfigSpec.EnumValue generationPriority; + public final ForgeConfigSpec.EnumValue distanceGenerationMode; + public final ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration; + public final ForgeConfigSpec.EnumValue blockToAvoid; + //public final ForgeConfigSpec.BooleanValue useExperimentalPreGenLoading; - verticalQuality = builder - .comment("\n\n" - + " This indicates how detailed LODs will represent \n" - + " overhangs, caves, floating islands, ect. \n" - + " Higher options will use more memory and increase GPU usage. \n" - + " " + VerticalQuality.LOW + ": uses at max 2 columns per position. \n" - + " " + VerticalQuality.MEDIUM + ": uses at max 4 columns per position. \n" - + " " + VerticalQuality.HIGH + ": uses at max 8 columns per position. \n") - .defineEnum("Vertical Quality", VerticalQuality.MEDIUM); - - - - generationResolution = builder - .comment("\n\n" - + " What is the maximum detail level that LODs should be generated at? \n" - + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n" - + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n" - + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n" - + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n" - + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n") - .defineEnum("Generation Resolution", HorizontalResolution.BLOCK); - - horizontalScale = builder - .comment("\n\n" - + " This indicates how quickly LODs drop off in quality. \n" - + " " + HorizontalScale.LOW + ": quality drops every " + HorizontalScale.LOW.distanceUnit / 16 + " chunks. \n" - + " " + HorizontalScale.MEDIUM + ": quality drops every " + HorizontalScale.MEDIUM.distanceUnit / 16 + " chunks. \n" - + " " + HorizontalScale.HIGH + ": quality drops every " + HorizontalScale.HIGH.distanceUnit / 16 + " chunks. \n") - .defineEnum("Horizontal Scale", HorizontalScale.MEDIUM); - - horizontalQuality = builder - .comment("\n\n" - + " This indicates the exponential base of the quadratic drop-off \n" - + " " + HorizontalQuality.LOWEST + ": base " + HorizontalQuality.LOWEST.quadraticBase + ". \n" - + " " + HorizontalQuality.LOW + ": base " + HorizontalQuality.LOW.quadraticBase + ". \n" - + " " + HorizontalQuality.MEDIUM + ": base " + HorizontalQuality.MEDIUM.quadraticBase + ". \n" - + " " + HorizontalQuality.HIGH + ": base " + HorizontalQuality.HIGH.quadraticBase + ". \n") - .defineEnum("Horizontal Quality", HorizontalQuality.MEDIUM); - - generationPriority = builder - .comment("\n\n" - + " " + GenerationPriority.FAR_FIRST + " \n" - + " LODs are generated from low to high detail \n" - + " with a small priority for far away regions. \n" - + " This fills in the world fastest. \n\n" - + "" - + " " + GenerationPriority.NEAR_FIRST + " \n" - + " LODs are generated around the player \n" - + " in a spiral, similar to vanilla minecraft. \n") - .defineEnum("Generation Priority", GenerationPriority.FAR_FIRST); - - distanceGenerationMode = builder - .comment("\n\n" - + " Note: The times listed here are the amount of time it took \n" - + " one of the developer's PC to generate 1 chunk, \n" - + " and are included so you can compare the \n" - + " different generation options. Your mileage may vary. \n" - + "\n" - - + " " + DistanceGenerationMode.NONE + " \n" - + " Don't run the distance generator. \n" - - + "\n" - + " " + DistanceGenerationMode.BIOME_ONLY + " \n" - + " Only generate the biomes and use the biome's \n" - + " grass color, water color, or snow color. \n" - + " Doesn't generate height, everything is shown at sea level. \n" - + " Multithreaded - Fastest (2-5 ms) \n" - - + "\n" - + " " + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT + " \n" - + " Same as BIOME_ONLY, except instead \n" - + " of always using sea level as the LOD height \n" - + " different biome types (mountain, ocean, forest, etc.) \n" - + " use predetermined heights to simulate having height data. \n" - + " Multithreaded - Fastest (2-5 ms) \n" - - + "\n" - + " " + DistanceGenerationMode.SURFACE + " \n" - + " Generate the world surface, \n" - + " this does NOT include trees, \n" - + " or structures. \n" - + " Multithreaded - Faster (10-20 ms) \n" - - + "\n" - + " " + DistanceGenerationMode.FEATURES + " \n" - + " Generate everything except structures. \n" - + " WARNING: This may cause world generation bugs or instability! \n" - + " Multithreaded - Fast (15-20 ms) \n" - - + "\n" - + " " + DistanceGenerationMode.SERVER + " \n" - + " Ask the server to generate/load each chunk. \n" - + " This will show player made structures, which can \n" - + " be useful if you are adding the mod to a pre-existing world. \n" - + " This is the most compatible, but causes server/simulation lag. \n" - + " SingleThreaded - Slow (15-50 ms, with spikes up to 200 ms) \n") - .defineEnum("Distance Generation Mode", DistanceGenerationMode.SURFACE); - - allowUnstableFeatureGeneration = builder - .comment("\n\n" - + " When using the " + DistanceGenerationMode.FEATURES + " generation mode \n" - + " some features may not be thread safe, which could \n" - + " cause instability and crashes. \n" - + " By default (false) those features are skipped, \n" - + " improving stability, but decreasing how many features are \n" - + " actually generated. \n" - + " (for example: some tree generation is unstable, \n" - + " so some trees may not be generated.) \n" - + " By setting this to true, all features will be generated, \n" - + " but your game will be more unstable and crashes may occur. \n" - + " \n" - + " I would love to remove this option and always generate everything, \n" - + " but I'm not sure how to do that. \n" - + " If you are a Java wizard, check out the git issue here: \n" - + " https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/35 \n") - .define("Allow Unstable Feature Generation", false); - - blockToAvoid = builder - .comment("\n\n" - + " " + BlockToAvoid.NONE + " \n" - + " Use all block in the generation \n" - + "\n" - + " " + BlockToAvoid.NON_FULL + " \n" - + " Avoid block that are not full (slab, lantern, grass, torches ..) \n" - + "\n" - + " " + BlockToAvoid.NO_COLLISION + " \n" - + " Avoid block that have no collision (grass, torches ..) \n" - + "\n" - + " " + BlockToAvoid.BOTH + " \n" - + " Avoid both type of blocks \n" - + "\n") - .defineEnum("Block to avoid", BlockToAvoid.BOTH); + WorldGenerator(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings control how LODs outside your normal view range are generated.").push(this.getClass().getSimpleName()); + + generationPriority = builder + .comment("\n\n" + + " " + GenerationPriority.FAR_FIRST + " \n" + + " LODs are generated from low to high detail \n" + + " with a small priority for far away regions. \n" + + " This fills in the world fastest. \n\n" + + "" + + " " + GenerationPriority.NEAR_FIRST + " \n" + + " LODs are generated around the player \n" + + " in a spiral, similar to vanilla minecraft. \n") + .defineEnum("Generation Priority", GenerationPriority.FAR_FIRST); + + distanceGenerationMode = builder + .comment("\n\n" + + " Note: The times listed here are the amount of time it took \n" + + " one of the developer's PC to generate 1 chunk, \n" + + " and are included so you can compare the \n" + + " different generation options. Your mileage may vary. \n" + + "\n" + + + " " + DistanceGenerationMode.NONE + " \n" + + " Don't run the distance generator. \n" + + + "\n" + + " " + DistanceGenerationMode.BIOME_ONLY + " \n" + + " Only generate the biomes and use the biome's \n" + + " grass color, water color, or snow color. \n" + + " Doesn't generate height, everything is shown at sea level. \n" + + " Multithreaded - Fastest (2-5 ms) \n" + + + "\n" + + " " + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT + " \n" + + " Same as BIOME_ONLY, except instead \n" + + " of always using sea level as the LOD height \n" + + " different biome types (mountain, ocean, forest, etc.) \n" + + " use predetermined heights to simulate having height data. \n" + + " Multithreaded - Fastest (2-5 ms) \n" + + + "\n" + + " " + DistanceGenerationMode.SURFACE + " \n" + + " Generate the world surface, \n" + + " this does NOT include trees, \n" + + " or structures. \n" + + " Multithreaded - Faster (10-20 ms) \n" + + + "\n" + + " " + DistanceGenerationMode.FEATURES + " \n" + + " Generate everything except structures. \n" + + " WARNING: This may cause world generation bugs or instability! \n" + + " Multithreaded - Fast (15-20 ms) \n" + + + "\n" + + " " + DistanceGenerationMode.SERVER + " \n" + + " Ask the server to generate/load each chunk. \n" + + " This will show player made structures, which can \n" + + " be useful if you are adding the mod to a pre-existing world. \n" + + " This is the most compatible, but causes server/simulation lag. \n" + + " SingleThreaded - Slow (15-50 ms, with spikes up to 200 ms) \n") + .defineEnum("Distance Generation Mode", DistanceGenerationMode.SURFACE); + + allowUnstableFeatureGeneration = builder + .comment("\n\n" + + " When using the " + DistanceGenerationMode.FEATURES + " generation mode \n" + + " some features may not be thread safe, which could \n" + + " cause instability and crashes. \n" + + " By default (false) those features are skipped, \n" + + " improving stability, but decreasing how many features are \n" + + " actually generated. \n" + + " (for example: some tree generation is unstable, \n" + + " so some trees may not be generated.) \n" + + " By setting this to true, all features will be generated, \n" + + " but your game will be more unstable and crashes may occur. \n" + + " \n" + + " I would love to remove this option and always generate everything, \n" + + " but I'm not sure how to do that. \n" + + " If you are a Java wizard, check out the git issue here: \n" + + " https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/35 \n") + .define("Allow Unstable Feature Generation", false); + + blockToAvoid = builder + .comment("\n\n" + + " " + BlockToAvoid.NONE + " \n" + + " Use all block in the generation \n" + + "\n" + + " " + BlockToAvoid.NON_FULL + " \n" + + " Avoid block that are not full (slab, lantern, grass, torches ..) \n" + + "\n" + + " " + BlockToAvoid.NO_COLLISION + " \n" + + " Avoid block that have no collision (grass, torches ..) \n" + + "\n" + + " " + BlockToAvoid.BOTH + " \n" + + " Avoid both type of blocks \n" + + "\n") + .defineEnum("Block to avoid", BlockToAvoid.BOTH); /*useExperimentalPreGenLoading = builder .comment("\n\n" + " if a chunk has been pre-generated, then the mod would use the real chunk for the \n" + "fake chunk creation. May require a deletion of the lod file to see the result. \n") .define("Use pre-generated chunks", false);*/ - builder.pop(); + builder.pop(); + } + } + + + public static class AdvancedModOptions + { + + public final Threading threading; + public final Debugging debugging; + public final Buffers buffers; + + public AdvancedModOptions(ForgeConfigSpec.Builder builder) + { + builder.comment("Advanced mod settings").push(this.getClass().getSimpleName()); + { + threading = new Threading(builder); + debugging = new Debugging(builder); + buffers = new Buffers(builder); + } + builder.pop(); + } + + public static class Threading + { + public final ForgeConfigSpec.IntValue numberOfWorldGenerationThreads; + public final ForgeConfigSpec.IntValue numberOfBufferBuilderThreads; + + Threading(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings control how many CPU threads the mod uses for different tasks.").push(this.getClass().getSimpleName()); + + numberOfWorldGenerationThreads = builder + .comment("\n\n" + + " This is how many threads are used when generating LODs outside \n" + + " the normal render distance. \n" + + " If you experience stuttering when generating distant LODs, decrease \n" + + " this number. If you want to increase LOD generation speed, \n" + + " increase this number. \n" + + " \n" + + " The maximum value is the number of logical processors on your CPU. \n" + + " Requires a restart to take effect. \n") + .defineInRange("numberOfWorldGenerationThreads", Math.max(1, Runtime.getRuntime().availableProcessors() / 2), 1, Runtime.getRuntime().availableProcessors()); + + numberOfBufferBuilderThreads = builder + .comment("\n\n" + + " This is how many threads are used when building vertex buffers \n" + + " (The things sent to your GPU to draw the LODs). \n" + + " If you experience high CPU usage when NOT generating distant \n" + + " LODs, lower this number. \n" + + " \n" + + " The maximum value is the number of logical processors on your CPU. \n" + + " Requires a restart to take effect. \n") + .defineInRange("numberOfBufferBuilderThreads", Math.max(1, Runtime.getRuntime().availableProcessors() / 2), 1, Runtime.getRuntime().availableProcessors()); + + builder.pop(); + } + } + + public static class Debugging + { + public final ForgeConfigSpec.BooleanValue drawLods; + public final ForgeConfigSpec.EnumValue debugMode; + public final ForgeConfigSpec.BooleanValue enableDebugKeybindings; + + Debugging(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings can be used to look for bugs, or see how certain aspects of the mod work.").push(this.getClass().getSimpleName()); + + drawLods = builder + .comment("\n\n" + + " If true, the mod is enabled and LODs will be drawn. \n" + + " If false, the mod will still generate LODs, \n" + + " but they won't be rendered. \n") + .define("Disable Draw", true); + + debugMode = builder + .comment("\n\n" + + " " + DebugMode.OFF + ": LODs will draw with their normal colors. \n" + + " " + DebugMode.SHOW_DETAIL + ": LOD colors will be based on their detail level. \n" + + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": LOD colors will be based on their detail level, drawn as a wireframe. \n") + .defineEnum("debugMode", DebugMode.OFF); + + enableDebugKeybindings = builder + .comment("\n\n" + + " If true the F4 key can be used to cycle through the different debug modes. \n" + + " and the F6 key can be used to enable and disable LOD rendering.") + .define("enableDebugKeybinding", false); + + builder.pop(); + } + } + + public static class Buffers + { + public final ForgeConfigSpec.EnumValue rebuildTimes; + + Buffers(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings affect when Vertex Buffers are built.").push(this.getClass().getSimpleName()); + + rebuildTimes = builder + .comment("\n\n" + + " How frequently should geometry be rebuilt and sent to the GPU? \n" + + " Faster settings may cause stuttering, but will prevent holes in the world \n") + .defineEnum("rebuildFrequency", BufferRebuildTimes.NORMAL); + + builder.pop(); + } + } } } - public static class Threading - { - public final ForgeConfigSpec.IntValue numberOfWorldGenerationThreads; - public final ForgeConfigSpec.IntValue numberOfBufferBuilderThreads; - - Threading(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings control how many CPU threads the mod uses for different tasks.").push(this.getClass().getSimpleName()); - - numberOfWorldGenerationThreads = builder - .comment("\n\n" - + " This is how many threads are used when generating LODs outside \n" - + " the normal render distance. \n" - + " If you experience stuttering when generating distant LODs, decrease \n" - + " this number. If you want to increase LOD generation speed, \n" - + " increase this number. \n" - + " \n" - + " The maximum value is the number of logical processors on your CPU. \n" - + " Requires a restart to take effect. \n") - .defineInRange("numberOfWorldGenerationThreads", Math.max(1,Runtime.getRuntime().availableProcessors() / 2), 1, Runtime.getRuntime().availableProcessors()); - - numberOfBufferBuilderThreads = builder - .comment("\n\n" - + " This is how many threads are used when building vertex buffers \n" - + " (The things sent to your GPU to draw the LODs). \n" - + " If you experience high CPU usage when NOT generating distant \n" - + " LODs, lower this number. \n" - + " \n" - + " The maximum value is the number of logical processors on your CPU. \n" - + " Requires a restart to take effect. \n") - .defineInRange("numberOfBufferBuilderThreads", Math.max(1,Runtime.getRuntime().availableProcessors() / 2), 1, Runtime.getRuntime().availableProcessors()); - - builder.pop(); - } - } - - public static class Debugging - { - public final ForgeConfigSpec.EnumValue debugMode; - public final ForgeConfigSpec.BooleanValue enableDebugKeybindings; - - Debugging(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings can be used to look for bugs, or see how certain aspects of the mod work.").push(this.getClass().getSimpleName()); - - debugMode = builder - .comment("\n\n" - + " " + DebugMode.OFF + ": LODs will draw with their normal colors. \n" - + " " + DebugMode.SHOW_DETAIL + ": LOD colors will be based on their detail level. \n" - + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": LOD colors will be based on their detail level, drawn as a wireframe. \n") - .defineEnum("debugMode", DebugMode.OFF); - - enableDebugKeybindings = builder - .comment("\n\n" - + " If true the F4 key can be used to cycle through the different debug modes. \n" - + " and the F6 key can be used to enable and disable LOD rendering.") - .define("enableDebugKeybinding", false); - - builder.pop(); - } - } - - public static class Buffers - { - public final ForgeConfigSpec.EnumValue rebuildTimes; - - Buffers(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings affect when Vertex Buffers are built.").push(this.getClass().getSimpleName()); - - rebuildTimes = builder - .comment("\n\n" - + " How frequently should geometry be rebuilt and sent to the GPU? \n" - + " Faster settings may cause stuttering, but will prevent holes in the world \n") - .defineEnum("rebuildFrequency", BufferRebuildTimes.NORMAL); - - builder.pop(); - } - } /** * {@link Path} to the configuration file of this mod @@ -442,8 +479,8 @@ public class LodConfig CLIENT_SPEC = specPair.getRight(); CLIENT = specPair.getLeft(); CommentedFileConfig clientConfig = CommentedFileConfig.builder(CONFIG_PATH) - .writingMode(WritingMode.REPLACE) - .build(); + .writingMode(WritingMode.REPLACE) + .build(); clientConfig.load(); clientConfig.save(); CLIENT_SPEC.setConfig(clientConfig); diff --git a/src/main/java/com/seibel/lod/enums/DetailDropOff.java b/src/main/java/com/seibel/lod/enums/DetailDropOff.java deleted file mode 100644 index 1127eb215..000000000 --- a/src/main/java/com/seibel/lod/enums/DetailDropOff.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the LOD Mod, licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.enums; - -/** - * By_Region_Fast,
- * By_Region_Fancy,
- * By_Chunk - * @author Leonardo Amato - * @version 9-25-2021 - */ -public enum DetailDropOff -{ - /** quality is determined per-region, using the lowest quality that would be used in BY_CHUNK */ - FAST, - - /** quality is determined per-block (the best quality option, may cause stuttering when moving) */ - FANCY, -} diff --git a/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java b/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java index 2ea118a60..3f722af05 100644 --- a/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java +++ b/src/main/java/com/seibel/lod/mixin/MixinWorldRenderer.java @@ -55,7 +55,7 @@ public class MixinWorldRenderer { // only render if LODs are enabled and // only render before solid blocks - if (LodConfig.CLIENT.graphics.drawLods.get() && renderType.equals(RenderType.solid())) + if (LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get() && renderType.equals(RenderType.solid())) LodMain.client_proxy.renderLods(matrixStackIn, previousPartialTicks); } } diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index f5496e39f..b774ef0ab 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -362,7 +362,7 @@ public class LodDimension { DistanceGenerationMode generationMode = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); ChunkPos newPlayerChunk = new ChunkPos(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); - VerticalQuality verticalQuality = LodConfig.CLIENT.worldGenerator.verticalQuality.get(); + VerticalQuality verticalQuality = LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); if (lastExpandedChunk == null) diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index cba8ad520..2ff21e0ef 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -345,38 +345,17 @@ public class LodRegion byte desiredLevel; int maxDistance; - boolean stopNow; int minDistance; int childLevel; // calculate the LevelPos that are in range - switch (LodConfig.CLIENT.graphics.detailDropOff.get()) - { + maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); + minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance)); - case FAST: - int playerRegionX = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerPosX); - int playerRegionZ = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL, playerPosZ); - if (playerRegionX == regionPosX && playerRegionZ == regionPosZ) - { - maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); - desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); - minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); - childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance)); - stopNow = detailLevel == childLevel - 1; - break; - } - default: - case FANCY: - maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); - desiredLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); - minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); - childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance)); - stopNow = detailLevel == childLevel - 1; - break; - } - - if (stopNow) + if (detailLevel == childLevel - 1) { posToRender.addPosToRender(detailLevel, posX + regionPosX * size, diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 0a99538ee..2d46f606f 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -144,7 +144,7 @@ public class ClientProxy // these can't be set until after the buffers are built (in renderer.drawLODs) // otherwise the buffers may be set to the wrong size, or not changed at all previousChunkRenderDistance = mc.getRenderDistance(); - previousLodRenderDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get(); + previousLodRenderDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(); } catch (Exception e) { @@ -183,7 +183,7 @@ public class ClientProxy // LodConfig.CLIENT.buffers.rebuildTimes.set(BufferRebuildTimes.FREQUENT); - LodConfig.CLIENT.debugging.enableDebugKeybindings.set(true); + LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(true); // LodConfig.CLIENT.debugging.debugMode.set(DebugMode.SHOW_DETAIL); } @@ -285,16 +285,16 @@ public class ClientProxy @SubscribeEvent public void onKeyInput(InputEvent.KeyInputEvent event) { - if (LodConfig.CLIENT.debugging.enableDebugKeybindings.get() + if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() && event.getKey() == GLFW.GLFW_KEY_F4 && event.getAction() == GLFW.GLFW_PRESS) { - LodConfig.CLIENT.debugging.debugMode.set(LodConfig.CLIENT.debugging.debugMode.get().getNext()); + LodConfig.CLIENT.advancedModOptions.debugging.debugMode.set(LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get().getNext()); } - if (LodConfig.CLIENT.debugging.enableDebugKeybindings.get() + if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() && event.getKey() == GLFW.GLFW_KEY_F6 && event.getAction() == GLFW.GLFW_PRESS) { - LodConfig.CLIENT.graphics.drawLods.set(!LodConfig.CLIENT.graphics.drawLods.get()); + LodConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get()); } } @@ -326,9 +326,9 @@ public class ClientProxy // calculate how wide the dimension(s) should be in regions int chunksWide; if (mc.getClientWorld().dimensionType().hasCeiling()) - chunksWide = Math.min(LodConfig.CLIENT.graphics.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1; + chunksWide = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1; else - chunksWide = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * 2 + 1; + chunksWide = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 2 + 1; int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS); // make sure we have an odd number of regions diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index f4b4847df..ef2d4fb02 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -32,7 +32,6 @@ import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilder.VertexBuffersAndOffset; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DebugMode; -import com.seibel.lod.enums.DetailDropOff; import com.seibel.lod.enums.FogDistance; import com.seibel.lod.enums.FogDrawOverride; import com.seibel.lod.enums.FogQuality; @@ -214,7 +213,7 @@ public class LodRenderer // set the required open GL settings - if (LodConfig.CLIENT.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME) + if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); else GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL); @@ -245,9 +244,9 @@ public class LodRenderer vanillaBlockRenderedDistance = mc.getRenderDistance() * LodUtil.CHUNK_WIDTH; // required for setupFog and setupProjectionMatrix if (mc.getClientWorld().dimensionType().hasCeiling()) - farPlaneBlockDistance = Math.min(LodConfig.CLIENT.graphics.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; + farPlaneBlockDistance = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; else - farPlaneBlockDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; + farPlaneBlockDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; setupProjectionMatrix(mcProjectionMatrix, partialTicks); // commented out until we can add shaders to handle lighting @@ -274,7 +273,7 @@ public class LodRenderer ActiveRenderInfo renderInfo = mc.getGameRenderer().getMainCamera(); Vector3d cameraDir = new Vector3d(renderInfo.getLookVector()); - boolean cullingDisabled = LodConfig.CLIENT.graphics.disableDirectionalCulling.get(); + boolean cullingDisabled = LodConfig.CLIENT.graphics.advancedOption.disableDirectionalCulling.get(); // used to determine what type of fog to render int halfWidth = vbos.length / 2; @@ -399,7 +398,7 @@ public class LodRenderer if (fogQuality == FogQuality.FANCY) { // for more realistic fog when using FAR - if (LodConfig.CLIENT.graphics.fogDistance.get() == FogDistance.NEAR_AND_FAR) + if (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get() == FogDistance.NEAR_AND_FAR) RenderSystem.fogStart(farPlaneBlockDistance * 0.9f); else RenderSystem.fogStart(Math.min(vanillaBlockRenderedDistance * 1.5f, farPlaneBlockDistance * 0.9f)); @@ -450,8 +449,8 @@ public class LodRenderer // disable fog if Minecraft wasn't rendering fog, // but we were if (!fogSettings.vanillaIsRenderingFog && - (fogSettings.near.quality != FogQuality.OFF || - fogSettings.far.quality != FogQuality.OFF)) + (fogSettings.near.quality != FogQuality.OFF || + fogSettings.far.quality != FogQuality.OFF)) { GL11.glDisable(GL11.GL_FOG); } @@ -659,7 +658,7 @@ public class LodRenderer FogQuality quality = ReflectionHandler.INSTANCE.getFogQuality(); - FogDrawOverride override = LodConfig.CLIENT.graphics.fogDrawOverride.get(); + FogDrawOverride override = LodConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.get(); fogSettings.vanillaIsRenderingFog = quality != FogQuality.OFF; @@ -700,7 +699,7 @@ public class LodRenderer fogSettings.near.quality = FogQuality.FANCY; fogSettings.far.quality = FogQuality.FANCY; - switch (LodConfig.CLIENT.graphics.fogDistance.get()) + switch (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { case NEAR_AND_FAR: fogSettings.near.distance = FogDistance.NEAR; @@ -727,7 +726,7 @@ public class LodRenderer // fog, since the LODs are separated into a near // and far portion; and fast fog is rendered from the // frustrum's perspective instead of the camera - switch (LodConfig.CLIENT.graphics.fogDistance.get()) + switch (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { case NEAR_AND_FAR: case NEAR: @@ -764,44 +763,41 @@ public class LodRenderer //=============// // check if the view distance changed - if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() - || chunkRenderDistance != prevRenderDistance - || prevFogDistance != LodConfig.CLIENT.graphics.fogDistance.get()) + if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() + || chunkRenderDistance != prevRenderDistance + || prevFogDistance != LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; DetailDistanceUtil.updateSettings(); fullRegen = true; previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk); - prevFogDistance = LodConfig.CLIENT.graphics.fogDistance.get(); + prevFogDistance = LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get(); prevRenderDistance = chunkRenderDistance; } // did the user change the debug setting? - if (LodConfig.CLIENT.debugging.debugMode.get() != previousDebugMode) + if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != previousDebugMode) { - previousDebugMode = LodConfig.CLIENT.debugging.debugMode.get(); + previousDebugMode = LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get(); fullRegen = true; } long newTime = System.currentTimeMillis(); - if (LodConfig.CLIENT.graphics.detailDropOff.get() == DetailDropOff.FANCY) + // check if the player has moved + if (newTime - prevPlayerPosTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().playerMoveTimeout) { - // check if the player has moved - if (newTime - prevPlayerPosTime > LodConfig.CLIENT.buffers.rebuildTimes.get().playerMoveTimeout) - { - if (LevelPosUtil.getDetailLevel(previousPos) == 0 + if (LevelPosUtil.getDetailLevel(previousPos) == 0 || mc.getPlayer().xChunk != LevelPosUtil.getPosX(previousPos) || mc.getPlayer().zChunk != LevelPosUtil.getPosZ(previousPos)) - { - vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; - fullRegen = true; - previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk); - } - prevPlayerPosTime = newTime; + { + vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; + fullRegen = true; + previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk); } + prevPlayerPosTime = newTime; } @@ -812,7 +808,7 @@ public class LodRenderer // the max brightness is 1 and the minimum is 0.2 float skyBrightness = lodDim.dimension.hasSkyLight() ? mc.getSkyDarken(partialTicks) : 0.2f; float minLightingDifference; - switch (LodConfig.CLIENT.buffers.rebuildTimes.get()) + switch (LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get()) { case FREQUENT: minLightingDifference = 0.025f; @@ -827,12 +823,12 @@ public class LodRenderer } // check if the lighting changed - if (Math.abs(skyBrightness - prevSkyBrightness) > minLightingDifference - // make sure the lighting gets to the max/minimum value - // (just in case the minLightingDifference is too large to notice the change) - || (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon - || (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight - || mc.getOptions().gamma != prevBrightness || lightMap == null) + if (Math.abs(skyBrightness - prevSkyBrightness) > minLightingDifference + // make sure the lighting gets to the max/minimum value + // (just in case the minLightingDifference is too large to notice the change) + || (skyBrightness == 1.0f && prevSkyBrightness != 1.0f) // noon + || (skyBrightness == 0.2f && prevSkyBrightness != 0.2f) // midnight + || mc.getOptions().gamma != prevBrightness || lightMap == null) { fullRegen = true; lightMap = mc.getCurrentLightMap(); @@ -847,7 +843,7 @@ public class LodRenderer // check if the vanilla rendered chunks changed - if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.buffers.rebuildTimes.get().renderedChunkTimeout) + if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().renderedChunkTimeout) { if (vanillaRenderedChunksChanged) { @@ -860,7 +856,7 @@ public class LodRenderer // check if there is any newly generated terrain to show - if (newTime - prevChunkTime > LodConfig.CLIENT.buffers.rebuildTimes.get().chunkChangeTimeout) + if (newTime - prevChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().chunkChangeTimeout) { if (lodDim.regenDimensionBuffers) { @@ -888,8 +884,8 @@ public class LodRenderer // sometimes we are given chunks that are outside the render distance, // This prevents index out of bounds exceptions if (xIndex >= 0 && zIndex >= 0 - && xIndex < vanillaRenderedChunks.length - && zIndex < vanillaRenderedChunks.length) + && xIndex < vanillaRenderedChunks.length + && zIndex < vanillaRenderedChunks.length) { if (!vanillaRenderedChunks[xIndex][zIndex]) { diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java index bc405b631..0863f8e33 100644 --- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java @@ -11,12 +11,12 @@ public class DetailDistanceUtil private static final double genMultiplier = 1.0; private static final double treeGenMultiplier = 1.0; private static final double treeCutMultiplier = 1.0; - private static int minGenDetail = LodConfig.CLIENT.worldGenerator.generationResolution.get().detailLevel; - private static int minDrawDetail = Math.max(LodConfig.CLIENT.graphics.drawResolution.get().detailLevel, LodConfig.CLIENT.worldGenerator.generationResolution.get().detailLevel); + private static int minGenDetail = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; + private static int minDrawDetail = Math.max(LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel, LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel); private static final int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1; private static final int minDistance = 0; private static int minDetailDistance = (int) (MinecraftWrapper.INSTANCE.getRenderDistance()*16 * 1.42f); - private static int maxDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * 16 * 2; + private static int maxDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 16 * 2; private static final HorizontalResolution[] lodGenDetails = { @@ -37,9 +37,9 @@ public class DetailDistanceUtil public static void updateSettings() { minDetailDistance = (int) (MinecraftWrapper.INSTANCE.getRenderDistance()*16 * 1.42f); - minGenDetail = LodConfig.CLIENT.worldGenerator.generationResolution.get().detailLevel; - minDrawDetail = Math.max(LodConfig.CLIENT.graphics.drawResolution.get().detailLevel, LodConfig.CLIENT.worldGenerator.generationResolution.get().detailLevel); - maxDistance = LodConfig.CLIENT.graphics.lodChunkRenderDistance.get() * 16 * 8; + minGenDetail = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; + minDrawDetail = Math.max(LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel, LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel); + maxDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 16 * 8; } public static int baseDistanceFunction(int detail) @@ -49,12 +49,12 @@ public class DetailDistanceUtil if (detail >= maxDetail) return maxDistance; - int distanceUnit = LodConfig.CLIENT.worldGenerator.horizontalScale.get().distanceUnit; - if (LodConfig.CLIENT.worldGenerator.horizontalQuality.get() == HorizontalQuality.LOWEST) + int distanceUnit = LodConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; + if (LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) return (detail * distanceUnit); else { - double base = LodConfig.CLIENT.worldGenerator.horizontalQuality.get().quadraticBase; + double base = LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; return (int) (Math.pow(base, detail) * distanceUnit); } } @@ -71,12 +71,12 @@ public class DetailDistanceUtil return (byte) minDetail; if (distance < minDetailDistance && useRenderMinDistance) return (byte) minDetail; - int distanceUnit = LodConfig.CLIENT.worldGenerator.horizontalScale.get().distanceUnit; - if (LodConfig.CLIENT.worldGenerator.horizontalQuality.get() == HorizontalQuality.LOWEST) + int distanceUnit = LodConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; + if (LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) detail = (byte) Math.floorDiv(distance, distanceUnit); else { - double base = LodConfig.CLIENT.worldGenerator.horizontalQuality.get().quadraticBase; + double base = LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; double logBase = Math.log(base); detail = (byte) (Math.log(Math.floorDiv(distance, distanceUnit)) / logBase); } @@ -115,14 +115,14 @@ public class DetailDistanceUtil { if (detail < minDrawDetail) { - if (LodConfig.CLIENT.graphics.alwaysDrawAtMaxQuality.get()) + if (LodConfig.CLIENT.graphics.advancedOption.alwaysDrawAtMaxQuality.get()) return getLodGenDetail(minDrawDetail).detailLevel; else return (byte) minDrawDetail; } else { - if (LodConfig.CLIENT.graphics.alwaysDrawAtMaxQuality.get()) + if (LodConfig.CLIENT.graphics.advancedOption.alwaysDrawAtMaxQuality.get()) return getLodGenDetail(detail).detailLevel; else return (byte) detail; @@ -160,7 +160,7 @@ public class DetailDistanceUtil public static int getMaxVerticalData(int detail) { - return LodConfig.CLIENT.worldGenerator.verticalQuality.get().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)]; + return LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)]; } } diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index 784777d2e..045f5805d 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -355,9 +355,8 @@ public class LodUtil ChunkPos centerChunk = new ChunkPos(playerPos); int skipRadius; - VanillaOverdraw overdraw = LodConfig.CLIENT.graphics.vanillaOverdraw.get(); - HorizontalResolution drawRes = LodConfig.CLIENT.graphics.drawResolution.get(); - HorizontalResolution genRes = LodConfig.CLIENT.worldGenerator.generationResolution.get(); + VanillaOverdraw overdraw = LodConfig.CLIENT.graphics.advancedOption.vanillaOverdraw.get(); + HorizontalResolution drawRes = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get(); // apply distance based rules for dynamic overdraw if (overdraw == VanillaOverdraw.DYNAMIC @@ -365,7 +364,7 @@ public class LodUtil { // The vanilla render distance isn't far enough // for partial skipping to make sense... - if (!lodDim.dimension.hasCeiling() && (drawRes == HorizontalResolution.BLOCK && genRes == HorizontalResolution.BLOCK)) + if (!lodDim.dimension.hasCeiling() && (drawRes == HorizontalResolution.BLOCK)) { // ...and the dimension is open, so we don't have to worry about // LODs rendering on top of the player,