From 3144cb9791fcc5dff7c3a756dcb24b65ce276229 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 14 Nov 2021 18:42:56 -0600 Subject: [PATCH] Add LodConfig, LodConfigWrapper, and ForgeConfig --- ...ClientProxy.java => ForgeClientProxy.java} | 2 +- .../com/seibel/lod/api/forge/ForgeConfig.java | 445 ++++++++++++ .../{LodForgeMain.java => ForgeMain.java} | 12 +- .../com/seibel/lod/api/forge/LodConfig.java | 591 ---------------- .../com/seibel/lod/api/lod/ClientApi.java | 6 +- .../com/seibel/lod/api/lod/ConfigApi.java | 498 -------------- .../java/com/seibel/lod/api/lod/EventApi.java | 14 +- .../LodBufferBuilderFactory.java | 12 +- .../lod/builders/lodBuilding/LodBuilder.java | 8 +- .../worldGeneration/LodGenWorker.java | 8 +- .../worldGeneration/LodWorldGenerator.java | 6 +- .../java/com/seibel/lod/config/LodConfig.java | 651 ++++++++++++++++++ .../lod/enums/config/BufferRebuildTimes.java | 5 +- src/main/java/com/seibel/lod/objects/Box.java | 4 +- .../seibel/lod/objects/lod/LodDimension.java | 12 +- .../com/seibel/lod/render/LodRenderer.java | 40 +- .../seibel/lod/util/DetailDistanceUtil.java | 34 +- .../java/com/seibel/lod/util/LodUtil.java | 6 +- .../lod/wrappers/config/LodConfigWrapper.java | 383 +++++++++++ .../WorldGeneratorWrapper.java | 4 +- 20 files changed, 1566 insertions(+), 1175 deletions(-) rename src/main/java/com/seibel/lod/api/forge/{ClientProxy.java => ForgeClientProxy.java} (99%) create mode 100644 src/main/java/com/seibel/lod/api/forge/ForgeConfig.java rename src/main/java/com/seibel/lod/api/forge/{LodForgeMain.java => ForgeMain.java} (90%) delete mode 100644 src/main/java/com/seibel/lod/api/forge/LodConfig.java delete mode 100644 src/main/java/com/seibel/lod/api/lod/ConfigApi.java create mode 100644 src/main/java/com/seibel/lod/config/LodConfig.java create mode 100644 src/main/java/com/seibel/lod/wrappers/config/LodConfigWrapper.java diff --git a/src/main/java/com/seibel/lod/api/forge/ClientProxy.java b/src/main/java/com/seibel/lod/api/forge/ForgeClientProxy.java similarity index 99% rename from src/main/java/com/seibel/lod/api/forge/ClientProxy.java rename to src/main/java/com/seibel/lod/api/forge/ForgeClientProxy.java index ebe30f46c..f8daf9f37 100644 --- a/src/main/java/com/seibel/lod/api/forge/ClientProxy.java +++ b/src/main/java/com/seibel/lod/api/forge/ForgeClientProxy.java @@ -38,7 +38,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; * @author James_Seibel * @version 11-12-2021 */ -public class ClientProxy +public class ForgeClientProxy { private final EventApi eventApi = EventApi.INSTANCE; diff --git a/src/main/java/com/seibel/lod/api/forge/ForgeConfig.java b/src/main/java/com/seibel/lod/api/forge/ForgeConfig.java new file mode 100644 index 000000000..b64abf648 --- /dev/null +++ b/src/main/java/com/seibel/lod/api/forge/ForgeConfig.java @@ -0,0 +1,445 @@ +/* + * This file is part of the Distant Horizon mod (formerly 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.api.forge; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; + +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.core.io.WritingMode; +import com.seibel.lod.ModInfo; +import com.seibel.lod.config.LodConfig; +import com.seibel.lod.enums.config.BlockToAvoid; +import com.seibel.lod.enums.config.BufferRebuildTimes; +import com.seibel.lod.enums.config.DistanceGenerationMode; +import com.seibel.lod.enums.config.GenerationPriority; +import com.seibel.lod.enums.config.GpuUploadMethod; +import com.seibel.lod.enums.config.HorizontalQuality; +import com.seibel.lod.enums.config.HorizontalResolution; +import com.seibel.lod.enums.config.HorizontalScale; +import com.seibel.lod.enums.config.LodTemplate; +import com.seibel.lod.enums.config.VanillaOverdraw; +import com.seibel.lod.enums.config.VerticalQuality; +import com.seibel.lod.enums.rendering.DebugMode; +import com.seibel.lod.enums.rendering.FogDistance; +import com.seibel.lod.enums.rendering.FogDrawOverride; +import com.seibel.lod.objects.MinDefaultMax; + +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; + +/** + * This handles any configuration the user has access to. + * @author Leonardo Amato + * @author James Seibel + * @version 11-14-2021 + */ +@Mod.EventBusSubscriber +public class ForgeConfig +{ + // CONFIG STRUCTURE + // -> Client + // | + // |-> Graphics + // | |-> QualityOption + // | |-> FogQualityOption + // | |-> AdvancedGraphicsOption + // | + // |-> World Generation + // | + // |-> Advanced Mod Option + // |-> Threads + // |-> Buffers + // |-> Debugging + + + + public static class Client + { + public final Graphics graphics; + public final WorldGenerator worldGenerator; + public final AdvancedModOptions advancedModOptions; + + + //================// + // Client Configs // + //================// + public Client(ForgeConfigSpec.Builder builder) + { + builder.push(this.getClass().getSimpleName()); + { + graphics = new Graphics(builder); + worldGenerator = new WorldGenerator(builder); + advancedModOptions = new AdvancedModOptions(builder); + } + builder.pop(); + } + + + //==================// + // Graphics Configs // + //==================// + public static class Graphics + { + + public final QualityOption qualityOption; + public final FogQualityOption fogQualityOption; + public final AdvancedGraphicsOption advancedGraphicsOption; + + Graphics(ForgeConfigSpec.Builder builder) + { + builder.comment("These settings control how the mod will look in game").push("Graphics"); + { + qualityOption = new QualityOption(builder); + advancedGraphicsOption = new AdvancedGraphicsOption(builder); + fogQualityOption = new FogQualityOption(builder); + } + builder.pop(); + } + + + 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(LodConfig.Client.Graphics.QualityOption.DESC).push(this.getClass().getSimpleName()); + + verticalQuality = builder + .comment("\n\n" + + LodConfig.Client.Graphics.QualityOption.VERTICAL_QUALITY_DESC) + .defineEnum("Vertical Quality", LodConfig.Client.Graphics.QualityOption.VERTICAL_QUALITY_DEFAULT); + + horizontalScale = builder + .comment("\n\n" + + LodConfig.Client.Graphics.QualityOption.HORIZONTAL_SCALE_DESC) + .defineEnum("Horizontal Scale", LodConfig.Client.Graphics.QualityOption.HORIZONTAL_SCALE_DEFAULT); + + horizontalQuality = builder + .comment("\n\n" + + LodConfig.Client.Graphics.QualityOption.HORIZONTAL_QUALITY_DESC) + .defineEnum("Horizontal Quality", LodConfig.Client.Graphics.QualityOption.HORIZONTAL_QUALITY_DEFAULT); + + drawResolution = builder + .comment("\n\n" + + LodConfig.Client.Graphics.QualityOption.DRAW_RESOLUTION_DESC) + .defineEnum("Block size", LodConfig.Client.Graphics.QualityOption.DRAW_RESOLUTION_DEFAULT); + + MinDefaultMax minDefaultMax = LodConfig.Client.Graphics.QualityOption.LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX; + lodChunkRenderDistance = builder + .comment("\n\n" + + LodConfig.Client.Graphics.QualityOption.LOD_CHUNK_RENDER_DISTANCE_DESC) + .defineInRange("Lod Render Distance", minDefaultMax.defaultValue, minDefaultMax.minValue, minDefaultMax.maxValue); + + builder.pop(); + } + } + + + public static class FogQualityOption + { + public final ForgeConfigSpec.EnumValue fogDistance; + + public final ForgeConfigSpec.EnumValue fogDrawOverride; + + public final ForgeConfigSpec.BooleanValue disableVanillaFog; + + FogQualityOption(ForgeConfigSpec.Builder builder) + { + + builder.comment(LodConfig.Client.Graphics.FogQualityOption.DESC).push(this.getClass().getSimpleName()); + + fogDistance = builder + .comment("\n\n" + + LodConfig.Client.Graphics.FogQualityOption.FOG_DISTANCE_DESC) + .defineEnum("Fog Distance", LodConfig.Client.Graphics.FogQualityOption.FOG_DISTANCE_DEFAULT); + + fogDrawOverride = builder + .comment("\n\n" + + LodConfig.Client.Graphics.FogQualityOption.FOG_DRAW_OVERRIDE_DESC) + .defineEnum("Fog Draw Override", LodConfig.Client.Graphics.FogQualityOption.FOG_DRAW_OVERRIDE_DEFAULT); + + disableVanillaFog = builder + .comment("\n\n" + + LodConfig.Client.Graphics.FogQualityOption.DISABLE_VANILLA_FOG_DESC) + .define("Experimental Disable Vanilla Fog", LodConfig.Client.Graphics.FogQualityOption.DISABLE_VANILLA_FOG_DEFAULT); + + builder.pop(); + } + } + + + public static class AdvancedGraphicsOption + { + public final ForgeConfigSpec.EnumValue lodTemplate; + + public final ForgeConfigSpec.BooleanValue disableDirectionalCulling; + + public final ForgeConfigSpec.BooleanValue alwaysDrawAtMaxQuality; + + public final ForgeConfigSpec.EnumValue vanillaOverdraw; + + public final ForgeConfigSpec.EnumValue gpuUploadMethod; + + public final ForgeConfigSpec.BooleanValue useExtendedNearClipPlane; + + AdvancedGraphicsOption(ForgeConfigSpec.Builder builder) + { + + builder.comment(LodConfig.Client.Graphics.AdvancedGraphicsOption.DESC).push(this.getClass().getSimpleName()); + + lodTemplate = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.LOD_TEMPLATE_DESC) + .defineEnum("LOD Template", LodConfig.Client.Graphics.AdvancedGraphicsOption.LOD_TEMPLATE_DEFAULT); + + disableDirectionalCulling = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.DISABLE_DIRECTIONAL_CULLING_DESC) + .define("Disable Directional Culling", LodConfig.Client.Graphics.AdvancedGraphicsOption.DISABLE_DIRECTIONAL_CULLING_DEFAULT); + + alwaysDrawAtMaxQuality = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.ALWAYS_DRAW_AT_MAD_QUALITY_DESC) + .define("Always Use Max Quality", LodConfig.Client.Graphics.AdvancedGraphicsOption.ALWAYS_DRAW_AT_MAD_QUALITY_DEFAULT); + + vanillaOverdraw = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.VANILLA_OVERDRAW_DESC) + .defineEnum("Vanilla Overdraw", LodConfig.Client.Graphics.AdvancedGraphicsOption.VANILLA_OVERDRAW_DEFAULT); + + gpuUploadMethod = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.GPU_UPLOAD_METHOD_DESC) + .defineEnum("GPU Upload Method", LodConfig.Client.Graphics.AdvancedGraphicsOption.GPU_UPLOAD_METHOD_DEFAULT); + + // This is a temporary fix (like vanilla overdraw) + // hopefully we can remove both once we get individual chunk rendering figured out + useExtendedNearClipPlane = builder + .comment("\n\n" + + LodConfig.Client.Graphics.AdvancedGraphicsOption.USE_EXTENDED_NEAR_CLIP_PLANE_DESC) + .define("Use Extended Near Clip Plane", LodConfig.Client.Graphics.AdvancedGraphicsOption.USE_EXTENDED_NEAR_CLIP_PLANE_DEFAULT); + + + builder.pop(); + } + } + } + + + + + //========================// + // WorldGenerator Configs // + //========================// + public static class WorldGenerator + { + 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; + + WorldGenerator(ForgeConfigSpec.Builder builder) + { + builder.comment(LodConfig.Client.WorldGenerator.DESC).push("Generation"); + + generationPriority = builder + .comment("\n\n" + + LodConfig.Client.WorldGenerator.GENERATION_PRIORITY_DESC) + .defineEnum("Generation Priority", LodConfig.Client.WorldGenerator.GENERATION_PRIORITY_DEFAULT); + + distanceGenerationMode = builder + .comment("\n\n" + + LodConfig.Client.WorldGenerator.DISTANCE_GENERATION_MODE_DESC) + .defineEnum("Distance Generation Mode", LodConfig.Client.WorldGenerator.DISTANCE_GENERATION_MODE_DEFAULT); + + allowUnstableFeatureGeneration = builder + .comment("\n\n" + + LodConfig.Client.WorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DESC) + .define("Allow Unstable Feature Generation", LodConfig.Client.WorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT); + + blockToAvoid = builder + .comment("\n\n" + + LodConfig.Client.WorldGenerator.BLOCK_TO_AVOID_DESC) + .defineEnum("Block to avoid", LodConfig.Client.WorldGenerator.BLOCK_TO_AVOID_DEFAULT); + + /*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(); + } + } + + + + + //============================// + // AdvancedModOptions Configs // + //============================// + 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(LodConfig.Client.AdvancedModOptions.Threading.DESC).push(this.getClass().getSimpleName()); + + MinDefaultMax minDefaultMax = LodConfig.Client.AdvancedModOptions.Threading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT; + numberOfWorldGenerationThreads = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Threading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC) + .defineInRange("numberOfWorldGenerationThreads", minDefaultMax.defaultValue, minDefaultMax.minValue, minDefaultMax.maxValue); + + + minDefaultMax = LodConfig.Client.AdvancedModOptions.Threading.NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX; + numberOfBufferBuilderThreads = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Threading.NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX) + .defineInRange("numberOfBufferBuilderThreads", minDefaultMax.defaultValue, minDefaultMax.minValue, minDefaultMax.maxValue); + + builder.pop(); + } + } + + + + + //===============// + // Debug Options // + //===============// + 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(LodConfig.Client.AdvancedModOptions.Debugging.DESC).push(this.getClass().getSimpleName()); + + drawLods = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Debugging.DRAW_LODS_DESC) + .define("Enable Rendering", LodConfig.Client.AdvancedModOptions.Debugging.DRAW_LODS_DEFAULT); + + debugMode = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Debugging.DEBUG_MODE_DESC) + .defineEnum("Debug Mode", LodConfig.Client.AdvancedModOptions.Debugging.DEBUG_MODE_DEFAULT); + + enableDebugKeybindings = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Debugging.ENABLE_DEBUG_KEYBINDINGS_DESC) + .define("Enable Debug Keybinding", LodConfig.Client.AdvancedModOptions.Debugging.ENABLE_DEBUG_KEYBINDINGS_DEFAULT); + + builder.pop(); + } + } + + + public static class Buffers + { + public final ForgeConfigSpec.EnumValue rebuildTimes; + + Buffers(ForgeConfigSpec.Builder builder) + { + builder.comment(LodConfig.Client.AdvancedModOptions.Buffers.DESC).push(this.getClass().getSimpleName()); + + rebuildTimes = builder + .comment("\n\n" + + LodConfig.Client.AdvancedModOptions.Buffers.REBUILD_TIMES_DESC) + .defineEnum("rebuildFrequency", LodConfig.Client.AdvancedModOptions.Buffers.REBUILD_TIMES_DEFAULT); + + builder.pop(); + } + } + } + } + + + /** {@link Path} to the configuration file of this mod */ + private static final Path CONFIG_PATH = Paths.get("config", ModInfo.NAME + ".toml"); + + public static final ForgeConfigSpec CLIENT_SPEC; + public static final Client CLIENT; + + static + { + final Pair specPair = new ForgeConfigSpec.Builder().configure(Client::new); + CLIENT_SPEC = specPair.getRight(); + CLIENT = specPair.getLeft(); + CommentedFileConfig clientConfig = CommentedFileConfig.builder(CONFIG_PATH) + .writingMode(WritingMode.REPLACE) + .build(); + clientConfig.load(); + clientConfig.save(); + CLIENT_SPEC.setConfig(clientConfig); + } + + @SubscribeEvent + public static void onLoad(final ModConfig.Loading configEvent) + { + LogManager.getLogger().debug(ModInfo.NAME, "Loaded forge config file {}", configEvent.getConfig().getFileName()); + } + + @SubscribeEvent + public static void onFileChange(final ModConfig.Reloading configEvent) + { + LogManager.getLogger().debug(ModInfo.NAME, "Forge config just got changed on the file system!"); + } + +} diff --git a/src/main/java/com/seibel/lod/api/forge/LodForgeMain.java b/src/main/java/com/seibel/lod/api/forge/ForgeMain.java similarity index 90% rename from src/main/java/com/seibel/lod/api/forge/LodForgeMain.java rename to src/main/java/com/seibel/lod/api/forge/ForgeMain.java index f61457ee4..4457c62da 100644 --- a/src/main/java/com/seibel/lod/api/forge/LodForgeMain.java +++ b/src/main/java/com/seibel/lod/api/forge/ForgeMain.java @@ -40,17 +40,17 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; * @version 7-3-2021 */ @Mod(ModInfo.ID) -public class LodForgeMain +public class ForgeMain { - public static ClientProxy clientProxy; + public static ForgeClientProxy forgeClientProxy; private void init(final FMLCommonSetupEvent event) { - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, LodConfig.CLIENT_SPEC); + ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.CLIENT_SPEC); } - public LodForgeMain() + public ForgeMain() { // Register the methods FMLJavaModLoadingContext.get().getModEventBus().addListener(this::init); @@ -62,8 +62,8 @@ public class LodForgeMain private void onClientStart(final FMLClientSetupEvent event) { - clientProxy = new ClientProxy(); - MinecraftForge.EVENT_BUS.register(clientProxy); + forgeClientProxy = new ForgeClientProxy(); + MinecraftForge.EVENT_BUS.register(forgeClientProxy); } diff --git a/src/main/java/com/seibel/lod/api/forge/LodConfig.java b/src/main/java/com/seibel/lod/api/forge/LodConfig.java deleted file mode 100644 index fc5c007c1..000000000 --- a/src/main/java/com/seibel/lod/api/forge/LodConfig.java +++ /dev/null @@ -1,591 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly 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.api.forge; - -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.apache.commons.lang3.tuple.Pair; -import org.apache.logging.log4j.LogManager; - -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.WritingMode; -import com.seibel.lod.ModInfo; -import com.seibel.lod.enums.config.BlockToAvoid; -import com.seibel.lod.enums.config.BufferRebuildTimes; -import com.seibel.lod.enums.config.DistanceGenerationMode; -import com.seibel.lod.enums.config.GenerationPriority; -import com.seibel.lod.enums.config.GpuUploadMethod; -import com.seibel.lod.enums.config.HorizontalQuality; -import com.seibel.lod.enums.config.HorizontalResolution; -import com.seibel.lod.enums.config.HorizontalScale; -import com.seibel.lod.enums.config.LodTemplate; -import com.seibel.lod.enums.config.VanillaOverdraw; -import com.seibel.lod.enums.config.VerticalQuality; -import com.seibel.lod.enums.rendering.DebugMode; -import com.seibel.lod.enums.rendering.FogDistance; -import com.seibel.lod.enums.rendering.FogDrawOverride; -import com.seibel.lod.util.LodUtil; - -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.config.ModConfig; - -/** - * This handles any configuration the user has access to. - * @author Leonardo Amato - * @author James Seibel - * @version 10-25-2021 - */ -@Mod.EventBusSubscriber -public class LodConfig -{ - // CONFIG STRUCTURE - // -> Client - // | - // |-> Graphics - // | |-> QualityOption - // | |-> FogQualityOption - // | |-> AdvancedGraphicsOption - // | - // |-> World Generation - // | - // |-> Advanced Mod Option - // |-> Threads - // |-> Buffers - // |-> Debugging - - - - public static class Client - { - public final Graphics graphics; - public final WorldGenerator worldGenerator; - public final AdvancedModOptions advancedModOptions; - - - //================// - // Client Configs // - //================// - public Client(ForgeConfigSpec.Builder builder) - { - builder.push(this.getClass().getSimpleName()); - { - graphics = new Graphics(builder); - worldGenerator = new WorldGenerator(builder); - advancedModOptions = new AdvancedModOptions(builder); - } - builder.pop(); - } - - - //==================// - // Graphics Configs // - //==================// - public static class Graphics - { - - public final QualityOption qualityOption; - public final FogQualityOption fogQualityOption; - public final AdvancedGraphicsOption advancedGraphicsOption; - - Graphics(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings control how the mod will look in game").push("Graphics"); - { - qualityOption = new QualityOption(builder); - advancedGraphicsOption = new AdvancedGraphicsOption(builder); - fogQualityOption = new FogQualityOption(builder); - } - builder.pop(); - } - - - 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 detailed the fake chunks will be.").push(this.getClass().getSimpleName()); - - verticalQuality = builder - .comment("\n\n" - + " This indicates how detailed fake chunks 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 fake chunks 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 fake chunks 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(); - } - } - - - public static class FogQualityOption - { - public final ForgeConfigSpec.EnumValue fogDistance; - - public final ForgeConfigSpec.EnumValue fogDrawOverride; - - public final ForgeConfigSpec.BooleanValue disableVanillaFog; - - 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 fake chunks? \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.FAR); - - fogDrawOverride = builder - .comment("\n\n" - + " When should fog be drawn? \n" - + " " + FogDrawOverride.OPTIFINE_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.FANCY + ". \n" - + " " + FogDrawOverride.NO_FOG + ": Never draw fog on the LODs \n" - + " " + FogDrawOverride.FAST + ": Always draw fast fog on the LODs \n" - + " " + FogDrawOverride.FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n") - .defineEnum("Fog Draw Override", FogDrawOverride.FANCY); - - disableVanillaFog = builder - .comment("\n\n" - + " If true disable Minecraft's fog. \n\n" - + "" - + " Experimental! May cause issues with Sodium. \n\n" - + "" - + " Unlike Optifine or Sodium's fog disabling option this won't change \n" - + " performance (we don't actually disable the fog, we just tell it to render a infinite distance away). \n" - + " May or may not play nice with other mods that edit fog. \n") - .define("Experimental Disable Vanilla Fog", false); - - builder.pop(); - } - } - - - public static class AdvancedGraphicsOption - { - public final ForgeConfigSpec.EnumValue lodTemplate; - - public final ForgeConfigSpec.BooleanValue disableDirectionalCulling; - - public final ForgeConfigSpec.BooleanValue alwaysDrawAtMaxQuality; - - public final ForgeConfigSpec.EnumValue vanillaOverdraw; - - public final ForgeConfigSpec.EnumValue gpuUploadMethod; - - public final ForgeConfigSpec.BooleanValue useExtendedNearClipPlane; - - AdvancedGraphicsOption(ForgeConfigSpec.Builder builder) - { - - builder.comment("Advanced graphics option for the mod").push(this.getClass().getSimpleName()); - - 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 fake chunks 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 quality falloff, \n" - + " all fake chunks 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.BORDER + ": LODs will render only on the border of vanilla chunks preventing only some holes in the world. \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); - - gpuUploadMethod = builder - .comment("\n\n" - + " What method should be used to upload geometry to the GPU? \n\\n" - + "" - + " " + GpuUploadMethod.BUFFER_STORAGE + ": Default if OpenGL 4.5 is supported. Fast rendering, no stuttering. \n" - + " " + GpuUploadMethod.SUB_DATA + ": Default if OpenGL 4.5 is NOT supported. Fast rendering but may stutter when uploading. \n" - + " " + GpuUploadMethod.BUFFER_MAPPING + ": Slow rendering but won't stutter when uploading. Possibly better than " + GpuUploadMethod.SUB_DATA + " if using a integrated GPU. \n") - .defineEnum("GPU Upload Method", GpuUploadMethod.BUFFER_STORAGE); - - // This is a temporary fix (like vanilla overdraw) - // hopefully we can remove both once we get individual chunk rendering figured out - useExtendedNearClipPlane = builder - .comment("\n\n" - + " Will prevent some overdraw issues, but may cause nearby fake chunks to render incorrectly \n" - + " especially when in/near an ocean. \n") - .define("Use Extended Near Clip Plane", false); - - - builder.pop(); - } - } - } - - - - - //========================// - // WorldGenerator Configs // - //========================// - public static class WorldGenerator - { - 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; - - WorldGenerator(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings control how fake chunks outside your normal view range are generated.").push("Generation"); - - 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 + ": Use all blocks when generating fake chunks \n\n" - + "" - + " " + BlockToAvoid.NON_FULL + ": Only use full blocks when generating fake chunks (ignores slabs, lanterns, torches, grass, etc.) \n\n" - + "" - + " " + BlockToAvoid.NO_COLLISION + ": Only use solid blocks when generating fake chunks (ignores grass, torches, etc.) \n" - + "" - + " " + BlockToAvoid.BOTH + ": Only use full solid blocks when generating fake chunks \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(); - } - } - - - - - //============================// - // AdvancedModOptions Configs // - //============================// - 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 fake chunks). \n" - + " If you experience high CPU usage when NOT generating distant \n" - + " fake chunks, 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(); - } - } - - - - - //===============// - // Debug Options // - //===============// - 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 fake chunks will be drawn. \n" - + " If false, the mod will still generate fake chunks, \n" - + " but they won't be rendered. \n") - .define("Enable Rendering", true); - - debugMode = builder - .comment("\n\n" - + " " + DebugMode.OFF + ": Fake chunks will be drawn with their normal colors. \n" - + " " + DebugMode.SHOW_DETAIL + ": Fake chunks color will be based on their detail level. \n" - + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": Fake chunks color will be based on their detail level, drawn as a wireframe. \n") - .defineEnum("Debug Mode", 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("Enable Debug Keybinding", false); - - builder.pop(); - } - } - - - public static class Buffers - { - public final ForgeConfigSpec.EnumValue rebuildTimes; - - Buffers(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings affect how often geometry is are built.").push(this.getClass().getSimpleName()); - - rebuildTimes = builder - .comment("\n\n" - + " How frequently should geometry be rebuilt and sent to the GPU? \n" - + " Higher 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 */ - private static final Path CONFIG_PATH = Paths.get("config", ModInfo.NAME + ".toml"); - - public static final ForgeConfigSpec CLIENT_SPEC; - public static final Client CLIENT; - - static - { - final Pair specPair = new ForgeConfigSpec.Builder().configure(Client::new); - CLIENT_SPEC = specPair.getRight(); - CLIENT = specPair.getLeft(); - CommentedFileConfig clientConfig = CommentedFileConfig.builder(CONFIG_PATH) - .writingMode(WritingMode.REPLACE) - .build(); - clientConfig.load(); - clientConfig.save(); - CLIENT_SPEC.setConfig(clientConfig); - } - - @SubscribeEvent - public static void onLoad(final ModConfig.Loading configEvent) - { - LogManager.getLogger().debug(ModInfo.NAME, "Loaded forge config file {}", configEvent.getConfig().getFileName()); - } - - @SubscribeEvent - public static void onFileChange(final ModConfig.Reloading configEvent) - { - LogManager.getLogger().debug(ModInfo.NAME, "Forge config just got changed on the file system!"); - } - -} diff --git a/src/main/java/com/seibel/lod/api/lod/ClientApi.java b/src/main/java/com/seibel/lod/api/lod/ClientApi.java index 260ef67c3..6b657e9ed 100644 --- a/src/main/java/com/seibel/lod/api/lod/ClientApi.java +++ b/src/main/java/com/seibel/lod/api/lod/ClientApi.java @@ -22,7 +22,7 @@ package com.seibel.lod.api.lod; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.builders.worldGeneration.LodGenWorker; import com.seibel.lod.objects.lod.LodDimension; import com.seibel.lod.objects.math.Mat4f; @@ -119,7 +119,7 @@ public class ClientApi // 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 ApiShared.previousChunkRenderDistance = mc.getRenderDistance(); - ApiShared.previousLodRenderDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(); + ApiShared.previousLodRenderDistance = ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(); } catch (Exception e) { @@ -163,7 +163,7 @@ public class ClientApi // LodConfig.CLIENT.buffers.rebuildTimes.set(BufferRebuildTimes.FREQUENT); - LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(true); + ForgeConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(true); // LodConfig.CLIENT.debugging.debugMode.set(DebugMode.SHOW_DETAIL); } diff --git a/src/main/java/com/seibel/lod/api/lod/ConfigApi.java b/src/main/java/com/seibel/lod/api/lod/ConfigApi.java deleted file mode 100644 index 29c89bd9b..000000000 --- a/src/main/java/com/seibel/lod/api/lod/ConfigApi.java +++ /dev/null @@ -1,498 +0,0 @@ -package com.seibel.lod.api.lod; - -import com.seibel.lod.api.forge.LodConfig; -import com.seibel.lod.enums.config.BlockToAvoid; -import com.seibel.lod.enums.config.BufferRebuildTimes; -import com.seibel.lod.enums.config.DistanceGenerationMode; -import com.seibel.lod.enums.config.GenerationPriority; -import com.seibel.lod.enums.config.GpuUploadMethod; -import com.seibel.lod.enums.config.HorizontalQuality; -import com.seibel.lod.enums.config.HorizontalResolution; -import com.seibel.lod.enums.config.HorizontalScale; -import com.seibel.lod.enums.config.LodTemplate; -import com.seibel.lod.enums.config.VanillaOverdraw; -import com.seibel.lod.enums.config.VerticalQuality; -import com.seibel.lod.enums.rendering.DebugMode; -import com.seibel.lod.enums.rendering.FogDistance; -import com.seibel.lod.enums.rendering.FogDrawOverride; -import com.seibel.lod.objects.MinDefaultMax; -import com.seibel.lod.util.LodUtil; - -import net.minecraftforge.common.ForgeConfigSpec; - -/** - * This holds the config defaults and setters/getters - * that should be hooked into the host mod loader (Fabric, Forge, etc.). - * - * @author James Seibel - * @version 11-14-2021 - */ -public class ConfigApi -{ - public static final Client client = new Client(); - - - public static class Client - { - public final Graphics graphics; - public final WorldGenerator worldGenerator; - public final AdvancedModOptions advancedModOptions; - - - //================// - // Client Configs // - //================// - public Client() - { - graphics = new Graphics(); - worldGenerator = new WorldGenerator(); - advancedModOptions = new AdvancedModOptions(); - } - - - //==================// - // Graphics Configs // - //==================// - public static class Graphics - { - - public final QualityOption qualityOption; - public final FogQualityOption fogQualityOption; - public final AdvancedGraphicsOption advancedGraphicsOption; - - Graphics() - { - qualityOption = new QualityOption(); - advancedGraphicsOption = new AdvancedGraphicsOption(); - fogQualityOption = new FogQualityOption(); - } - - - public static class QualityOption - { - public static final HorizontalResolution DRAW_RESOLUTION_DEFAULT = HorizontalResolution.BLOCK; - public HorizontalResolution getDrawResolution() - { - return LodConfig.CLIENT.graphics.qualityOption.drawResolution.get(); - } - public void setDrawResolution(HorizontalResolution newHorizontalResolution) - { - LodConfig.CLIENT.graphics.qualityOption.drawResolution.set(newHorizontalResolution); - } - - public static final MinDefaultMax LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX = new MinDefaultMax(32, 64, 1024); - public int getLodChunkRenderDistance() - { - return LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(); - } - public void setLodChunkRenderDistance(int newLodChunkRenderDistance) - { - LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.set(newLodChunkRenderDistance); - } - - public static final VerticalQuality VERTICAL_QUALITY_DEFAULT = VerticalQuality.MEDIUM; - public VerticalQuality getVerticalQuality() - { - return LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); - } - public void setVerticalQuality(VerticalQuality newVerticalQuality) - { - LodConfig.CLIENT.graphics.qualityOption.verticalQuality.set(newVerticalQuality); - } - - public static final HorizontalScale HORIZONTAL_SCALE_DEFAULT = HorizontalScale.MEDIUM; - public HorizontalScale getHorizontalScale() - { - return LodConfig.CLIENT.graphics.qualityOption.horizontalScale.get(); - } - public void setLodChunkRenderDistance(HorizontalScale newHorizontalScale) - { - LodConfig.CLIENT.graphics.qualityOption.horizontalScale.set(newHorizontalScale); - } - - public static final HorizontalQuality HORIZONTAL_QUALITY_DEFAULT = HorizontalQuality.MEDIUM; - public HorizontalQuality getHorizontalQuality() - { - return LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get(); - } - public void setLodChunkRenderDistance(HorizontalQuality newHorizontalQuality) - { - LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.set(newHorizontalQuality); - } - } - - - public static class FogQualityOption - { - public final ForgeConfigSpec.EnumValue fogDistance; - - public final ForgeConfigSpec.EnumValue fogDrawOverride; - - public final ForgeConfigSpec.BooleanValue disableVanillaFog; - - 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 fake chunks? \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.FAR); - - fogDrawOverride = builder - .comment("\n\n" - + " When should fog be drawn? \n" - + " " + FogDrawOverride.OPTIFINE_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.FANCY + ". \n" - + " " + FogDrawOverride.NO_FOG + ": Never draw fog on the LODs \n" - + " " + FogDrawOverride.FAST + ": Always draw fast fog on the LODs \n" - + " " + FogDrawOverride.FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n") - .defineEnum("Fog Draw Override", FogDrawOverride.FANCY); - - disableVanillaFog = builder - .comment("\n\n" - + " If true disable Minecraft's fog. \n\n" - + "" - + " Experimental! May cause issues with Sodium. \n\n" - + "" - + " Unlike Optifine or Sodium's fog disabling option this won't change \n" - + " performance (we don't actually disable the fog, we just tell it to render a infinite distance away). \n" - + " May or may not play nice with other mods that edit fog. \n") - .define("Experimental Disable Vanilla Fog", false); - - builder.pop(); - } - } - - - public static class AdvancedGraphicsOption - { - public final ForgeConfigSpec.EnumValue lodTemplate; - - public final ForgeConfigSpec.BooleanValue disableDirectionalCulling; - - public final ForgeConfigSpec.BooleanValue alwaysDrawAtMaxQuality; - - public final ForgeConfigSpec.EnumValue vanillaOverdraw; - - public final ForgeConfigSpec.EnumValue gpuUploadMethod; - - public final ForgeConfigSpec.BooleanValue useExtendedNearClipPlane; - - AdvancedGraphicsOption(ForgeConfigSpec.Builder builder) - { - - builder.comment("Advanced graphics option for the mod").push(this.getClass().getSimpleName()); - - 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 fake chunks 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 quality falloff, \n" - + " all fake chunks 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.BORDER + ": LODs will render only on the border of vanilla chunks preventing only some holes in the world. \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); - - gpuUploadMethod = builder - .comment("\n\n" - + " What method should be used to upload geometry to the GPU? \n\\n" - + "" - + " " + GpuUploadMethod.BUFFER_STORAGE + ": Default if OpenGL 4.5 is supported. Fast rendering, no stuttering. \n" - + " " + GpuUploadMethod.SUB_DATA + ": Default if OpenGL 4.5 is NOT supported. Fast rendering but may stutter when uploading. \n" - + " " + GpuUploadMethod.BUFFER_MAPPING + ": Slow rendering but won't stutter when uploading. Possibly better than " + GpuUploadMethod.SUB_DATA + " if using a integrated GPU. \n") - .defineEnum("GPU Upload Method", GpuUploadMethod.BUFFER_STORAGE); - - // This is a temporary fix (like vanilla overdraw) - // hopefully we can remove both once we get individual chunk rendering figured out - useExtendedNearClipPlane = builder - .comment("\n\n" - + " Will prevent some overdraw issues, but may cause nearby fake chunks to render incorrectly \n" - + " especially when in/near an ocean. \n") - .define("Use Extended Near Clip Plane", false); - - - builder.pop(); - } - } - } - - - - - //========================// - // WorldGenerator Configs // - //========================// - public static class WorldGenerator - { - 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; - - WorldGenerator(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings control how fake chunks outside your normal view range are generated.").push("Generation"); - - 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 + ": Use all blocks when generating fake chunks \n\n" - + "" - + " " + BlockToAvoid.NON_FULL + ": Only use full blocks when generating fake chunks (ignores slabs, lanterns, torches, grass, etc.) \n\n" - + "" - + " " + BlockToAvoid.NO_COLLISION + ": Only use solid blocks when generating fake chunks (ignores grass, torches, etc.) \n" - + "" - + " " + BlockToAvoid.BOTH + ": Only use full solid blocks when generating fake chunks \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(); - } - } - - - - - //============================// - // AdvancedModOptions Configs // - //============================// - 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 fake chunks). \n" - + " If you experience high CPU usage when NOT generating distant \n" - + " fake chunks, 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(); - } - } - - - - - //===============// - // Debug Options // - //===============// - 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 fake chunks will be drawn. \n" - + " If false, the mod will still generate fake chunks, \n" - + " but they won't be rendered. \n") - .define("Enable Rendering", true); - - debugMode = builder - .comment("\n\n" - + " " + DebugMode.OFF + ": Fake chunks will be drawn with their normal colors. \n" - + " " + DebugMode.SHOW_DETAIL + ": Fake chunks color will be based on their detail level. \n" - + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": Fake chunks color will be based on their detail level, drawn as a wireframe. \n") - .defineEnum("Debug Mode", 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("Enable Debug Keybinding", false); - - builder.pop(); - } - } - - - public static class Buffers - { - public final ForgeConfigSpec.EnumValue rebuildTimes; - - Buffers(ForgeConfigSpec.Builder builder) - { - builder.comment("These settings affect how often geometry is are built.").push(this.getClass().getSimpleName()); - - rebuildTimes = builder - .comment("\n\n" - + " How frequently should geometry be rebuilt and sent to the GPU? \n" - + " Higher settings may cause stuttering, but will prevent holes in the world \n") - .defineEnum("rebuildFrequency", BufferRebuildTimes.NORMAL); - - builder.pop(); - } - } - } - } - -} diff --git a/src/main/java/com/seibel/lod/api/lod/EventApi.java b/src/main/java/com/seibel/lod/api/lod/EventApi.java index 469ddfb9e..fe74de7df 100644 --- a/src/main/java/com/seibel/lod/api/lod/EventApi.java +++ b/src/main/java/com/seibel/lod/api/lod/EventApi.java @@ -21,7 +21,7 @@ package com.seibel.lod.api.lod; import org.lwjgl.glfw.GLFW; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.builders.worldGeneration.LodWorldGenerator; import com.seibel.lod.enums.config.DistanceGenerationMode; import com.seibel.lod.objects.lod.LodDimension; @@ -163,16 +163,16 @@ public class EventApi public void onKeyInput(int key, int keyAction) { - if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() + if (ForgeConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() && key == GLFW.GLFW_KEY_F4 && keyAction == GLFW.GLFW_PRESS) { - LodConfig.CLIENT.advancedModOptions.debugging.debugMode.set(LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get().getNext()); + ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.set(ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get().getNext()); } - if (LodConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() + if (ForgeConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get() && key == GLFW.GLFW_KEY_F6 && keyAction == GLFW.GLFW_PRESS) { - LodConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!LodConfig.CLIENT.advancedModOptions.debugging.drawLods.get()); + ForgeConfig.CLIENT.advancedModOptions.debugging.drawLods.set(!ForgeConfig.CLIENT.advancedModOptions.debugging.drawLods.get()); } } @@ -196,9 +196,9 @@ public class EventApi // calculate how wide the dimension(s) should be in regions int chunksWide; if (mc.getClientWorld().dimensionType().hasCeiling()) - chunksWide = Math.min(LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1; + chunksWide = Math.min(ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * 2 + 1; else - chunksWide = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 2 + 1; + chunksWide = ForgeConfig.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/builders/bufferBuilding/LodBufferBuilderFactory.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilderFactory.java index d91625317..276d616ad 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilderFactory.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilderFactory.java @@ -36,7 +36,7 @@ import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.GL45; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.api.lod.ClientApi; import com.seibel.lod.enums.LodDirection; import com.seibel.lod.enums.config.GpuUploadMethod; @@ -74,7 +74,7 @@ public class LodBufferBuilderFactory /** The thread used to generate new LODs off the main thread. */ public static final ExecutorService mainGenThread = Executors.newSingleThreadExecutor(new LodThreadFactory(LodBufferBuilderFactory.class.getSimpleName() + " - main")); /** The threads used to generate buffers. */ - public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfBufferBuilderThreads.get(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); + public static final ExecutorService bufferBuilderThreads = Executors.newFixedThreadPool(ForgeConfig.CLIENT.advancedModOptions.threading.numberOfBufferBuilderThreads.get(), new ThreadFactoryBuilder().setNameFormat("Buffer-Builder-%d").build()); /** * When uploading to a buffer that is too small, @@ -402,7 +402,7 @@ public class LodBufferBuilderFactory break; //We send the call to create the vertices - LodConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, detailLevel, posX, posZ, box, renderer.previousDebugMode, adjShadeDisabled); } @@ -481,7 +481,7 @@ public class LodBufferBuilderFactory // check if the chunk is on the border boolean isItBorderPos; - if (LodConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get() == VanillaOverdraw.BORDER) + if (ForgeConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get() == VanillaOverdraw.BORDER) isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1); else isItBorderPos = false; @@ -759,12 +759,12 @@ public class LodBufferBuilderFactory glProxy.setGlContext(GlProxyContext.LOD_BUILDER); // determine the upload method - GpuUploadMethod uploadMethod = LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get(); + GpuUploadMethod uploadMethod = ForgeConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get(); if (!glProxy.bufferStorageSupported && uploadMethod == GpuUploadMethod.BUFFER_STORAGE) { // if buffer storage isn't supported // default to SUB_DATA - LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.SUB_DATA); + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(GpuUploadMethod.SUB_DATA); uploadMethod = GpuUploadMethod.SUB_DATA; } 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 721813908..13e37a8c7 100644 --- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java @@ -22,7 +22,7 @@ package com.seibel.lod.builders.lodBuilding; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.enums.config.DistanceGenerationMode; import com.seibel.lod.enums.config.HorizontalResolution; import com.seibel.lod.objects.lod.LodDimension; @@ -355,7 +355,7 @@ public class LodBuilder // snow, flowers, etc. Get the above block so we can still get the color // of the snow, flower, etc. that may be above this block int aboveColorInt = 0; - if (LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull || LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision) + if (ForgeConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull || ForgeConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision) { blockPos.set(chunk.getPos().getMinBlockX() + xRel, yAbs + 1, chunk.getPos().getMinBlockZ() + zRel); aboveColorInt = getColorForBlock(chunk, blockPos); @@ -519,8 +519,8 @@ public class LodBuilder if (chunk.isWaterLogged(blockPos)) return true; - boolean nonFullAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull; - boolean noCollisionAvoidance = LodConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; + boolean nonFullAvoidance = ForgeConfig.CLIENT.worldGenerator.blockToAvoid.get().nonFull; + boolean noCollisionAvoidance = ForgeConfig.CLIENT.worldGenerator.blockToAvoid.get().noCollision; BlockShapeWrapper block = chunk.getBlockShapeWrapper(blockPos); return !block.isToAvoid() diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java index 7c84d6424..a943d8972 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodGenWorker.java @@ -23,7 +23,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.api.lod.ClientApi; import com.seibel.lod.builders.lodBuilding.LodBuilder; import com.seibel.lod.enums.config.DistanceGenerationMode; @@ -43,7 +43,7 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker; */ public class LodGenWorker implements IWorker // TODO is there a way to have this fabric/forge independent? { - public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); + public static ExecutorService genThreads = Executors.newFixedThreadPool(ForgeConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); private boolean threadStarted = false; private final LodChunkGenThread thread; @@ -79,7 +79,7 @@ public class LodGenWorker implements IWorker // TODO is there a way to have this { if (!threadStarted) { - if (LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get() == DistanceGenerationMode.SERVER) + if (ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get() == DistanceGenerationMode.SERVER) { // if we are using SERVER generation that has to be done // synchronously to prevent crashing and harmful @@ -217,7 +217,7 @@ public class LodGenWorker implements IWorker // TODO is there a way to have this { genThreads.shutdownNow(); } - genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build()); + genThreads = Executors.newFixedThreadPool(ForgeConfig.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 9df08e128..f104dd868 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -25,7 +25,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.builders.lodBuilding.LodBuilder; import com.seibel.lod.enums.config.DistanceGenerationMode; import com.seibel.lod.objects.PosToGenerateContainer; @@ -93,7 +93,7 @@ public class LodWorldGenerator */ public void queueGenerationRequests(LodDimension lodDim, LodRenderer renderer, LodBuilder lodBuilder) { - if (LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get() != DistanceGenerationMode.NONE + if (ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get() != DistanceGenerationMode.NONE && !generatorThreadRunning && mc.hasSinglePlayerServer()) { @@ -101,7 +101,7 @@ public class LodWorldGenerator generatorThreadRunning = true; // just in case the config changed - maxChunkGenRequests = LodConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get() * 8; + maxChunkGenRequests = ForgeConfig.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 new file mode 100644 index 000000000..968bc964f --- /dev/null +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -0,0 +1,651 @@ +package com.seibel.lod.config; + +import com.seibel.lod.enums.config.BlockToAvoid; +import com.seibel.lod.enums.config.BufferRebuildTimes; +import com.seibel.lod.enums.config.DistanceGenerationMode; +import com.seibel.lod.enums.config.GenerationPriority; +import com.seibel.lod.enums.config.GpuUploadMethod; +import com.seibel.lod.enums.config.HorizontalQuality; +import com.seibel.lod.enums.config.HorizontalResolution; +import com.seibel.lod.enums.config.HorizontalScale; +import com.seibel.lod.enums.config.LodTemplate; +import com.seibel.lod.enums.config.VanillaOverdraw; +import com.seibel.lod.enums.config.VerticalQuality; +import com.seibel.lod.enums.rendering.DebugMode; +import com.seibel.lod.enums.rendering.FogDistance; +import com.seibel.lod.enums.rendering.FogDrawOverride; +import com.seibel.lod.objects.MinDefaultMax; +import com.seibel.lod.util.LodUtil; +import com.seibel.lod.wrappers.config.LodConfigWrapper; + +/** + * Interacts with the LodConfigWrapper to get the config + * + * @author James Seibel + * @version 11-14-2021 + */ +public class LodConfig +{ + public static final Client client = new Client(); + + + public static class Client + { + public final Graphics graphics; + public final WorldGenerator worldGenerator; + public final AdvancedModOptions advancedModOptions; + + + //================// + // Client Configs // + //================// + public Client() + { + graphics = new Graphics(); + worldGenerator = new WorldGenerator(); + advancedModOptions = new AdvancedModOptions(); + } + + + //==================// + // Graphics Configs // + //==================// + public static class Graphics + { + + public final QualityOption qualityOption; + public final FogQualityOption fogQualityOption; + public final AdvancedGraphicsOption advancedGraphicsOption; + + Graphics() + { + qualityOption = new QualityOption(); + advancedGraphicsOption = new AdvancedGraphicsOption(); + fogQualityOption = new FogQualityOption(); + } + + + public static class QualityOption + { + public static final String DESC = "These settings control how detailed the fake chunks will be."; + + + + public static final String DRAW_RESOLUTION_DESC = "" + + " What is the maximum detail fake chunks 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"; + public static final HorizontalResolution DRAW_RESOLUTION_DEFAULT = HorizontalResolution.BLOCK; + + public HorizontalResolution getDrawResolution() + { + return LodConfigWrapper.CLIENT.graphics.qualityOption.getDrawResolution(); + } + public void setDrawResolution(HorizontalResolution newHorizontalResolution) + { + LodConfigWrapper.CLIENT.graphics.qualityOption.setDrawResolution(newHorizontalResolution); + } + + + + public static final String LOD_CHUNK_RENDER_DISTANCE_DESC = "" + + " The mod's render distance, measured in chunks. \n"; + public static final MinDefaultMax LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX = new MinDefaultMax(16, 64, 1024); + + public int getLodChunkRenderDistance() + { + return LodConfigWrapper.CLIENT.graphics.qualityOption.getLodChunkRenderDistance(); + } + public void setLodChunkRenderDistance(int newLodChunkRenderDistance) + { + LodConfigWrapper.CLIENT.graphics.qualityOption.setLodChunkRenderDistance(newLodChunkRenderDistance); + } + + + + public static final String VERTICAL_QUALITY_DESC = "" + + " This indicates how detailed fake chunks 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"; + public static final VerticalQuality VERTICAL_QUALITY_DEFAULT = VerticalQuality.MEDIUM; + + public VerticalQuality getVerticalQuality() + { + return LodConfigWrapper.CLIENT.graphics.qualityOption.getVerticalQuality(); + } + public void setVerticalQuality(VerticalQuality newVerticalQuality) + { + LodConfigWrapper.CLIENT.graphics.qualityOption.setVerticalQuality(newVerticalQuality); + } + + + + public static final String HORIZONTAL_SCALE_DESC = "" + + " This indicates how quickly fake chunks 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"; + public static final HorizontalScale HORIZONTAL_SCALE_DEFAULT = HorizontalScale.MEDIUM; + + public HorizontalScale getHorizontalScale() + { + return LodConfigWrapper.CLIENT.graphics.qualityOption.getHorizontalScale(); + } + public void setLodChunkRenderDistance(HorizontalScale newHorizontalScale) + { + LodConfigWrapper.CLIENT.graphics.qualityOption.setHorizontalScale(newHorizontalScale); + } + + + + public static final String HORIZONTAL_QUALITY_DESC = "" + + " 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"; + public static final HorizontalQuality HORIZONTAL_QUALITY_DEFAULT = HorizontalQuality.MEDIUM; + + public HorizontalQuality getHorizontalQuality() + { + return LodConfigWrapper.CLIENT.graphics.qualityOption.getHorizontalQuality(); + } + public void setLodChunkRenderDistance(HorizontalQuality newHorizontalQuality) + { + LodConfigWrapper.CLIENT.graphics.qualityOption.setHorizontalQuality(newHorizontalQuality); + } + } + + + public static class FogQualityOption + { + public static final String DESC = "These settings control the fog quality."; + + + + public static final String FOG_DISTANCE_DESC = "" + + " At what distance should Fog be drawn on the fake chunks? \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"; + public static final FogDistance FOG_DISTANCE_DEFAULT = FogDistance.FAR; + + public FogDistance getFogDistance() + { + return LodConfigWrapper.CLIENT.graphics.fogQualityOption.getFogDistance(); + } + public void setFogDistance(FogDistance newFogDistance) + { + LodConfigWrapper.CLIENT.graphics.fogQualityOption.setFogDistance(newFogDistance); + } + + + + public static final String FOG_DRAW_OVERRIDE_DESC = "" + + " When should fog be drawn? \n" + + " " + FogDrawOverride.OPTIFINE_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.FANCY + ". \n" + + " " + FogDrawOverride.NO_FOG + ": Never draw fog on the LODs \n" + + " " + FogDrawOverride.FAST + ": Always draw fast fog on the LODs \n" + + " " + FogDrawOverride.FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n"; + public static final FogDrawOverride FOG_DRAW_OVERRIDE_DEFAULT = FogDrawOverride.FANCY; + + public FogDrawOverride getFogDrawOverride() + { + return LodConfigWrapper.CLIENT.graphics.fogQualityOption.getFogDrawOverride(); + } + public void setFogDrawOverride(FogDrawOverride newFogDrawOverride) + { + LodConfigWrapper.CLIENT.graphics.fogQualityOption.setFogDrawOverride(newFogDrawOverride); + } + + + + public static final String DISABLE_VANILLA_FOG_DESC = "" + + " If true disable Minecraft's fog. \n\n" + + "" + + " Experimental! May cause issues with Sodium. \n\n" + + "" + + " Unlike Optifine or Sodium's fog disabling option this won't change \n" + + " performance (we don't actually disable the fog, we just tell it to render a infinite distance away). \n" + + " May or may not play nice with other mods that edit fog. \n"; + public static final boolean DISABLE_VANILLA_FOG_DEFAULT = false; + + public boolean getDisableVanillaFog() + { + return LodConfigWrapper.CLIENT.graphics.fogQualityOption.getDisableVanillaFog(); + } + public void setDisableVanillaFog(boolean newDisableVanillaFog) + { + LodConfigWrapper.CLIENT.graphics.fogQualityOption.setDisableVanillaFog(newDisableVanillaFog); + } + } + + + public static class AdvancedGraphicsOption + { + public static final String DESC = "Advanced graphics options for the mod"; + + + + public static final String LOD_TEMPLATE_DESC = "" + + " 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"; + public static final LodTemplate LOD_TEMPLATE_DEFAULT = LodTemplate.CUBIC; + + public LodTemplate getLodTemplate() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getLodTemplate(); + } + public void setLodTemplate(LodTemplate newLodTemplate) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setLodTemplate(newLodTemplate); + } + + + + public static final String DISABLE_DIRECTIONAL_CULLING_DESC = "" + + " If false fake chunks 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"; + public static final boolean DISABLE_DIRECTIONAL_CULLING_DEFAULT = false; + + public boolean getDisableDirectionalCulling() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getDisableDirectionalCulling(); + } + public void setDisableDirectionalCulling(boolean newDisableDirectionalCulling) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setDisableDirectionalCulling(newDisableDirectionalCulling); + } + + + + public static final String ALWAYS_DRAW_AT_MAD_QUALITY_DESC = "" + + " Disable quality falloff, \n" + + " all fake chunks 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"; + public static final boolean ALWAYS_DRAW_AT_MAD_QUALITY_DEFAULT = false; + + public boolean getAlwaysDrawAtMaxQuality() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getAlwaysDrawAtMaxQuality(); + } + public void setAlwaysDrawAtMaxQuality(boolean newAlwaysDrawAtMaxQuality) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setAlwaysDrawAtMaxQuality(newAlwaysDrawAtMaxQuality); + } + + + + public static final String VANILLA_OVERDRAW_DESC = "" + + " 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.BORDER + ": LODs will render only on the border of vanilla chunks preventing only some holes in the world. \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"; + public static final VanillaOverdraw VANILLA_OVERDRAW_DEFAULT = VanillaOverdraw.DYNAMIC; + + public VanillaOverdraw getVanillaOverdraw() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getVanillaOverdraw(); + } + public void setVanillaOverdraw(VanillaOverdraw newVanillaOverdraw) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setVanillaOverdraw(newVanillaOverdraw); + } + + + + public static final String GPU_UPLOAD_METHOD_DESC = "" + + " What method should be used to upload geometry to the GPU? \n\n" + + "" + + " " + GpuUploadMethod.BUFFER_STORAGE + ": Default if OpenGL 4.5 is supported. Fast rendering, no stuttering. \n" + + " " + GpuUploadMethod.SUB_DATA + ": Default if OpenGL 4.5 is NOT supported. Fast rendering but may stutter when uploading. \n" + + " " + GpuUploadMethod.BUFFER_MAPPING + ": Slow rendering but won't stutter when uploading. Possibly better than " + GpuUploadMethod.SUB_DATA + " if using a integrated GPU. \n"; + public static final GpuUploadMethod GPU_UPLOAD_METHOD_DEFAULT = GpuUploadMethod.BUFFER_STORAGE; + + public GpuUploadMethod getGpuUploadMethod() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getGpuUploadMethod(); + } + public void setGpuUploadMethod(GpuUploadMethod newDisableVanillaFog) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setGpuUploadMethod(newDisableVanillaFog); + } + + + + public static final String USE_EXTENDED_NEAR_CLIP_PLANE_DESC = "" + + " Will prevent some overdraw issues, but may cause nearby fake chunks to render incorrectly \n" + + " especially when in/near an ocean. \n"; + public static final boolean USE_EXTENDED_NEAR_CLIP_PLANE_DEFAULT = false; + + public boolean getUseExtendedNearClipPlane() + { + return LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.getUseExtendedNearClipPlane(); + } + public void setGpuUploadMethod(boolean newUseExtendedNearClipPlane) + { + LodConfigWrapper.CLIENT.graphics.advancedGraphicsOption.setUseExtendedNearClipPlane(newUseExtendedNearClipPlane); + } + } + } + + + + + //========================// + // WorldGenerator Configs // + //========================// + public static class WorldGenerator + { + public static final String DESC = "These settings control how fake chunks outside your normal view range are generated."; + + + + public static final String GENERATION_PRIORITY_DESC = "" + + " " + 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"; + public static final GenerationPriority GENERATION_PRIORITY_DEFAULT = GenerationPriority.FAR_FIRST; + + public GenerationPriority getGenerationPriority() + { + return LodConfigWrapper.CLIENT.worldGenerator.getGenerationPriority(); + } + public void setGenerationPriority(GenerationPriority newGenerationPriority) + { + LodConfigWrapper.CLIENT.worldGenerator.setGenerationPriority(newGenerationPriority); + } + + + + public static final String DISTANCE_GENERATION_MODE_DESC = "" + + " 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"; + public static final DistanceGenerationMode DISTANCE_GENERATION_MODE_DEFAULT = DistanceGenerationMode.SURFACE; + + public DistanceGenerationMode getDistanceGenerationMode() + { + return LodConfigWrapper.CLIENT.worldGenerator.getDistanceGenerationMode(); + } + public void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode) + { + LodConfigWrapper.CLIENT.worldGenerator.setDistanceGenerationMode(newDistanceGenerationMode); + } + + + + public static final String ALLOW_UNSTABLE_FEATURE_GENERATION_DESC = "" + + " 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"; + public static final boolean ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT = false; + + public boolean getAllowUnstableFeatureGeneration() + { + return LodConfigWrapper.CLIENT.worldGenerator.getAllowUnstableFeatureGeneration(); + } + public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration) + { + LodConfigWrapper.CLIENT.worldGenerator.setAllowUnstableFeatureGeneration(newAllowUnstableFeatureGeneration); + } + + + + public static final String BLOCK_TO_AVOID_DESC = "" + + " " + BlockToAvoid.NONE + ": Use all blocks when generating fake chunks \n\n" + + "" + + " " + BlockToAvoid.NON_FULL + ": Only use full blocks when generating fake chunks (ignores slabs, lanterns, torches, grass, etc.) \n\n" + + "" + + " " + BlockToAvoid.NO_COLLISION + ": Only use solid blocks when generating fake chunks (ignores grass, torches, etc.) \n" + + "" + + " " + BlockToAvoid.BOTH + ": Only use full solid blocks when generating fake chunks \n"; + public static final BlockToAvoid BLOCK_TO_AVOID_DEFAULT = BlockToAvoid.BOTH; + + public BlockToAvoid getBlockToAvoid() + { + return LodConfigWrapper.CLIENT.worldGenerator.getBlockToAvoid(); + } + public void setBlockToAvoid(BlockToAvoid newBlockToAvoid) + { + LodConfigWrapper.CLIENT.worldGenerator.setBlockToAvoid(newBlockToAvoid); + } + } + + + + + //============================// + // AdvancedModOptions Configs // + //============================// + public static class AdvancedModOptions + { + + public final Threading threading; + public final Debugging debugging; + public final Buffers buffers; + + public AdvancedModOptions() + { + threading = new Threading(); + debugging = new Debugging(); + buffers = new Buffers(); + } + + public static class Threading + { + public static final String DESC = "These settings control how many CPU threads the mod uses for different tasks."; + + + + public static final String NUMBER_OF_WORLD_GENERATION_THREADS_DESC = "" + + " 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"; + public static final MinDefaultMax NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT = new MinDefaultMax(1, Runtime.getRuntime().availableProcessors() / 2, Runtime.getRuntime().availableProcessors()); + + public int getNumberOfWorldGenerationThreads() + { + return LodConfigWrapper.CLIENT.advancedModOptions.threading.getNumberOfWorldGenerationThreads(); + } + public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads) + { + LodConfigWrapper.CLIENT.advancedModOptions.threading.setNumberOfWorldGenerationThreads(newNumberOfWorldGenerationThreads); + } + + + + public static final String NUMBER_OF_BUFFER_BUILDER_THREADS_DESC = "" + + " This is how many threads are used when building vertex buffers \n" + + " (The things sent to your GPU to draw the fake chunks). \n" + + " If you experience high CPU usage when NOT generating distant \n" + + " fake chunks, 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"; + public static final MinDefaultMax NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX = new MinDefaultMax(1, Runtime.getRuntime().availableProcessors() / 2, Runtime.getRuntime().availableProcessors()); + + public int getNumberOfBufferBuilderThreads() + { + return LodConfigWrapper.CLIENT.advancedModOptions.threading.getNumberOfBufferBuilderThreads(); + } + public void setNumberOfBufferBuilderThreads(int newNumberOfWorldBuilderThreads) + { + LodConfigWrapper.CLIENT.advancedModOptions.threading.setNumberOfBufferBuilderThreads(newNumberOfWorldBuilderThreads); + } + } + + + + + //===============// + // Debug Options // + //===============// + public static class Debugging + { + public static final String DESC = "These settings can be used to look for bugs, or see how certain aspects of the mod work."; + + + + public static final String DRAW_LODS_DESC = "" + + " If true, the mod is enabled and fake chunks will be drawn. \n" + + " If false, the mod will still generate fake chunks, \n" + + " but they won't be rendered. \n"; + public static final boolean DRAW_LODS_DEFAULT = true; + + public boolean getDrawLods() + { + return LodConfigWrapper.CLIENT.advancedModOptions.debugging.getDrawLods(); + } + public void setDrawLods(boolean newDrawLods) + { + LodConfigWrapper.CLIENT.advancedModOptions.debugging.setDrawLods(newDrawLods); + } + + + + public static final String DEBUG_MODE_DESC = "" + + " " + DebugMode.OFF + ": Fake chunks will be drawn with their normal colors. \n" + + " " + DebugMode.SHOW_DETAIL + ": Fake chunks color will be based on their detail level. \n" + + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": Fake chunks color will be based on their detail level, drawn as a wireframe. \n"; + public static final DebugMode DEBUG_MODE_DEFAULT = DebugMode.OFF; + + public DebugMode getDebugMode() + { + return LodConfigWrapper.CLIENT.advancedModOptions.debugging.getDebugMode(); + } + public void setDebugMode(DebugMode newDebugMode) + { + LodConfigWrapper.CLIENT.advancedModOptions.debugging.setDebugMode(newDebugMode); + } + + + + public static final String ENABLE_DEBUG_KEYBINDINGS_DESC = "" + + " 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."; + public static final boolean ENABLE_DEBUG_KEYBINDINGS_DEFAULT = true; + + public boolean getEnableDebugKeybindings() + { + return LodConfigWrapper.CLIENT.advancedModOptions.debugging.getEnableDebugKeybindings(); + } + public void setEnableDebugKeybindings(boolean newEnableDebugKeybindings) + { + LodConfigWrapper.CLIENT.advancedModOptions.debugging.setEnableDebugKeybindings(newEnableDebugKeybindings); + } + } + + + public static class Buffers + { + public static final String DESC = "These settings affect how often geometry is rebuilt."; + + + + public static final String REBUILD_TIMES_DESC = "" + + " How frequently should geometry be rebuilt and sent to the GPU? \n" + + " Higher settings may cause stuttering, but will prevent holes in the world \n"; + public static final BufferRebuildTimes REBUILD_TIMES_DEFAULT = BufferRebuildTimes.NORMAL; + + public BufferRebuildTimes getDrawLods() + { + return LodConfigWrapper.CLIENT.advancedModOptions.buffers.getRebuildTimes(); + } + public void setDrawLods(BufferRebuildTimes newBufferRebuildTimes) + { + LodConfigWrapper.CLIENT.advancedModOptions.buffers.setRebuildTimes(newBufferRebuildTimes); + } + } + } + } + +} diff --git a/src/main/java/com/seibel/lod/enums/config/BufferRebuildTimes.java b/src/main/java/com/seibel/lod/enums/config/BufferRebuildTimes.java index 3f7c3bafa..1fdbf47ca 100644 --- a/src/main/java/com/seibel/lod/enums/config/BufferRebuildTimes.java +++ b/src/main/java/com/seibel/lod/enums/config/BufferRebuildTimes.java @@ -20,8 +20,9 @@ package com.seibel.lod.enums.config; /** - * Near_First
- * Far_First
+ * FREQUENT
+ * NORMAL
+ * RARE
*
* Determines how fast the buffers need to be regenerated * diff --git a/src/main/java/com/seibel/lod/objects/Box.java b/src/main/java/com/seibel/lod/objects/Box.java index cfece97fe..227a5defb 100644 --- a/src/main/java/com/seibel/lod/objects/Box.java +++ b/src/main/java/com/seibel/lod/objects/Box.java @@ -23,7 +23,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.enums.LodDirection; import com.seibel.lod.enums.rendering.DebugMode; import com.seibel.lod.objects.math.Vec3i; @@ -260,7 +260,7 @@ public class Box */ public int getColor(LodDirection lodDirection) { - if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != DebugMode.SHOW_DETAIL) + if (ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != DebugMode.SHOW_DETAIL) return colorMap[DIRECTION_INDEX.get(lodDirection)]; else return ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getShade(lodDirection)); diff --git a/src/main/java/com/seibel/lod/objects/lod/LodDimension.java b/src/main/java/com/seibel/lod/objects/lod/LodDimension.java index 2ec35c4a1..7ef887733 100644 --- a/src/main/java/com/seibel/lod/objects/lod/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/lod/LodDimension.java @@ -24,7 +24,7 @@ import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.enums.config.DistanceGenerationMode; import com.seibel.lod.enums.config.GenerationPriority; import com.seibel.lod.enums.config.VerticalQuality; @@ -365,9 +365,9 @@ public class LodDimension /** Either expands or loads all regions in the rendered LOD area */ public void expandOrLoadRegionsAsync(int playerPosX, int playerPosZ) { - DistanceGenerationMode generationMode = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); + DistanceGenerationMode generationMode = ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); ChunkPosWrapper newPlayerChunk = new ChunkPosWrapper(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); - VerticalQuality verticalQuality = LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); + VerticalQuality verticalQuality = ForgeConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); if (lastExpandedChunk == null) @@ -544,7 +544,7 @@ public class LodDimension dz = -1; // We can use two type of generation scheduling - switch (LodConfig.CLIENT.worldGenerator.generationPriority.get()) + switch (ForgeConfig.CLIENT.worldGenerator.generationPriority.get()) { default: case NEAR_FIRST: @@ -601,7 +601,7 @@ public class LodDimension //if(lodRegion.isChunkPreGenerated(xChunkToCheck,zChunkToCheck)) // complexity = DistanceGenerationMode.SERVER.complexity; //else - complexity = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get().complexity; + complexity = ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get().complexity; //we create the level position info of the chunk @@ -676,7 +676,7 @@ public class LodDimension { LodRegion region = getRegion(regionPos.x, regionPos.z); if (region != null) - region.getPosToRender(posToRender, playerPosX, playerPosZ, LodConfig.CLIENT.worldGenerator.generationPriority.get() == GenerationPriority.NEAR_FIRST); + region.getPosToRender(posToRender, playerPosX, playerPosZ, ForgeConfig.CLIENT.worldGenerator.generationPriority.get() == GenerationPriority.NEAR_FIRST); } /** diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 6cfb6cf79..8b0dd9ca0 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -26,7 +26,7 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import org.lwjgl.opengl.NVFogDistance; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.api.lod.ApiShared; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilderFactory; import com.seibel.lod.builders.bufferBuilding.LodBufferBuilderFactory.VertexBuffersAndOffset; @@ -231,7 +231,7 @@ public class LodRenderer // set the required open GL settings - if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME) + if (ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get() == DebugMode.SHOW_DETAIL_WIREFRAME) GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_LINE); else GL15.glPolygonMode(GL15.GL_FRONT_AND_BACK, GL15.GL_FILL); @@ -251,9 +251,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.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; + farPlaneBlockDistance = Math.min(ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(), LodUtil.CEILED_DIMENSION_MAX_RENDER_DISTANCE) * LodUtil.CHUNK_WIDTH; else - farPlaneBlockDistance = LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; + farPlaneBlockDistance = ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; Mat4f projectionMatrix = createProjectionMatrix(mcProjectionMatrix, vanillaBlockRenderedDistance, partialTicks); @@ -291,7 +291,7 @@ public class LodRenderer // TODO re-enable once rendering is totally working boolean cullingDisabled = true; //LodConfig.CLIENT.graphics.advancedGraphicsOption.disableDirectionalCulling.get(); - boolean renderBufferStorage = LodConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported; + boolean renderBufferStorage = ForgeConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get() == GpuUploadMethod.BUFFER_STORAGE && glProxy.bufferStorageSupported; // used to determine what type of fog to render int halfWidth = vbos.length / 2; @@ -463,7 +463,7 @@ public class LodRenderer if (fogQuality == FogQuality.FANCY) { // for more realistic fog when using FAR - if (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get() == FogDistance.NEAR_AND_FAR) + if (ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get() == FogDistance.NEAR_AND_FAR) GL15.glFogf(GL15.GL_FOG_START, farPlaneBlockDistance * 1.6f * 0.9f); else GL15.glFogf(GL15.GL_FOG_START, Math.min(vanillaBlockRenderedDistance * 1.5f, farPlaneBlockDistance * 0.9f * 1.6f)); @@ -518,7 +518,7 @@ public class LodRenderer // disable fog if Minecraft wasn't rendering fog // or we want it disabled if (!fogSettings.vanillaIsRenderingFog - || LodConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.get()) + || ForgeConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.get()) { // Make fog render a infinite distance away. // This doesn't technically disable Minecraft's fog @@ -572,7 +572,7 @@ public class LodRenderer Mat4f lodProj = Mat4f.perspective( getFov(partialTicks, true), (float) this.mc.getWindow().getScreenWidth() / (float) this.mc.getWindow().getScreenHeight(), - LodConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1, + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get() ? vanillaBlockRenderedDistance / 5 : 1, farPlaneBlockDistance * LodUtil.CHUNK_WIDTH / 2); @@ -698,7 +698,7 @@ public class LodRenderer FogQuality quality = ReflectionHandler.INSTANCE.getFogQuality(); - FogDrawOverride override = LodConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.get(); + FogDrawOverride override = ForgeConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.get(); fogSettings.vanillaIsRenderingFog = quality != FogQuality.OFF; @@ -739,7 +739,7 @@ public class LodRenderer fogSettings.near.quality = FogQuality.FANCY; fogSettings.far.quality = FogQuality.FANCY; - switch (LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) + switch (ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { case NEAR_AND_FAR: fogSettings.near.distance = FogDistance.NEAR; @@ -766,7 +766,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.fogQualityOption.fogDistance.get()) + switch (ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { case NEAR_AND_FAR: case NEAR: @@ -801,23 +801,23 @@ public class LodRenderer //=============// // check if the view distance changed - if (ApiShared.previousLodRenderDistance != LodConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() + if (ApiShared.previousLodRenderDistance != ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() || chunkRenderDistance != prevRenderDistance - || prevFogDistance != LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) + || prevFogDistance != ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get()) { vanillaRenderedChunks = new boolean[vanillaRenderedChunksWidth][vanillaRenderedChunksWidth]; DetailDistanceUtil.updateSettings(); fullRegen = true; previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayerChunkPos().getZ(), mc.getPlayerChunkPos().getZ()); - prevFogDistance = LodConfig.CLIENT.graphics.fogQualityOption.fogDistance.get(); + prevFogDistance = ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get(); prevRenderDistance = chunkRenderDistance; } // did the user change the debug setting? - if (LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != previousDebugMode) + if (ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get() != previousDebugMode) { - previousDebugMode = LodConfig.CLIENT.advancedModOptions.debugging.debugMode.get(); + previousDebugMode = ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get(); fullRegen = true; } @@ -825,7 +825,7 @@ public class LodRenderer long newTime = System.currentTimeMillis(); // check if the player has moved - if (newTime - prevPlayerPosTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().playerMoveTimeout) + if (newTime - prevPlayerPosTime > ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().playerMoveTimeout) { if (LevelPosUtil.getDetailLevel(previousPos) == 0 || mc.getPlayerChunkPos().getX() != LevelPosUtil.getPosX(previousPos) @@ -846,7 +846,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.advancedModOptions.buffers.rebuildTimes.get()) + switch (ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get()) { case FREQUENT: minLightingDifference = 0.025f; @@ -885,7 +885,7 @@ public class LodRenderer // check if the vanilla rendered chunks changed - if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().renderedChunkTimeout) + if (newTime - prevVanillaChunkTime > ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().renderedChunkTimeout) { if (vanillaRenderedChunksChanged) { @@ -897,7 +897,7 @@ public class LodRenderer // check if there is any newly generated terrain to show - if (newTime - prevChunkTime > LodConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().chunkChangeTimeout) + if (newTime - prevChunkTime > ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get().chunkChangeTimeout) { if (lodDim.regenDimensionBuffers) { diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java index bdb051bc4..f380806f9 100644 --- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java @@ -19,7 +19,7 @@ package com.seibel.lod.util; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.enums.config.DistanceGenerationMode; import com.seibel.lod.enums.config.HorizontalQuality; import com.seibel.lod.enums.config.HorizontalResolution; @@ -35,12 +35,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 byte minGenDetail = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; - private static byte minDrawDetail = (byte) Math.max(LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel, LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel); + private static byte minGenDetail = ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; + private static byte minDrawDetail = (byte) Math.max(ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel, ForgeConfig.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.qualityOption.lodChunkRenderDistance.get() * 16 * 2; + private static int maxDistance = ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 16 * 2; private static final HorizontalResolution[] lodGenDetails = { @@ -61,9 +61,9 @@ public class DetailDistanceUtil public static void updateSettings() { minDetailDistance = (int) (MinecraftWrapper.INSTANCE.getRenderDistance()*16 * 1.42f); - minGenDetail = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; - minDrawDetail = (byte) 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; + minGenDetail = ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel; + minDrawDetail = (byte) Math.max(ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel, ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get().detailLevel); + maxDistance = ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get() * 16 * 8; } public static int baseDistanceFunction(int detail) @@ -73,15 +73,15 @@ public class DetailDistanceUtil if (detail >= maxDetail) return maxDistance; - if (LodConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.get()) + if (ForgeConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.get()) return detail * 0x10000; //if you want more you are doing wrong - int distanceUnit = LodConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; - if (LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) + int distanceUnit = ForgeConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; + if (ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) return (detail * distanceUnit); else { - double base = LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; + double base = ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; return (int) (Math.pow(base, detail) * distanceUnit); } } @@ -96,14 +96,14 @@ public class DetailDistanceUtil int detail; if (distance == 0 || (distance < minDetailDistance && useRenderMinDistance) - || LodConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.get()) + || ForgeConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.get()) return minDetail; - int distanceUnit = LodConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; - if (LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) + int distanceUnit = ForgeConfig.CLIENT.graphics.qualityOption.horizontalScale.get().distanceUnit; + if (ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.get() == HorizontalQuality.LOWEST) detail = (byte) distance / distanceUnit; else { - double base = LodConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; + double base = ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.get().quadraticBase; double logBase = Math.log(base); //noinspection IntegerDivisionInFloatingPointContext detail = (byte) (Math.log(distance / distanceUnit) / logBase); @@ -133,7 +133,7 @@ public class DetailDistanceUtil public static DistanceGenerationMode getDistanceGenerationMode(int detail) { - return LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); + return ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); } public static byte getLodDrawDetail(int detail) @@ -165,7 +165,7 @@ public class DetailDistanceUtil public static int getMaxVerticalData(int detail) { - return LodConfig.CLIENT.graphics.qualityOption.verticalQuality.get().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)]; + return ForgeConfig.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 14b8f3332..0c8513712 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -23,7 +23,7 @@ import java.awt.Color; import java.io.File; import java.util.HashSet; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.enums.LodDirection; import com.seibel.lod.enums.config.HorizontalResolution; import com.seibel.lod.enums.config.VanillaOverdraw; @@ -352,8 +352,8 @@ public class LodUtil ChunkPosWrapper centerChunk = new ChunkPosWrapper(blockPosWrapper); int skipRadius; - VanillaOverdraw overdraw = LodConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get(); - HorizontalResolution drawRes = LodConfig.CLIENT.graphics.qualityOption.drawResolution.get(); + VanillaOverdraw overdraw = ForgeConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get(); + HorizontalResolution drawRes = ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get(); // apply distance based rules for dynamic overdraw if (overdraw == VanillaOverdraw.DYNAMIC diff --git a/src/main/java/com/seibel/lod/wrappers/config/LodConfigWrapper.java b/src/main/java/com/seibel/lod/wrappers/config/LodConfigWrapper.java new file mode 100644 index 000000000..774ece8c3 --- /dev/null +++ b/src/main/java/com/seibel/lod/wrappers/config/LodConfigWrapper.java @@ -0,0 +1,383 @@ +package com.seibel.lod.wrappers.config; + +import com.seibel.lod.api.forge.ForgeConfig; +import com.seibel.lod.enums.config.BlockToAvoid; +import com.seibel.lod.enums.config.BufferRebuildTimes; +import com.seibel.lod.enums.config.DistanceGenerationMode; +import com.seibel.lod.enums.config.GenerationPriority; +import com.seibel.lod.enums.config.GpuUploadMethod; +import com.seibel.lod.enums.config.HorizontalQuality; +import com.seibel.lod.enums.config.HorizontalResolution; +import com.seibel.lod.enums.config.HorizontalScale; +import com.seibel.lod.enums.config.LodTemplate; +import com.seibel.lod.enums.config.VanillaOverdraw; +import com.seibel.lod.enums.config.VerticalQuality; +import com.seibel.lod.enums.rendering.DebugMode; +import com.seibel.lod.enums.rendering.FogDistance; +import com.seibel.lod.enums.rendering.FogDrawOverride; + +/** + * This holds the config defaults and setters/getters + * that should be hooked into the host mod loader (Fabric, Forge, etc.). + * + * @author James Seibel + * @version 11-14-2021 + */ +public class LodConfigWrapper +{ + public static final Client CLIENT = new Client(); + + + public static class Client + { + public final Graphics graphics; + public final WorldGenerator worldGenerator; + public final AdvancedModOptions advancedModOptions; + + + //================// + // Client Configs // + //================// + public Client() + { + graphics = new Graphics(); + worldGenerator = new WorldGenerator(); + advancedModOptions = new AdvancedModOptions(); + } + + + //==================// + // Graphics Configs // + //==================// + public static class Graphics + { + + public final QualityOption qualityOption; + public final FogQualityOption fogQualityOption; + public final AdvancedGraphicsOption advancedGraphicsOption; + + Graphics() + { + qualityOption = new QualityOption(); + advancedGraphicsOption = new AdvancedGraphicsOption(); + fogQualityOption = new FogQualityOption(); + } + + + public static class QualityOption + { + + public HorizontalResolution getDrawResolution() + { + return ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.get(); + } + public void setDrawResolution(HorizontalResolution newHorizontalResolution) + { + ForgeConfig.CLIENT.graphics.qualityOption.drawResolution.set(newHorizontalResolution); + } + + + + public int getLodChunkRenderDistance() + { + return ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.get(); + } + public void setLodChunkRenderDistance(int newLodChunkRenderDistance) + { + ForgeConfig.CLIENT.graphics.qualityOption.lodChunkRenderDistance.set(newLodChunkRenderDistance); + } + + + + public VerticalQuality getVerticalQuality() + { + return ForgeConfig.CLIENT.graphics.qualityOption.verticalQuality.get(); + } + public void setVerticalQuality(VerticalQuality newVerticalQuality) + { + ForgeConfig.CLIENT.graphics.qualityOption.verticalQuality.set(newVerticalQuality); + } + + + + public HorizontalScale getHorizontalScale() + { + return ForgeConfig.CLIENT.graphics.qualityOption.horizontalScale.get(); + } + public void setHorizontalScale(HorizontalScale newHorizontalScale) + { + ForgeConfig.CLIENT.graphics.qualityOption.horizontalScale.set(newHorizontalScale); + } + + + + public HorizontalQuality getHorizontalQuality() + { + return ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.get(); + } + public void setHorizontalQuality(HorizontalQuality newHorizontalQuality) + { + ForgeConfig.CLIENT.graphics.qualityOption.horizontalQuality.set(newHorizontalQuality); + } + } + + + public static class FogQualityOption + { + + public FogDistance getFogDistance() + { + return ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.get(); + } + public void setFogDistance(FogDistance newFogDistance) + { + ForgeConfig.CLIENT.graphics.fogQualityOption.fogDistance.set(newFogDistance); + } + + + + public FogDrawOverride getFogDrawOverride() + { + return ForgeConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.get(); + } + public void setFogDrawOverride(FogDrawOverride newFogDrawOverride) + { + ForgeConfig.CLIENT.graphics.fogQualityOption.fogDrawOverride.set(newFogDrawOverride); + } + + + + public boolean getDisableVanillaFog() + { + return ForgeConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.get(); + } + public void setDisableVanillaFog(boolean newDisableVanillaFog) + { + ForgeConfig.CLIENT.graphics.fogQualityOption.disableVanillaFog.set(newDisableVanillaFog); + } + } + + + public static class AdvancedGraphicsOption + { + + public LodTemplate getLodTemplate() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.get(); + } + public void setLodTemplate(LodTemplate newLodTemplate) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.lodTemplate.set(newLodTemplate); + } + + + + public boolean getDisableDirectionalCulling() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.disableDirectionalCulling.get(); + } + public void setDisableDirectionalCulling(boolean newDisableDirectionalCulling) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.disableDirectionalCulling.set(newDisableDirectionalCulling); + } + + + + public boolean getAlwaysDrawAtMaxQuality() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.get(); + } + public void setAlwaysDrawAtMaxQuality(boolean newAlwaysDrawAtMaxQuality) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.alwaysDrawAtMaxQuality.set(newAlwaysDrawAtMaxQuality); + } + + + + public VanillaOverdraw getVanillaOverdraw() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.get(); + } + public void setVanillaOverdraw(VanillaOverdraw newVanillaOverdraw) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.vanillaOverdraw.set(newVanillaOverdraw); + } + + + + public GpuUploadMethod getGpuUploadMethod() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.get(); + } + public void setGpuUploadMethod(GpuUploadMethod newDisableVanillaFog) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.gpuUploadMethod.set(newDisableVanillaFog); + } + + + + public boolean getUseExtendedNearClipPlane() + { + return ForgeConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.get(); + } + public void setUseExtendedNearClipPlane(boolean newUseExtendedNearClipPlane) + { + ForgeConfig.CLIENT.graphics.advancedGraphicsOption.useExtendedNearClipPlane.set(newUseExtendedNearClipPlane); + } + } + } + + + + + //========================// + // WorldGenerator Configs // + //========================// + public static class WorldGenerator + { + + public GenerationPriority getGenerationPriority() + { + return ForgeConfig.CLIENT.worldGenerator.generationPriority.get(); + } + public void setGenerationPriority(GenerationPriority newGenerationPriority) + { + ForgeConfig.CLIENT.worldGenerator.generationPriority.set(newGenerationPriority); + } + + + + public DistanceGenerationMode getDistanceGenerationMode() + { + return ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); + } + public void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode) + { + ForgeConfig.CLIENT.worldGenerator.distanceGenerationMode.set(newDistanceGenerationMode); + } + + + + public boolean getAllowUnstableFeatureGeneration() + { + return ForgeConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.get(); + } + public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration) + { + ForgeConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.set(newAllowUnstableFeatureGeneration); + } + + + + public BlockToAvoid getBlockToAvoid() + { + return ForgeConfig.CLIENT.worldGenerator.blockToAvoid.get(); + } + public void setBlockToAvoid(BlockToAvoid newBlockToAvoid) + { + ForgeConfig.CLIENT.worldGenerator.blockToAvoid.set(newBlockToAvoid); + } + } + + + + + //============================// + // AdvancedModOptions Configs // + //============================// + public static class AdvancedModOptions + { + + public final Threading threading; + public final Debugging debugging; + public final Buffers buffers; + + public AdvancedModOptions() + { + threading = new Threading(); + debugging = new Debugging(); + buffers = new Buffers(); + } + + public static class Threading + { + + public int getNumberOfWorldGenerationThreads() + { + return ForgeConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.get(); + } + public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads) + { + ForgeConfig.CLIENT.advancedModOptions.threading.numberOfWorldGenerationThreads.set(newNumberOfWorldGenerationThreads); + } + + + + public int getNumberOfBufferBuilderThreads() + { + return ForgeConfig.CLIENT.advancedModOptions.threading.numberOfBufferBuilderThreads.get(); + } + public void setNumberOfBufferBuilderThreads(int newNumberOfWorldBuilderThreads) + { + ForgeConfig.CLIENT.advancedModOptions.threading.numberOfBufferBuilderThreads.set(newNumberOfWorldBuilderThreads); + } + } + + + + + //===============// + // Debug Options // + //===============// + public static class Debugging + { + + public boolean getDrawLods() + { + return ForgeConfig.CLIENT.advancedModOptions.debugging.drawLods.get(); + } + public void setDrawLods(boolean newDrawLods) + { + ForgeConfig.CLIENT.advancedModOptions.debugging.drawLods.set(newDrawLods); + } + + + + public DebugMode getDebugMode() + { + return ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.get(); + } + public void setDebugMode(DebugMode newDebugMode) + { + ForgeConfig.CLIENT.advancedModOptions.debugging.debugMode.set(newDebugMode); + } + + + + public boolean getEnableDebugKeybindings() + { + return ForgeConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.get(); + } + public void setEnableDebugKeybindings(boolean newEnableDebugKeybindings) + { + ForgeConfig.CLIENT.advancedModOptions.debugging.enableDebugKeybindings.set(newEnableDebugKeybindings); + } + } + + + public static class Buffers + { + + public BufferRebuildTimes getRebuildTimes() + { + return ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.get(); + } + public void setRebuildTimes(BufferRebuildTimes newBufferRebuildTimes) + { + ForgeConfig.CLIENT.advancedModOptions.buffers.rebuildTimes.set(newBufferRebuildTimes); + } + } + } + } + +} diff --git a/src/main/java/com/seibel/lod/wrappers/worldGeneration/WorldGeneratorWrapper.java b/src/main/java/com/seibel/lod/wrappers/worldGeneration/WorldGeneratorWrapper.java index 5e19a5afb..fe7ae9cbc 100644 --- a/src/main/java/com/seibel/lod/wrappers/worldGeneration/WorldGeneratorWrapper.java +++ b/src/main/java/com/seibel/lod/wrappers/worldGeneration/WorldGeneratorWrapper.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -import com.seibel.lod.api.forge.LodConfig; +import com.seibel.lod.api.forge.ForgeConfig; import com.seibel.lod.builders.lodBuilding.LodBuilder; import com.seibel.lod.builders.lodBuilding.LodBuilderConfig; import com.seibel.lod.enums.config.DistanceGenerationMode; @@ -267,7 +267,7 @@ public class WorldGeneratorWrapper } } - boolean allowUnstableFeatures = LodConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.get(); + boolean allowUnstableFeatures = ForgeConfig.CLIENT.worldGenerator.allowUnstableFeatureGeneration.get(); // generate all the features related to this chunk. // this may or may not be thread safe