From da413f594e2cbb64eab85099145030199302cab9 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 22 Sep 2021 17:17:17 +0200 Subject: [PATCH] Added different detail drop off option --- .../java/com/seibel/lod/config/LodConfig.java | 25 +++++++------- .../com/seibel/lod/enums/DetailDropOff.java | 28 +++++++++++++++ .../com/seibel/lod/objects/LodRegion.java | 28 +++++++++++++-- .../com/seibel/lod/render/LodRenderer.java | 34 ++++++++----------- 4 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/seibel/lod/enums/DetailDropOff.java diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index 89469c917..cbebe2040 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -20,23 +20,13 @@ package com.seibel.lod.config; import java.nio.file.Path; import java.nio.file.Paths; +import com.seibel.lod.enums.*; 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.DebugMode; -import com.seibel.lod.enums.DistanceGenerationMode; -import com.seibel.lod.enums.DistanceQualityDropOff; -import com.seibel.lod.enums.FogDistance; -import com.seibel.lod.enums.FogDrawOverride; -import com.seibel.lod.enums.GenerationPriority; -import com.seibel.lod.enums.HorizontalQuality; -import com.seibel.lod.enums.HorizontalResolution; -import com.seibel.lod.enums.LodTemplate; -import com.seibel.lod.enums.ShadingMode; -import com.seibel.lod.enums.VerticalQuality; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -90,10 +80,13 @@ public class LodConfig public ForgeConfigSpec.EnumValue shadingMode; public ForgeConfigSpec.EnumValue horizontalQuality; + + public ForgeConfigSpec.EnumValue detailDropOff; public ForgeConfigSpec.IntValue lodChunkRenderDistance; public ForgeConfigSpec.BooleanValue disableDirectionalCulling; + Graphics(ForgeConfigSpec.Builder builder) { @@ -125,7 +118,15 @@ public class LodConfig + " " + LodTemplate.DYNAMIC + ": LOD Chunks smoothly transition between other, \n" + " " + " unless a neighboring chunk is at a significantly different height. \n") .defineEnum("lodTemplate", LodTemplate.CUBIC); - + + detailDropOff = builder + .comment("\n\n" + + " how the detail should go dropoff? \n" + + DetailDropOff.BY_BLOCK + " in chunks circles around the player (best quality option, may cause stuttering)\n" + + DetailDropOff.BY_REGION_FANCY + " in regions circles around the player (quality option)\n" + + DetailDropOff.BY_REGION_FAST + " in regions circles around the player (performance option)\n") + .defineEnum("detailDropOff", DetailDropOff.BY_REGION_FAST); + drawResolution = builder .comment("\n\n" + " What is the maximum detail level that LODs should be drawn at? \n" diff --git a/src/main/java/com/seibel/lod/enums/DetailDropOff.java b/src/main/java/com/seibel/lod/enums/DetailDropOff.java new file mode 100644 index 000000000..c887bb75a --- /dev/null +++ b/src/main/java/com/seibel/lod/enums/DetailDropOff.java @@ -0,0 +1,28 @@ +/* + * This file is part of the LOD Mod, licensed under the GNU GPL v3 License. + * + * Copyright (C) 2020 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.seibel.lod.enums; + +/** + * + */ +public enum DetailDropOff +{ + BY_REGION_FAST, + BY_REGION_FANCY, + BY_BLOCK, +} diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 0145b9c9b..66132de67 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -1,10 +1,10 @@ package com.seibel.lod.objects; +import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodTemplate; import com.seibel.lod.enums.VerticalQuality; -import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.DetailDistanceUtil; import com.seibel.lod.util.LevelPosUtil; @@ -229,9 +229,31 @@ public class LodRegion //here i calculate the the LevelPos is in range //This is important to avoid any kind of hole in the rendering - int maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + byte supposedLevel; + int maxDistance; + switch (LodConfig.CLIENT.graphics.detailDropOff.get()) + { + default: + case BY_BLOCK: + maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); + break; + case BY_REGION_FANCY: + supposedLevel = minDetailLevel; + break; + case BY_REGION_FAST: + int playerRegionX = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL,playerPosX); + int playerRegionZ = LevelPosUtil.getRegion(LodUtil.BLOCK_DETAIL_LEVEL,playerPosZ); + if(playerRegionX == regionPosX && playerRegionZ == regionPosZ) + supposedLevel = minDetailLevel; + else + { + maxDistance = LevelPosUtil.maxDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerRegionX*512 + 256, playerRegionZ*512 + 256); + supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); + } + break; + } - byte supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); if (supposedLevel > detailLevel) return; else if (supposedLevel == detailLevel) diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index a7e353cbb..8db445ffe 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -17,12 +17,9 @@ */ package com.seibel.lod.render; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; import java.util.HashSet; -import java.util.Iterator; +import com.seibel.lod.enums.*; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL15C; @@ -34,10 +31,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.seibel.lod.builders.LodBufferBuilder; import com.seibel.lod.builders.LodBufferBuilder.VertexBuffersAndOffset; import com.seibel.lod.config.LodConfig; -import com.seibel.lod.enums.DebugMode; -import com.seibel.lod.enums.FogDistance; -import com.seibel.lod.enums.FogDrawOverride; -import com.seibel.lod.enums.FogQuality; import com.seibel.lod.handlers.ReflectionHandler; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.NearFarFogSettings; @@ -56,8 +49,6 @@ import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.VertexBuffer; import net.minecraft.client.renderer.vertex.VertexFormat; -import net.minecraft.potion.EffectInstance; -import net.minecraft.potion.Effects; import net.minecraft.profiler.IProfiler; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; @@ -796,19 +787,22 @@ public class LodRenderer long newTime = System.currentTimeMillis(); - // check if the player has moved - if (newTime - prevPlayerPosTime > LodConfig.CLIENT.buffers.bufferRebuildPlayerMoveTimeout.get()) + if(LodConfig.CLIENT.graphics.detailDropOff.get() == DetailDropOff.BY_BLOCK) { - if (LevelPosUtil.getDetailLevel(previousPos) == 0 - || mc.getPlayer().xChunk != LevelPosUtil.getPosX(previousPos) - || mc.getPlayer().zChunk != LevelPosUtil.getPosZ(previousPos)) + // check if the player has moved + if (newTime - prevPlayerPosTime > LodConfig.CLIENT.buffers.bufferRebuildPlayerMoveTimeout.get()) { - fullRegen = true; - previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk); - //should use this when it's ready - vanillaRenderedChunks = new boolean[chunkRenderDistance*2+2][chunkRenderDistance*2+2]; + if (LevelPosUtil.getDetailLevel(previousPos) == 0 + || mc.getPlayer().xChunk != LevelPosUtil.getPosX(previousPos) + || mc.getPlayer().zChunk != LevelPosUtil.getPosZ(previousPos)) + { + fullRegen = true; + previousPos = LevelPosUtil.createLevelPos((byte) 4, mc.getPlayer().xChunk, mc.getPlayer().zChunk); + //should use this when it's ready + vanillaRenderedChunks = new boolean[chunkRenderDistance * 2 + 2][chunkRenderDistance * 2 + 2]; + } + prevPlayerPosTime = newTime; } - prevPlayerPosTime = newTime; }