From 1ff4a56e2d8848a364276c1a035c824d3ee526e8 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 7 Apr 2024 21:42:31 -0500 Subject: [PATCH] Improve grass side rendering and add a config --- .../config/EDhApiGrassSideRendering.java | 40 +++++++++++++++++ .../distanthorizons/core/config/Config.java | 11 +++++ .../RenderCacheConfigEventHandler.java | 12 +++-- .../render/bufferBuilding/ColumnBox.java | 19 +++----- .../bufferBuilding/CubicLodTemplate.java | 4 +- .../render/bufferBuilding/LodQuadBuilder.java | 45 ++++++++++++++----- .../distanthorizons/core/util/ColorUtil.java | 2 +- .../assets/distanthorizons/lang/en_us.json | 14 +++++- 8 files changed, 116 insertions(+), 31 deletions(-) create mode 100644 api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiGrassSideRendering.java diff --git a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiGrassSideRendering.java b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiGrassSideRendering.java new file mode 100644 index 000000000..2f2f1a8fa --- /dev/null +++ b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiGrassSideRendering.java @@ -0,0 +1,40 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL v3 License. + * + * Copyright (C) 2020-2023 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.seibel.distanthorizons.api.enums.config; + +/** + * AS_GRASS
+ * FADE_TO_DIRT
+ * AS_DIRT
+ * + * @since API 1.1.0 + * @version 2024-4-7 + */ +public enum EDhApiGrassSideRendering +{ + // Reminder: + // when adding items up the API minor version + // when removing items up the API major version + + AS_GRASS, + FADE_TO_DIRT, + AS_DIRT; + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index ec19ad4f0..391aefa2d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -645,6 +645,17 @@ public class Config + "Disable this if shadows render incorrectly.") .build(); + public static ConfigEntry grassSideRendering = new ConfigEntry.Builder() + .set(EDhApiGrassSideRendering.AS_DIRT) + .comment("" + + "How should the sides and bottom of grass block LODs render? \n" + + "\n" + + EDhApiGrassSideRendering.AS_GRASS + ": all sides of dirt LOD's render using the top (green) color. \n" + + EDhApiGrassSideRendering.FADE_TO_DIRT + ": sides fade from grass to dirt. \n" + + EDhApiGrassSideRendering.AS_DIRT + ": sides render entirely as dirt. \n" + + "") + .setPerformance(EConfigEntryPerformance.NONE) + .build(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderCacheConfigEventHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderCacheConfigEventHandler.java index 6e3901462..24b613e9b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderCacheConfigEventHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/RenderCacheConfigEventHandler.java @@ -20,10 +20,8 @@ package com.seibel.distanthorizons.core.config.eventHandlers; import com.seibel.distanthorizons.api.DhApi; -import com.seibel.distanthorizons.api.enums.config.EDhApiBlocksToAvoid; -import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading; -import com.seibel.distanthorizons.api.enums.config.EDhApiMaxHorizontalResolution; -import com.seibel.distanthorizons.api.enums.config.EDhApiVerticalQuality; +import com.seibel.distanthorizons.api.enums.config.*; +import com.seibel.distanthorizons.api.enums.rendering.EDhApiDebugRendering; import com.seibel.distanthorizons.api.enums.rendering.EDhApiTransparency; import com.seibel.distanthorizons.core.config.listeners.ConfigChangeListener; import com.seibel.distanthorizons.core.config.Config; @@ -53,6 +51,9 @@ public class RenderCacheConfigEventHandler private final ConfigChangeListener brightnessMultiplierChangeListener; private final ConfigChangeListener saturationMultiplierChangeListener; private final ConfigChangeListener lodShadingChangeListener; + private final ConfigChangeListener grassSideChangeListener; + + private final ConfigChangeListener debugRenderingChangeListener; /** how long to wait in milliseconds before applying the config changes */ private static final long TIMEOUT_IN_MS = 4_000L; @@ -82,6 +83,9 @@ public class RenderCacheConfigEventHandler this.brightnessMultiplierChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.AdvancedGraphics.brightnessMultiplier, (newValue) -> this.refreshRenderDataAfterTimeout()); this.saturationMultiplierChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.AdvancedGraphics.saturationMultiplier, (newValue) -> this.refreshRenderDataAfterTimeout()); this.lodShadingChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading, (newValue) -> this.refreshRenderDataAfterTimeout()); + this.grassSideChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.AdvancedGraphics.grassSideRendering, (newValue) -> this.refreshRenderDataAfterTimeout()); + + this.debugRenderingChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Debugging.debugRendering, (newValue) -> this.refreshRenderDataAfterTimeout()); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java index 8d52addd6..edf2a4c67 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java @@ -61,23 +61,16 @@ public class ColumnBox color = ColorUtil.setAlpha(color, 255); } - // try to prevent displaying grass gradients for dirt blocks underneath solid blocks - if (!isTopTransparent && irisBlockMaterialId == IBlockStateWrapper.IrisBlockMaterial.GRASS) - { - irisBlockMaterialId = IBlockStateWrapper.IrisBlockMaterial.DIRT; - } - // cave culling prevention // prevents certain faces from being culled underground that should be allowed if (builder.skipQuadsWithZeroSkylight - && 0 == skyLight - && builder.skyLightCullingBelow > maxY - && - ( - (RenderDataPointUtil.getAlpha(topData) < 255 && RenderDataPointUtil.getYMax(topData) >= builder.skyLightCullingBelow) - || (RenderDataPointUtil.getYMin(topData) >= builder.skyLightCullingBelow) - || !RenderDataPointUtil.doesDataPointExist(topData) + && 0 == skyLight + && builder.skyLightCullingBelow > maxY + && ( + (RenderDataPointUtil.getAlpha(topData) < 255 && RenderDataPointUtil.getYMax(topData) >= builder.skyLightCullingBelow) + || (RenderDataPointUtil.getYMin(topData) >= builder.skyLightCullingBelow) + || !RenderDataPointUtil.doesDataPointExist(topData) ) ) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java index 45d107c99..87b2e7720 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/CubicLodTemplate.java @@ -103,7 +103,7 @@ public class CubicLodTemplate break; case IBlockStateWrapper.IrisBlockMaterial.LEAVES: - color = ColorUtil.GREEN; + color = ColorUtil.DARK_GREEN; break; case IBlockStateWrapper.IrisBlockMaterial.STONE: color = ColorUtil.GRAY; @@ -139,7 +139,7 @@ public class CubicLodTemplate color = ColorUtil.BLUE; break; case IBlockStateWrapper.IrisBlockMaterial.GRASS: - color = ColorUtil.LIGHT_GREEN; + color = ColorUtil.GREEN; break; case IBlockStateWrapper.IrisBlockMaterial.ILLUMINATED: color = ColorUtil.YELLOW; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java index dabcea970..07744dcb9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java @@ -23,6 +23,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.*; +import com.seibel.distanthorizons.api.enums.config.EDhApiGrassSideRendering; +import com.seibel.distanthorizons.api.enums.rendering.EDhApiDebugRendering; +import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; @@ -58,6 +61,8 @@ public class LodQuadBuilder private final boolean doTransparency; private final IClientLevelWrapper clientLevelWrapper; + private final EDhApiDebugRendering debugRenderingMode; + private final EDhApiGrassSideRendering grassSideRenderingMode; public static final int[][][] DIRECTION_VERTEX_IBO_QUAD = new int[][][] @@ -130,6 +135,9 @@ public class LodQuadBuilder this.skyLightCullingBelow = skyLightCullingBelow; this.clientLevelWrapper = clientLevelWrapper; + this.debugRenderingMode = Config.Client.Advanced.Debugging.debugRendering.get(); + this.grassSideRenderingMode = Config.Client.Advanced.Graphics.AdvancedGraphics.grassSideRendering.get(); + } @@ -263,19 +271,36 @@ public class LodQuadBuilder int color = quad.color; - if (quad.irisBlockMaterialId == IBlockStateWrapper.IrisBlockMaterial.GRASS - && - ( - (quad.direction.getAxis().isHorizontal() && quadBase[i][1] == 0) // TODO what does "quadBase[i][1] == 0" mean? - || quad.direction == EDhDirection.DOWN) - ) + + // use custom side color logic for grass blocks + if (quad.irisBlockMaterialId == IBlockStateWrapper.IrisBlockMaterial.GRASS) { - // for horizontal and bottom faces of grass blocks, use the dirt color to - // prevent green cliff walls - color = this.clientLevelWrapper.getDirtBlockColor(); - color = ColorUtil.applyShade(color, MC.getShade(quad.direction)); + // only use dirt colors if debug rendering is disabled + if (this.debugRenderingMode == EDhApiDebugRendering.OFF) + { + // determine if any custom coloring logic should be used + if (this.grassSideRenderingMode != EDhApiGrassSideRendering.AS_GRASS) + { + // only change the vertex color if it's on the side or bottom + if (quad.direction.getAxis().isHorizontal() || quad.direction == EDhDirection.DOWN) + { + if (this.grassSideRenderingMode == EDhApiGrassSideRendering.AS_DIRT + // if we want the color to fade, only apply the dirt color to the bottom vertices + || (this.grassSideRenderingMode == EDhApiGrassSideRendering.FADE_TO_DIRT && quadBase[i][1] == 0) + // always render the bottom as dirt + || quad.direction == EDhDirection.DOWN) + { + // for horizontal and bottom faces of grass blocks, use the dirt color to + // prevent green cliff walls + color = this.clientLevelWrapper.getDirtBlockColor(); + color = ColorUtil.applyShade(color, MC.getShade(quad.direction)); + } + } + } + } } + this.putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz), quad.hasError ? ColorUtil.RED : color, quad.hasError ? 0 : normalIndex, diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/ColorUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/ColorUtil.java index c0ffb7554..222fcbb9b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/ColorUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/ColorUtil.java @@ -41,7 +41,7 @@ public class ColorUtil public static final int RED = rgbToInt(255, 0, 0); public static final int DARK_RED = rgbToInt(100, 0, 0); public static final int GREEN = rgbToInt(0, 255, 0); - public static final int LIGHT_GREEN = rgbToInt(80, 255, 80); + public static final int DARK_GREEN = rgbToInt(80, 140, 80); public static final int BLUE = rgbToInt(0, 0, 255); public static final int YELLOW = rgbToInt(255, 255, 0); public static final int CYAN = rgbToInt(0, 255, 255); diff --git a/core/src/main/resources/assets/distanthorizons/lang/en_us.json b/core/src/main/resources/assets/distanthorizons/lang/en_us.json index d8f6bdc19..d88fb35c3 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -305,6 +305,10 @@ "Disable Shadow Pass Frustum Culling", "distanthorizons.config.client.advanced.graphics.advancedGraphics.disableShadowPassFrustumCulling.@tooltip": "Identical to the other frustum culling option except that it is \nonly used when a shader mod is present using the DH API \nand the shadow pass is being rendered. \n\nDisable this if shadows render incorrectly.", + "distanthorizons.config.client.advanced.graphics.advancedGraphics.grassSideRendering": + "Grass Side Rendering", + "distanthorizons.config.client.advanced.graphics.advancedGraphics.grassSideRendering.@tooltip": + "How should the sides and bottom of grass block LODs render?", "distanthorizons.config.client.advanced.worldGenerator": @@ -913,5 +917,13 @@ "distanthorizons.config.enum.EDhApiUpdateBranch.STABLE": "Stable", "distanthorizons.config.enum.EDhApiUpdateBranch.NIGHTLY": - "Nightly" + "Nightly", + + "distanthorizons.config.enum.EDhApiGrassSideRendering.AS_GRASS": + "As Grass", + "distanthorizons.config.enum.EDhApiGrassSideRendering.FADE_TO_DIRT": + "Fade To Dirt", + "distanthorizons.config.enum.EDhApiGrassSideRendering.AS_DIRT": + "As Dirt" + }