From 1b2992f1dcb6d0588f6c3d189b36e5aad37022cc Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 23 Feb 2026 12:31:21 -0600 Subject: [PATCH 01/46] proof-of-concept test renderer --- .../core/api/internal/ClientApi.java | 14 +++- .../core/render/glObject/GLProxy.java | 8 +- .../core/render/renderer/LodRenderer.java | 83 ++++++++++--------- .../render/IMcTestRenderer.java | 29 +++++++ .../assets/distanthorizons/shaders/frag.fsh | 10 +++ .../assets/distanthorizons/shaders/vert.vsh | 13 +++ 6 files changed, 114 insertions(+), 43 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/vert.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 96de8af7f..9c3eb066e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -38,6 +38,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; @@ -485,6 +486,13 @@ public class ClientApi ///endregion + IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); + if (testRenderer == null) + { + return; + } + + //=================// @@ -577,7 +585,9 @@ public class ClientApi boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); if (!renderingCancelled) { - LodRenderer.INSTANCE.render(renderParams, profiler); + testRenderer.render(); + + //LodRenderer.INSTANCE.render(renderParams, profiler); } if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) @@ -590,7 +600,7 @@ public class ClientApi boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams); if (!renderingCancelled) { - LodRenderer.INSTANCE.renderDeferred(renderParams, profiler); + //LodRenderer.INSTANCE.renderDeferred(renderParams, profiler); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java index e3740c34d..eb4f6f1ab 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java @@ -50,8 +50,8 @@ import java.util.concurrent.ConcurrentLinkedQueue; */ public class GLProxy { - private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + //private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + //private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); public static final DhLogger LOGGER = new DhLoggerBuilder() .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) @@ -145,6 +145,7 @@ public class GLProxy String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GLProxy.class.getSimpleName() + " and discovered this GPU doesn't meet the OpenGL requirements. Sorry I couldn't tell you sooner :(\n" + "Additional info:\n" + supportedVersionInfo; + IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); MC.crashMinecraft(errorMessage, new UnsupportedOperationException("Distant Horizon OpenGL requirements not met")); } LOGGER.info("minecraftGlCapabilities:\n" + this.versionInfoToString(this.glCapabilities)); @@ -287,6 +288,8 @@ public class GLProxy */ public void runRenderThreadTasks() { + IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + int frameLimit = MC_RENDER.getFrameLimit(); if (frameLimit <= 1) { @@ -336,6 +339,7 @@ public class GLProxy // this means we could have GL jobs building up. // Run the queued tasks on MC's executor (hopefully this should always run, // even if DH's render code isn't being hit). + IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); MC.executeOnRenderThread(() -> this.runRenderThreadTasks(1_000)); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 7b08a6cff..5251e851d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -51,6 +51,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; import com.seibel.distanthorizons.core.util.math.Vec3f; @@ -660,48 +661,52 @@ public class LodRenderer GLMC.enableFaceCulling(); } - if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) - { - // Normal LOD rendering - - SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); - if (lodBufferContainer != null) - { - for (int lodIndex = 0; lodIndex < lodBufferContainer.size(); lodIndex++) - { - LodBufferContainer bufferContainer = lodBufferContainer.get(lodIndex); - this.setShaderProgramMvmOffset(bufferContainer.minCornerBlockPos, shaderProgram, renderEventParam); - - GLVertexBuffer[] vbos = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent; - for (int vboIndex = 0; vboIndex < vbos.length; vboIndex++) - { - GLVertexBuffer vbo = vbos[vboIndex]; - if (vbo == null) - { - continue; - } - - if (vbo.getVertexCount() == 0) - { - continue; - } - - vbo.bind(); - shaderProgram.bindVertexBuffer(vbo.getId()); - GL32.glDrawElements( - GL32.GL_TRIANGLES, - vbo.getVertexCount(), - this.quadIBO.getType(), 0); - vbo.unbind(); - } - } - } - } - else + //if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) + //{ + // // Normal LOD rendering + // + // SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); + // if (lodBufferContainer != null) + // { + // for (int lodIndex = 0; lodIndex < lodBufferContainer.size(); lodIndex++) + // { + // LodBufferContainer bufferContainer = lodBufferContainer.get(lodIndex); + // this.setShaderProgramMvmOffset(bufferContainer.minCornerBlockPos, shaderProgram, renderEventParam); + // + // GLVertexBuffer[] vbos = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent; + // for (int vboIndex = 0; vboIndex < vbos.length; vboIndex++) + // { + // GLVertexBuffer vbo = vbos[vboIndex]; + // if (vbo == null) + // { + // continue; + // } + // + // if (vbo.getVertexCount() == 0) + // { + // continue; + // } + // + // vbo.bind(); + // shaderProgram.bindVertexBuffer(vbo.getId()); + // GL32.glDrawElements( + // GL32.GL_TRIANGLES, + // vbo.getVertexCount(), + // this.quadIBO.getType(), 0); + // vbo.unbind(); + // } + // } + // } + //} + //else { // basic quad rendering - TestRenderer.INSTANCE.render(); + IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); + testRenderer.render(); + + //TestRenderer.INSTANCE.render(); + //McTestRenderer.INSTANCE.render(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java new file mode 100644 index 000000000..fbf101b7a --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java @@ -0,0 +1,29 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcTestRenderer extends IBindable +{ + + void render(); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/frag.fsh new file mode 100644 index 000000000..3fd25f9db --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/frag.fsh @@ -0,0 +1,10 @@ +#version 150 core + +in vec4 fColor; +out vec4 fragColor; + +// DH frag test +void main() +{ + fragColor = fColor; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/vert.vsh new file mode 100644 index 000000000..2887fea56 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/vert.vsh @@ -0,0 +1,13 @@ +#version 150 core + +in vec2 vPosition; +in vec4 vColor; + +out vec4 fColor; + +// DH vert test +void main() +{ + gl_Position = vec4(vPosition, 0.0, 1.0); + fColor = vColor; +} \ No newline at end of file From 87cead607fddddcd5c93770fc81fc4aa6bd3eebc Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 24 Feb 2026 07:02:05 -0600 Subject: [PATCH 02/46] move test shader folder --- .../resources/assets/distanthorizons/shaders/{ => test}/frag.fsh | 0 .../resources/assets/distanthorizons/shaders/{ => test}/vert.vsh | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename core/src/main/resources/assets/distanthorizons/shaders/{ => test}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/{ => test}/vert.vsh (100%) diff --git a/core/src/main/resources/assets/distanthorizons/shaders/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/test/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/test/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/test/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/test/vert.vsh From d1ba402f4d1db1f8cd98ef880984de089429153b Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 24 Feb 2026 09:57:03 -0600 Subject: [PATCH 03/46] start of vanilla fade logic --- .../core/api/internal/ClientApi.java | 71 +++++++++------ .../core/render/renderer/TestRenderer.java | 1 + .../render/IMcFadeRenderer.java | 29 ++++++ .../distanthorizons/shaders/fade/frag.fsh | 24 +++++ .../shaders/fade/vanillaFade.fsh | 91 +++++++++++++++++++ .../distanthorizons/shaders/fade/vert.vsh | 15 +++ .../distanthorizons/shaders/quadApply.vsh | 15 +++ 7 files changed, 216 insertions(+), 30 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 9c3eb066e..0002eaa9b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -38,6 +38,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; @@ -585,7 +586,7 @@ public class ClientApi boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); if (!renderingCancelled) { - testRenderer.render(); + //testRenderer.render(); //LodRenderer.INSTANCE.render(renderParams, profiler); } @@ -644,20 +645,28 @@ public class ClientApi */ public void renderFadeOpaque() { - // only fade when DH is rendering - if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED - && - ( - // only fade when requested - Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() == EDhApiMcRenderingFadeMode.DOUBLE_PASS - // or if LOD-only mode is enabled (fading is used to remove the MC render pass) - || Config.Client.Advanced.Debugging.lodOnlyMode.get() - ) - // don't fade when Iris shaders are active, otherwise the rendering can get weird - && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) + IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + if (fadeRenderer == null) { - VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); + return; } + fadeRenderer.render(); + + + //// only fade when DH is rendering + //if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED + // && + // ( + // // only fade when requested + // Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() == EDhApiMcRenderingFadeMode.DOUBLE_PASS + // // or if LOD-only mode is enabled (fading is used to remove the MC render pass) + // || Config.Client.Advanced.Debugging.lodOnlyMode.get() + // ) + // // don't fade when Iris shaders are active, otherwise the rendering can get weird + // && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) + //{ + // VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); + //} } /** * The second fade pass. @@ -666,23 +675,25 @@ public class ClientApi */ public void renderFadeTransparent() { - // only fade when DH is rendering - if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED) - { - boolean renderFade = - ( - // only fade when requested - Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() != EDhApiMcRenderingFadeMode.NONE - // or if LOD-only mode is enabled (fading is used to remove the MC render pass) - || Config.Client.Advanced.Debugging.lodOnlyMode.get() - ) - // don't fade when Iris shaders are active, otherwise the rendering can get weird - && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); - if (renderFade) - { - VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); - } - } + + + //// only fade when DH is rendering + //if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED) + //{ + // boolean renderFade = + // ( + // // only fade when requested + // Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() != EDhApiMcRenderingFadeMode.NONE + // // or if LOD-only mode is enabled (fading is used to remove the MC render pass) + // || Config.Client.Advanced.Debugging.lodOnlyMode.get() + // ) + // // don't fade when Iris shaders are active, otherwise the rendering can get weird + // && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); + // if (renderFade) + // { + // VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); + // } + //} } ///endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java index 0b55d611e..eadf83958 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java @@ -40,6 +40,7 @@ import java.nio.ByteOrder; * to the center of the screen to confirm DH's * apply shader is running correctly */ +@Deprecated public class TestRenderer { public static final DhLogger LOGGER = new DhLoggerBuilder().build(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java new file mode 100644 index 000000000..4180fc986 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java @@ -0,0 +1,29 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcFadeRenderer extends IBindable +{ + + void render(); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh new file mode 100644 index 000000000..72751ec8f --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh @@ -0,0 +1,24 @@ +#version 150 core + +in vec2 TexCoord; +in vec4 fColor; + +out vec4 fragColor; + +uniform sampler2D uDhDepthTexture; + +// DH fade frag test +void main() +{ + float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; + if (dhFragmentDepth == 0) + { + // no MC depth + fragColor = fColor; + } + else + { + // MC depth drawn + fragColor = vec4(0, 0, 1, 1); // green + } +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh new file mode 100644 index 000000000..da2064fa0 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh @@ -0,0 +1,91 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +// inverted model view matrix and projection matrix +uniform mat4 uDhInvMvmProj; +uniform mat4 uMcInvMvmProj; + +uniform sampler2D uMcDepthTexture; +uniform sampler2D uDhDepthTexture; +uniform sampler2D uCombinedMcDhColorTexture; +uniform sampler2D uDhColorTexture; + +uniform float uStartFadeBlockDistance; +uniform float uEndFadeBlockDistance; +uniform float uMaxLevelHeight; + +uniform bool uOnlyRenderLods; + + + +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) +{ + // normalized device coordinates + vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); + ndc.xyz = ndc.xyz * 2.0 - 1.0; + + vec4 eyeCoord = invMvmProj * ndc; + return eyeCoord.xyz / eyeCoord.w; +} + +/** + * Used to fade out vanilla chunks so the transition + * between DH and vanilla is smoother. + */ +void main() +{ + // includes both the vanilla chunks as well as DH + vec4 combinedMcDhColor = texture(uCombinedMcDhColorTexture, TexCoord); + // just the DH render pass + vec4 dhColor = texture(uDhColorTexture, TexCoord); + + // completely remove the MC render pass to only show LODs + // useful for debugging/troubleshooting, but doesn't improve performance since MC is still rendering + if (uOnlyRenderLods) + { + fragColor = dhColor; + return; + } + + + // ignore anything that DH hasn't drawn to + // We don't use DH's depth here because it would prevent the fade from running before DH has loaded + if (dhColor == vec4(1)) + { + // if not done vanilla clouds will render incorrectly at night + dhColor = combinedMcDhColor; + } + + float mcFragmentDepth = texture(uMcDepthTexture, TexCoord).r; + float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; + vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj); + + // this is a work around to prevent MC clouds rendering behind DH clouds + if (dhVertexWorldPos.y > uMaxLevelHeight) + { + fragColor = vec4(combinedMcDhColor.rgb, 0.0); + } + // a fragment depth of "1" means the fragment wasn't drawn to, + // we only want to fade vanilla rendered objects, not to the sky or LODs + else if (mcFragmentDepth < 1.0) + { + // fade based on distance from the camera + vec3 mcVertexWorldPos = calcViewPosition(mcFragmentDepth, uMcInvMvmProj); + float mcFragmentDistance = length(mcVertexWorldPos.xzy); + + + // Smoothly transition between combinedMcDhColor and uDhColorTexture + // as the depth increases from the camera + float fadeStep = smoothstep(uStartFadeBlockDistance, uEndFadeBlockDistance, mcFragmentDistance); + fragColor = mix(combinedMcDhColor, dhColor, fadeStep); + fragColor.a = 1.0; + } + else + { + fragColor = vec4(combinedMcDhColor.rgb, 0.0); + } +} + diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh new file mode 100644 index 000000000..d7f46cf36 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh @@ -0,0 +1,15 @@ +#version 150 core + +in vec2 vPosition; +in vec4 vColor; + +out vec4 fColor; +out vec2 TexCoord; + +// DH vert fade test +void main() +{ + gl_Position = vec4(vPosition, 0.0, 1.0); + fColor = vec4(vPosition, 0.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh new file mode 100644 index 000000000..3f614c123 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh @@ -0,0 +1,15 @@ +#version 150 core + +in vec2 vPosition; + +out vec2 TexCoord; + +/** + * This is specifically used by application shaders. + * IE post process or pixel transfer shaders, anything that is rendered using a single rectangle. + */ +void main() +{ + gl_Position = vec4(vPosition, 1.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file From 9f483ee07a78dcfb00744f623761efed65c24b9c Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 24 Feb 2026 22:03:43 -0600 Subject: [PATCH 04/46] Fix fade test shader --- .../resources/assets/distanthorizons/shaders/fade/frag.fsh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh index 72751ec8f..cf8963b19 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh @@ -11,14 +11,14 @@ uniform sampler2D uDhDepthTexture; void main() { float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; - if (dhFragmentDepth == 0) + if (dhFragmentDepth == 1) { // no MC depth - fragColor = fColor; + fragColor = fColor; } else { // MC depth drawn - fragColor = vec4(0, 0, 1, 1); // green + fragColor = vec4(1, 1, 1, 1); // white } } \ No newline at end of file From 3e80961d18d3099cb55840fd464090ac4d797c82 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 26 Feb 2026 16:55:54 -0600 Subject: [PATCH 05/46] Rough initial LOD renderering --- .../core/api/internal/ClientApi.java | 16 +- .../bufferBuilding/LodBufferContainer.java | 80 ++-- .../core/render/DhApiRenderProxy.java | 7 +- .../core/render/RenderBufferHandler.java | 4 +- .../glObject/buffer/QuadElementBuffer.java | 2 +- .../core/render/renderer/DebugRenderer.java | 11 +- .../core/render/renderer/DhFadeRenderer.java | 2 +- .../core/render/renderer/McLodRenderer.java | 359 ++++++++++++++++++ .../core/render/renderer/ScreenQuad.java | 14 +- .../render/renderer/VanillaFadeRenderer.java | 2 +- .../generic/GenericObjectRenderer.java | 11 +- .../renderer/shaders/DhApplyShader.java | 14 +- .../render/renderer/shaders/DhFadeShader.java | 6 +- .../renderer/shaders/FogApplyShader.java | 6 +- .../render/renderer/shaders/FogShader.java | 4 +- .../renderer/shaders/SSAOApplyShader.java | 7 +- .../render/renderer/shaders/SSAOShader.java | 7 +- .../renderer/shaders/VanillaFadeShader.java | 6 +- .../wrapperInterfaces/IWrapperFactory.java | 5 + .../render/IMcLodRenderer.java | 43 +++ .../render/IVertexBufferWrapper.java | 35 ++ .../distanthorizons/shaders/lod/frag.fsh | 135 +++++++ .../distanthorizons/shaders/lod/vert.vsh | 87 +++++ core/src/main/resources/shaders/standard.vert | 4 +- 24 files changed, 753 insertions(+), 114 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 0002eaa9b..682f842df 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -20,7 +20,6 @@ package com.seibel.distanthorizons.core.api.internal; import com.seibel.distanthorizons.api.DhApi; -import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode; import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState; @@ -38,7 +37,6 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; @@ -588,7 +586,7 @@ public class ClientApi { //testRenderer.render(); - //LodRenderer.INSTANCE.render(renderParams, profiler); + McLodRenderer.INSTANCE.render(renderParams, profiler); } if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) @@ -645,12 +643,12 @@ public class ClientApi */ public void renderFadeOpaque() { - IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); - if (fadeRenderer == null) - { - return; - } - fadeRenderer.render(); + //IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + //if (fadeRenderer == null) + //{ + // return; + //} + //fadeRenderer.render(); //// only fade when DH is rendering diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index c25ef4158..94e170e8e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -19,15 +19,17 @@ package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.objects.StatsMap; import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; +import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; @@ -58,8 +60,8 @@ public class LodBufferContainer implements AutoCloseable public boolean buffersUploaded = false; - public GLVertexBuffer[] vbos; - public GLVertexBuffer[] vbosTransparent; + public IVertexBufferWrapper[] vbos; + public IVertexBufferWrapper[] vbosTransparent; private final AtomicReference> uploadFutureRef = new AtomicReference<>(null); @@ -73,8 +75,8 @@ public class LodBufferContainer implements AutoCloseable { this.pos = pos; this.minCornerBlockPos = minCornerBlockPos; - this.vbos = new GLVertexBuffer[0]; - this.vbosTransparent = new GLVertexBuffer[0]; + this.vbos = new IVertexBufferWrapper[0]; + this.vbosTransparent = new IVertexBufferWrapper[0]; } @@ -173,14 +175,14 @@ public class LodBufferContainer implements AutoCloseable return future; } - private static GLVertexBuffer[] resizeBuffer(GLVertexBuffer[] vbos, int newSize) + private static IVertexBufferWrapper[] resizeBuffer(IVertexBufferWrapper[] vbos, int newSize) { if (vbos.length == newSize) { return vbos; } - GLVertexBuffer[] newVbos = new GLVertexBuffer[newSize]; + IVertexBufferWrapper[] newVbos = new IVertexBufferWrapper[newSize]; System.arraycopy(vbos, 0, newVbos, 0, Math.min(vbos.length, newSize)); if (newSize < vbos.length) { @@ -195,7 +197,7 @@ public class LodBufferContainer implements AutoCloseable return newVbos; } private static void uploadBuffersDirect( - GLVertexBuffer[] vbos, ArrayList byteBuffers, + IVertexBufferWrapper[] vbos, ArrayList byteBuffers, EDhApiGpuUploadMethod uploadMethod) throws InterruptedException { int vboIndex = 0; @@ -210,18 +212,23 @@ public class LodBufferContainer implements AutoCloseable // get or create the VBO if (vbos[vboIndex] == null) { - vbos[vboIndex] = new GLVertexBuffer(uploadMethod.useBufferStorage); + vbos[vboIndex] = SingletonInjector.INSTANCE.get(IWrapperFactory.class).createVboWrapper(); } - GLVertexBuffer vbo = vbos[vboIndex]; + IVertexBufferWrapper vbo = vbos[vboIndex]; + IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); ByteBuffer buffer = byteBuffers.get(i); int size = buffer.limit() - buffer.position(); + //int vertexCount = size / LodUtil.DH_VERTEX_FORMAT.getByteSize(); + int vertexCount = size / lodRenderer.getVertexSize(); + // 6,1,0 + // java.nio.DirectByteBuffer[pos=0 lim=219840 cap=10485760] + // 13740 try { - vbo.bind(); - vbo.uploadBuffer(buffer, size / LodUtil.DH_VERTEX_FORMAT.getByteSize(), uploadMethod, FULL_SIZED_BUFFER); + vbo.upload(buffer, vertexCount); } catch (Exception e) { @@ -268,30 +275,6 @@ public class LodBufferContainer implements AutoCloseable public boolean uploadInProgress() { return this.uploadFutureRef.get() != null; } - public void debugDumpStats(StatsMap statsMap) - { - statsMap.incStat("RenderBuffers"); - statsMap.incStat("SimpleRenderBuffers"); - for (GLVertexBuffer vertexBuffer : this.vbos) - { - if (vertexBuffer != null) - { - statsMap.incStat("VBOs"); - if (vertexBuffer.getSize() == FULL_SIZED_BUFFER) - { - statsMap.incStat("FullsizedVBOs"); - } - - if (vertexBuffer.getSize() == 0) - { - GLProxy.LOGGER.warn("VBO with size 0"); - } - statsMap.incBytesStat("TotalUsage", vertexBuffer.getSize()); - } - } - } - - //================// @@ -309,21 +292,24 @@ public class LodBufferContainer implements AutoCloseable { this.buffersUploaded = false; - for (GLVertexBuffer buffer : this.vbos) + GLProxy.queueRunningOnRenderThread(() -> { - if (buffer != null) + for (IVertexBufferWrapper buffer : this.vbos) { - buffer.destroyAsync(); + if (buffer != null) + { + buffer.close(); + } } - } - - for (GLVertexBuffer buffer : this.vbosTransparent) - { - if (buffer != null) + + for (IVertexBufferWrapper buffer : this.vbosTransparent) { - buffer.destroyAsync(); + if (buffer != null) + { + buffer.close(); + } } - } + }); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java index 17aa0dddc..67e622952 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java @@ -25,11 +25,10 @@ import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.level.IDhClientLevel; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; /** * Used to interact with Distant Horizons' rendering systems. @@ -86,13 +85,13 @@ public class DhApiRenderProxy implements IDhApiRenderProxy @Override public DhApiResult getDhDepthTextureId() { - int activeTexture = LodRenderer.INSTANCE.getActiveDepthTextureId(); + int activeTexture = McLodRenderer.INSTANCE.getActiveDepthTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's depth texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } @Override public DhApiResult getDhColorTextureId() { - int activeTexture = LodRenderer.INSTANCE.getActiveColorTextureId(); + int activeTexture = McLodRenderer.INSTANCE.getActiveColorTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index 1a739a8ec..05048ee1b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.RenderParams; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -47,7 +47,7 @@ import org.joml.Matrix4fc; import java.util.ArrayList; /** - * This object tells the {@link LodRenderer} what buffers to render + * This object tells the {@link McLodRenderer} what buffers to render */ public class RenderBufferHandler implements AutoCloseable { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java index 52a5c5a87..341920e01 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java @@ -109,7 +109,7 @@ public class QuadElementBuffer extends GLElementBuffer //==========// //region - private static void buildBuffer(int quadCount, ByteBuffer buffer, int type) + public static void buildBuffer(int quadCount, ByteBuffer buffer, int type) { switch (type) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java index 0df411af5..10f1e8b42 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java @@ -27,7 +27,6 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; @@ -67,7 +66,7 @@ public class DebugRenderer // rendering setup private ShaderProgram basicShader; - private GLVertexBuffer vertexBuffer; + //private GLVertexBuffer vertexBuffer; private GLElementBuffer outlineIndexBuffer; private AbstractVertexAttribute va; private boolean init = false; @@ -153,9 +152,9 @@ public class DebugRenderer boxVerticesBuffer.order(ByteOrder.nativeOrder()); boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); boxVerticesBuffer.rewind(); - this.vertexBuffer = new GLVertexBuffer(false); - this.vertexBuffer.bind(); - this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); + //this.vertexBuffer = new GLVertexBuffer(false); + //this.vertexBuffer.bind(); + //this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); // outline vertex indexes @@ -215,7 +214,7 @@ public class DebugRenderer this.basicShader.bind(); this.va.bind(); - this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId()); + //this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId()); this.outlineIndexBuffer.bind(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java index ad0d1d298..2017e0a7b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java @@ -146,7 +146,7 @@ public class DhFadeRenderer FadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; FadeApplyShader.INSTANCE.readFramebuffer = DhFadeShader.INSTANCE.frameBuffer; - FadeApplyShader.INSTANCE.drawFramebuffer = LodRenderer.INSTANCE.getActiveFramebufferId(); + FadeApplyShader.INSTANCE.drawFramebuffer = McLodRenderer.INSTANCE.getActiveFramebufferId(); FadeApplyShader.INSTANCE.render(partialTicks); } catch (Exception e) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java new file mode 100644 index 000000000..85a9b19a3 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -0,0 +1,359 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.render.renderer; + +import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode; +import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.logging.DhLogger; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.render.DhApiRenderProxy; +import com.seibel.distanthorizons.core.render.RenderBufferHandler; +import com.seibel.distanthorizons.core.util.math.Vec3d; +import com.seibel.distanthorizons.core.util.objects.SortedArraySet; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; +import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; +import com.seibel.distanthorizons.core.util.math.Vec3f; + +/** + * This is where all the magic happens.
+ * This is where LODs are draw to the world. + */ +public class McLodRenderer +{ + public static final DhLogger LOGGER = new DhLoggerBuilder() + .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) + .build(); + + public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder() + .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) + .maxCountPerSecond(4) + .build(); + + private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + + public static final McLodRenderer INSTANCE = new McLodRenderer(); + + + + private boolean renderObjectsCreated = false; + + + + //=============// + // constructor // + //=============// + + private McLodRenderer() { } + + + + //===========// + // rendering // + //===========// + //region + + /** + * This will draw both opaque and transparent LODs if + * {@link DhApiRenderProxy#getDeferTransparentRendering()} is false, + * otherwise it will only render opaque LODs. + */ + public void render(RenderParams renderParams, IProfilerWrapper profiler) + { this.renderLodPass(renderParams, profiler, false); } + + /** + * This method is designed for Iris to be able + * to draw water in a deferred rendering context. + * It needs to be updated with any major changes, + * but shouldn't be activated as per deferWaterRendering. + */ + public void renderDeferred(RenderParams renderParams, IProfilerWrapper profiler) + { this.renderLodPass(renderParams, profiler, true); } + + private void renderLodPass(RenderParams renderParams, IProfilerWrapper profiler, boolean runningDeferredPass) + { + //====================// + // validate rendering // + //====================// + + boolean deferTransparentRendering = DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); + if (runningDeferredPass + && !deferTransparentRendering) + { + return; + } + boolean firstPass = !runningDeferredPass; + + // RenderParams parameter validation should be done before this + if (!renderParams.validationRun) + { + throw new IllegalArgumentException("Render parameters validation"); + } + + RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; + //GenericObjectRenderer genericRenderer = renderParams.genericRenderer; + + + + //=================// + // rendering setup // + //=================// + + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams); + profiler.push("LOD GL setup"); + + if (!this.renderObjectsCreated) + { + // only do this once, that way they can still be reverted if desired + if (Config.Client.Advanced.Graphics.overrideVanillaGraphicsSettings.get()) + { + LOGGER.info("Overriding vanilla MC settings to better fit Distant Horizons... This behavior can be disabled in the Distant Horizons config."); + + MC.disableVanillaClouds(); + MC.disableVanillaChunkFadeIn(); + MC.disableFabulousTransparency(); + } + + this.renderObjectsCreated = true; + } + + if (firstPass) + { + // we only need to sort/cull the LODs during the first frame + profiler.popPush("LOD build render list"); + renderBufferHandler.buildRenderList(renderParams); + } + + IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); + + + + //===========// + // rendering // + //===========// + + if (!runningDeferredPass) + { + //=========================// + // opaque and non-deferred // + // transparent rendering // + //=========================// + + // opaque LODs + profiler.popPush("LOD Opaque"); + + this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ true, profiler); + + // custom objects with SSAO + if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) + { + //profiler.popPush("Custom Objects"); + //genericRenderer.render(renderParams, profiler, true); + } + + // SSAO + if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get()) + { + //profiler.popPush("LOD SSAO"); + //SSAORenderer.INSTANCE.render(new Mat4f(renderParams.dhProjectionMatrix), renderParams.partialTicks); + } + + // custom objects without SSAO + if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) + { + //profiler.popPush("Custom Objects"); + //genericRenderer.render(renderParams, profiler, false); + } + + // combined pass transparent rendering + if (!deferTransparentRendering + && Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) + { + profiler.popPush("LOD Transparent"); + this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); + } + + // far plane clip fading + if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get()) + { + //profiler.popPush("Fade Far Clip Fade"); + //DhFadeRenderer.INSTANCE.render( + // new Mat4f(renderParams.mcModelViewMatrix), new Mat4f(renderParams.mcProjectionMatrix), + // renderParams.partialTicks, profiler); + } + + // fog + if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() + // this is done to fix issues with: underwater fog, blindness effect, etc. + || renderParams.vanillaFogEnabled) + { + //profiler.popPush("LOD Fog"); + // + //Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); + //combinedMatrix.multiply(renderParams.dhModelViewMatrix); + // + //FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); + } + + + + //=================// + // debug rendering // + //=================// + + if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get()) + { + //profiler.popPush("Debug wireframes"); + // + //Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); + //combinedMatrix.multiply(renderParams.dhModelViewMatrix); + // + //// Note: this can be very slow if a lot of boxes are being rendered + //DebugRenderer.INSTANCE.render(combinedMatrix); + } + + lodRenderer.clearDepth(); + + } + else + { + ////====================// + //// deferred rendering // + ////====================// + // + //if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) + //{ + // profiler.popPush("LOD Transparent"); + // this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ false); + // + // + // if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() + // // this is done to fix issues with: underwater fog, blindness effect, etc. + // || renderParams.vanillaFogEnabled) + // { + // profiler.popPush("LOD Fog"); + // + // Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); + // combinedMatrix.multiply(renderParams.dhModelViewMatrix); + // + // FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); + // } + //} + } + + + + //================// + // render cleanup // + //================// + + profiler.popPush("LOD cleanup"); + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams); + + + + // end of internal LOD profiling + profiler.pop(); + } + + //endregion + + + + + + //===============// + // LOD rendering // + //===============// + //region + + private void renderLodPass(IMcLodRenderer lodRenderer, RenderBufferHandler lodBufferHandler, RenderParams renderEventParam, boolean opaquePass, IProfilerWrapper profilerWrapper) + { + //===========// + // rendering // + //===========// + + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam); + + if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) + { + // Normal LOD rendering + + SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); + if (lodBufferContainer != null) + { + for (int lodIndex = 0; lodIndex < lodBufferContainer.size(); lodIndex++) + { + LodBufferContainer bufferContainer = lodBufferContainer.get(lodIndex); + // TODO match buffer builder debugger + //if (bufferContainer.pos != DhSectionPos.encode((byte)6, 1,0)) + //{ + // continue; + //} + + Vec3d camPos = renderEventParam.exactCameraPosition; + Vec3f modelPos = new Vec3f( + (float) (bufferContainer.minCornerBlockPos.getX() - camPos.x), + (float) (bufferContainer.minCornerBlockPos.getY() - camPos.y), + (float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z)); + + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos)); + + IVertexBufferWrapper[] vbos = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent; + lodRenderer.render(renderEventParam, opaquePass, modelPos, vbos, profilerWrapper); + } + } + } + else + { + IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); + testRenderer.render(); + } + } + + //endregion + + + + //===============// + // API functions // + //===============// + //region + + /** @return -1 if no frame buffer has been bound yet */ + public int getActiveFramebufferId() { return -1; } + + /** @return -1 if no texture has been bound yet */ + public int getActiveColorTextureId() { return -1; } + + /** @return -1 if no texture has been bound yet */ + public int getActiveDepthTextureId() { return -1; } + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java index 497e4b0de..b1d429cb5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java @@ -19,8 +19,6 @@ package com.seibel.distanthorizons.core.render.renderer; -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; import org.lwjgl.opengl.GL32; @@ -46,7 +44,7 @@ public class ScreenQuad -1, 1, }; - private GLVertexBuffer boxBuffer; + //private GLVertexBuffer boxBuffer; private AbstractVertexAttribute va; private boolean init = false; @@ -77,10 +75,10 @@ public class ScreenQuad { this.init(); - this.boxBuffer.bind(); + //this.boxBuffer.bind(); this.va.bind(); - this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId()); + //this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId()); GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); } @@ -91,9 +89,9 @@ public class ScreenQuad buffer.asFloatBuffer().put(box_vertices); buffer.rewind(); - this.boxBuffer = new GLVertexBuffer(false); - this.boxBuffer.bind(); - this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EDhApiGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); + //this.boxBuffer = new GLVertexBuffer(false); + //this.boxBuffer.bind(); + //this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EDhApiGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); MemoryUtil.memFree(buffer); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java index f1c1d5a5a..45a1b5ff7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java @@ -121,7 +121,7 @@ public class VanillaFadeRenderer public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) { - int depthTextureId = LodRenderer.INSTANCE.getActiveDepthTextureId(); + int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); if (depthTextureId == -1) { // the renderer hasn't been set up yet diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java index d93c2be8f..a3af4bbc6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java @@ -38,7 +38,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -86,7 +85,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister private IDhApiGenericObjectShaderProgram instancedShaderProgram; private IDhApiGenericObjectShaderProgram directShaderProgram; - private GLVertexBuffer boxVertexBuffer; + //private GLVertexBuffer boxVertexBuffer; private GLElementBuffer boxIndexBuffer; private boolean instancedRenderingAvailable; @@ -219,9 +218,9 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES); boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); boxVerticesBuffer.rewind(); - this.boxVertexBuffer = new GLVertexBuffer(false); - this.boxVertexBuffer.bind(); - this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); + //this.boxVertexBuffer = new GLVertexBuffer(false); + //this.boxVertexBuffer.bind(); + //this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); MemoryUtil.memFree(boxVerticesBuffer); // box vertex indexes @@ -424,7 +423,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister } shaderProgram.bind(renderEventParam); - shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId()); + //shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId()); this.boxIndexBuffer.bind(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java index 95b0c8b05..030a74c7f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java @@ -23,14 +23,14 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.glObject.GLState; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.logging.DhLogger; import org.lwjgl.opengl.GL32; /** - * Copies {@link LodRenderer}'s currently active color and depth texture to Minecraft's framebuffer. + * Copies {@link McLodRenderer}'s currently active color and depth texture to Minecraft's framebuffer. */ public class DhApplyShader extends AbstractShaderRenderer { @@ -117,11 +117,11 @@ public class DhApplyShader extends AbstractShaderRenderer //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveColorTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveColorTextureId()); GL32.glUniform1i(this.gDhColorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 1); // Copy to MC's framebuffer @@ -141,7 +141,7 @@ public class DhApplyShader extends AbstractShaderRenderer return; } - int dhFrameBufferId = LodRenderer.INSTANCE.getActiveFramebufferId(); + int dhFrameBufferId = McLodRenderer.INSTANCE.getActiveFramebufferId(); if (dhFrameBufferId == -1) { return; @@ -170,11 +170,11 @@ public class DhApplyShader extends AbstractShaderRenderer //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveColorTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveColorTextureId()); GL32.glUniform1i(this.gDhColorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 1); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java index 884aa8b1f..d7bf72b40 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java @@ -21,7 +21,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; @@ -126,8 +126,8 @@ public class DhFadeShader extends AbstractShaderRenderer @Override protected void onRender() { - int depthTextureId = LodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = LodRenderer.INSTANCE.getActiveColorTextureId(); + int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); + int colorTextureId = McLodRenderer.INSTANCE.getActiveColorTextureId(); if (depthTextureId == -1 || colorTextureId == -1) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java index 3c90a17e7..a0b3086b5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java @@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.renderer.FogRenderer; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import org.lwjgl.opengl.GL32; @@ -82,7 +82,7 @@ public class FogApplyShader extends AbstractShaderRenderer GL32.glUniform1i(this.colorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.depthTextureUniform, 1); } @@ -108,7 +108,7 @@ public class FogApplyShader extends AbstractShaderRenderer // apply the rendered Fog to DH's framebuffer GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FogShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.INSTANCE.getActiveFramebufferId()); + GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, McLodRenderer.INSTANCE.getActiveFramebufferId()); ScreenQuad.INSTANCE.render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 028fb4d78..3f18283fe 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -25,7 +25,7 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -264,7 +264,7 @@ public class FogShader extends AbstractShaderRenderer GLMC.disableBlend(); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.uDepthMap, 0); // this is necessary for MC 1.16 (IE Legacy OpenGL) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index e2861d8cc..099b0bc9d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -19,10 +19,9 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; -import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; @@ -87,7 +86,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer protected void onApplyUniforms(float partialTicks) { GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); @@ -136,7 +135,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer // apply the rendered SSAO to the LODs GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, SSAOShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, LodRenderer.INSTANCE.getActiveFramebufferId()); + GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, McLodRenderer.INSTANCE.getActiveFramebufferId()); ScreenQuad.INSTANCE.render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index 3327f9e56..a0dd90cf5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -19,16 +19,13 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; -import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.NumberUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.coreapi.util.MathUtil; import org.lwjgl.opengl.GL32; /** @@ -136,7 +133,7 @@ public class SSAOShader extends AbstractShaderRenderer GLMC.disableBlend(); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(LodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); ScreenQuad.INSTANCE.render(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java index 028eb8088..9ea2c4f04 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java @@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.LodRenderer; +import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; @@ -156,8 +156,8 @@ public class VanillaFadeShader extends AbstractShaderRenderer @Override protected void onRender() { - int depthTextureId = LodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = LodRenderer.INSTANCE.getActiveColorTextureId(); + int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); + int colorTextureId = McLodRenderer.INSTANCE.getActiveColorTextureId(); if (depthTextureId == -1 || colorTextureId == -1) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index 13da93aed..f7aefe454 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory; import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.IBatchGeneratorEnvironmentWrapper; @@ -102,4 +103,8 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable */ IChunkWrapper createChunkWrapper(Object[] objectArray) throws ClassCastException; + + + IVertexBufferWrapper createVboWrapper(); + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java new file mode 100644 index 000000000..857555205 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -0,0 +1,43 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcLodRenderer extends IBindable +{ + //void fillUniformData(DhApiRenderParam renderEventParam); + ///** sets the vec3 that all DH verticies should be offset by when rendering */ + //void setModelOffsetPos(DhApiVec3f modelPos); + + //void render(IVertexBufferWrapper[] bufferList, IProfilerWrapper profiler); + void render( + DhApiRenderParam renderEventParam, boolean opaquePass, + DhApiVec3f modelPos, IVertexBufferWrapper[] bufferList, + IProfilerWrapper profiler); + + int getVertexSize(); + + void clearDepth(); + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java new file mode 100644 index 000000000..24ea0bd11 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java @@ -0,0 +1,35 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +import java.nio.ByteBuffer; + +public interface IVertexBufferWrapper extends IBindable, AutoCloseable +{ + void upload(ByteBuffer buffer, int vertexCount); + + @Override + void close(); + + int getVertexCount(); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh new file mode 100644 index 000000000..0f57d5f17 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh @@ -0,0 +1,135 @@ +#version 150 + +in vec4 vertexColor; +in vec3 vertexWorldPos; +in vec4 vPos; +in vec4 gl_FragCoord; + +out vec4 fragColor; + +//// Fade/Clip Uniforms +//layout (std140) uniform uClipDistance { float uClipDistance; }; +// +//// Noise Uniforms +//layout (std140) uniform uNoiseEnabled { bool uNoiseEnabled; }; +//layout (std140) uniform uNoiseSteps { int uNoiseSteps; }; +//layout (std140) uniform uNoiseIntensity { float uNoiseIntensity; }; +//layout (std140) uniform uNoiseDropoff { int uNoiseDropoff; }; +//layout (std140) uniform uDitherDhRendering { bool uDitherDhRendering; }; + +layout (std140) uniform fragUniformBlock +{ + // Fade/Clip Uniforms + float uClipDistance; + + // Noise Uniforms + bool uNoiseEnabled; + int uNoiseSteps; + float uNoiseIntensity; + int uNoiseDropoff; + bool uDitherDhRendering; +}; + + +// The random functions for diffrent dimentions +float rand(float co) { return fract(sin(co*(91.3458)) * 47453.5453); } +float rand(vec2 co) { return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } +float rand(vec3 co) { return rand(co.xy + rand(co.z)); } + +// Puts steps in a float +// EG. setting stepSize to 4 then this would be the result of this function +// In: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, ..., 1.1, 1.2, 1.3 +// Out: 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, ..., 1.0, 1.0, 1.25 +vec3 quantize(vec3 val, int stepSize) +{ + return floor(val * stepSize) / stepSize; +} + +void applyNoise(inout vec4 fragColor, const in float viewDist) +{ + vec3 vertexNormal = normalize(cross(dFdy(vPos.xyz), dFdx(vPos.xyz))); + // This bit of code is required to fix the vertex position problem cus of floats in the verted world position varuable + vec3 fixedVPos = vPos.xyz + vertexNormal * 0.001; + + float noiseAmplification = uNoiseIntensity; + float lum = (fragColor.r + fragColor.g + fragColor.b) / 3.0; + noiseAmplification = (1.0 - pow(lum * 2.0 - 1.0, 2.0)) * noiseAmplification; // Lessen the effect on depending on how dark the object is, equasion for this is -(2x-1)^{2}+1 + noiseAmplification *= fragColor.a; // The effect would lessen on transparent objects + + // Random value for each position + float randomValue = rand(quantize(fixedVPos, uNoiseSteps)) + * 2.0 * noiseAmplification - noiseAmplification; + + // Modifies the color + // A value of 0 on the randomValue will result in the original color, while a value of 1 will result in a fully bright color + vec3 newCol = fragColor.rgb + (1.0 - fragColor.rgb) * randomValue; + newCol = clamp(newCol, 0.0, 1.0); + + if (uNoiseDropoff != 0) { + float distF = min(viewDist / uNoiseDropoff, 1.0); + newCol = mix(newCol, fragColor.rgb, distF); // The further away it gets, the less noise gets applied + } + + fragColor.rgb = newCol; +} + +/** returns a normalized value between 0.0 and 1.0 */ +float bayerMatrix4x4(vec2 st) +{ + int x = int(mod(st.x, 4.0)); + int y = int(mod(st.y, 4.0)); + + // Flattened 4x4 Bayer matrix + float bayer4x4[16] = float[16]( + 0.0, 8.0, 2.0, 10.0, + 12.0, 4.0, 14.0, 6.0, + 3.0, 11.0, 1.0, 9.0, + 15.0, 7.0, 13.0, 5.0 + ); + + // Calculate the 1D index from the 2D coordinates + int index = y * 4 + x; + + // Return the Bayer value normalized between 0.0 and 1.0 + return bayer4x4[index] / 16.0; +} + + + +void main() +{ + fragColor = vertexColor; + + float viewDist = length(vertexWorldPos); + + if (uDitherDhRendering) + { + // Dither out the fragment based on distance and noise. + // Dithering is used since it works for both opaque and transparent rendering + + // noise increases as the distance increases + // the fragCoord is used since it is stable and small so the dithering is cleaner + float worldNoise = bayerMatrix4x4(gl_FragCoord.xy); + // minor fudge factor to make sure all pixels fade out + // if not included 1 in 16 pixels would never fade away + worldNoise += 0.001; + + float fadeStep = smoothstep(uClipDistance, uClipDistance * 1.5, viewDist); + if (fadeStep <= worldNoise) + { + discard; + } + } + else + { + if (viewDist < uClipDistance && uClipDistance > 0.0) + { + discard; + } + } + + if (uNoiseEnabled) + { + applyNoise(fragColor, viewDist); + } +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh new file mode 100644 index 000000000..c86733ff0 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh @@ -0,0 +1,87 @@ +#version 330 core + +in uvec4 vPosition; +in vec4 vColor; + +out vec4 vPos; +out vec4 vertexColor; +out vec3 vertexWorldPos; +out float vertexYPos; + +//layout (std140) uniform uIsWhiteWorld { bool uIsWhiteWorld; }; +//layout (std140) uniform uCombinedMatrix { mat4 uCombinedMatrix; }; +//layout (std140) uniform uModelOffset { vec3 uModelOffset; }; +//layout (std140) uniform uWorldYOffset { float uWorldYOffset; }; +//layout (std140) uniform uMircoOffset { float uMircoOffset; }; +//layout (std140) uniform uEarthRadius { float uEarthRadius; }; + +layout (std140) uniform vertUniformBlock +{ + bool uIsWhiteWorld; + mat4 uCombinedMatrix; + vec3 uModelOffset; + float uWorldYOffset; + float uMircoOffset; + float uEarthRadius; +}; + +uniform sampler2D uLightMap; + +/** + * Vertex Shader + * + * author: James Seibel + * author: TomTheFurry + * author: stduhpf + * updated: coolGi + * + * version: 2025-12-22 + */ +void main() +{ + vPos = vPosition; // This is so it can be passed to the fragment shader + + vertexWorldPos = vPosition.xyz + uModelOffset; + + vertexYPos = vPosition.y + uWorldYOffset; + + uint meta = vPosition.a; + + uint mirco = (meta & 0xFF00u) >> 8u; // mirco offset which is a xyz 2bit value + // 0b00 = no offset + // 0b01 = positive offset + // 0b11 = negative offset + // format is: 0b00zzyyxx + float mx = (mirco & 1u)!=0u ? uMircoOffset : 0.0; + mx = (mirco & 2u)!=0u ? -mx : mx; + //float my = (mirco & 4u)!=0u ? uMircoOffset : 0.0; + //my = (mirco & 8u)!=0u ? -my : my; + float mz = (mirco & 16u)!=0u ? uMircoOffset : 0.0; + mz = (mirco & 32u)!=0u ? -mz : mz; + + vertexWorldPos.x += mx; + //vertexWorldPos.y += my; + vertexWorldPos.z += mz; + + // apply the earth curvature if needed + if (uEarthRadius < -1.0f || uEarthRadius > 1.0f) + { + // vertex transformation logic - stduhpf + float localRadius = uEarthRadius + vertexYPos; + float phi = length(vertexWorldPos.xz) / localRadius; + vertexWorldPos.y += (cos(phi) - 1.0) * localRadius; + vertexWorldPos.xz = vertexWorldPos.xz * sin(phi) / phi; + } + + uint lights = meta & 0xFFu; + float skyLight = (float(lights/16u)+0.5) / 16.0; + float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0; + vertexColor = vec4(1.0); //vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); + + if (!uIsWhiteWorld) + { + vertexColor *= vColor; + } + + gl_Position = uCombinedMatrix * vec4(vertexWorldPos, 1.0); +} diff --git a/core/src/main/resources/shaders/standard.vert b/core/src/main/resources/shaders/standard.vert index f948f1708..86393a15e 100644 --- a/core/src/main/resources/shaders/standard.vert +++ b/core/src/main/resources/shaders/standard.vert @@ -1,9 +1,9 @@ #version 150 core in uvec4 vPosition; -out vec4 vPos; in vec4 color; +out vec4 vPos; out vec4 vertexColor; out vec3 vertexWorldPos; out float vertexYPos; @@ -68,7 +68,7 @@ void main() uint lights = meta & 0xFFu; float skyLight = (float(lights/16u)+0.5) / 16.0; float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0; - vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); + vertexColor = vec4(1.0); //vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); if (!uIsWhiteWorld) { From c6a43557185d068ef0c0f35c60235d275dbe4960 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 28 Feb 2026 08:13:26 -0600 Subject: [PATCH 06/46] minor render cleanup --- .../bufferBuilding/LodBufferContainer.java | 4 ---- .../distanthorizons/core/util/LodUtil.java | 1 + .../render/IMcLodRenderer.java | 5 ----- .../shaders/fade/vanillaFade.fsh | 19 +++++++++++-------- .../distanthorizons/shaders/lod/frag.fsh | 16 +++------------- .../distanthorizons/shaders/lod/vert.vsh | 16 ++++++---------- 6 files changed, 21 insertions(+), 40 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index 94e170e8e..0a8ecf4a9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -220,12 +220,8 @@ public class LodBufferContainer implements AutoCloseable ByteBuffer buffer = byteBuffers.get(i); int size = buffer.limit() - buffer.position(); - //int vertexCount = size / LodUtil.DH_VERTEX_FORMAT.getByteSize(); int vertexCount = size / lodRenderer.getVertexSize(); - // 6,1,0 - // java.nio.DirectByteBuffer[pos=0 lim=219840 cap=10485760] - // 13740 try { vbo.upload(buffer, vertexCount); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java index 92516bc46..e24634518 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java @@ -109,6 +109,7 @@ public class LodUtil public static final int MAX_ALLOCATABLE_DIRECT_MEMORY = 64 * 1024 * 1024; /** the format of data stored in the GPU buffers */ + @Deprecated public static final LodVertexFormat DH_VERTEX_FORMAT = VertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java index 857555205..dbcadf849 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -26,11 +26,6 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab public interface IMcLodRenderer extends IBindable { - //void fillUniformData(DhApiRenderParam renderEventParam); - ///** sets the vec3 that all DH verticies should be offset by when rendering */ - //void setModelOffsetPos(DhApiVec3f modelPos); - - //void render(IVertexBufferWrapper[] bufferList, IProfilerWrapper profiler); void render( DhApiRenderParam renderEventParam, boolean opaquePass, DhApiVec3f modelPos, IVertexBufferWrapper[] bufferList, diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh index da2064fa0..186ef51e2 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh @@ -4,20 +4,23 @@ in vec2 TexCoord; out vec4 fragColor; -// inverted model view matrix and projection matrix -uniform mat4 uDhInvMvmProj; -uniform mat4 uMcInvMvmProj; - uniform sampler2D uMcDepthTexture; uniform sampler2D uDhDepthTexture; uniform sampler2D uCombinedMcDhColorTexture; uniform sampler2D uDhColorTexture; -uniform float uStartFadeBlockDistance; -uniform float uEndFadeBlockDistance; -uniform float uMaxLevelHeight; +layout (std140) uniform fragUniformBlock +{ + // inverted model view matrix and projection matrix + mat4 uDhInvMvmProj; + mat4 uMcInvMvmProj; -uniform bool uOnlyRenderLods; + float uStartFadeBlockDistance; + float uEndFadeBlockDistance; + float uMaxLevelHeight; + + bool uOnlyRenderLods; +}; diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh index 0f57d5f17..5431a2ce0 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh @@ -7,27 +7,17 @@ in vec4 gl_FragCoord; out vec4 fragColor; -//// Fade/Clip Uniforms -//layout (std140) uniform uClipDistance { float uClipDistance; }; -// -//// Noise Uniforms -//layout (std140) uniform uNoiseEnabled { bool uNoiseEnabled; }; -//layout (std140) uniform uNoiseSteps { int uNoiseSteps; }; -//layout (std140) uniform uNoiseIntensity { float uNoiseIntensity; }; -//layout (std140) uniform uNoiseDropoff { int uNoiseDropoff; }; -//layout (std140) uniform uDitherDhRendering { bool uDitherDhRendering; }; - layout (std140) uniform fragUniformBlock { // Fade/Clip Uniforms float uClipDistance; - + // Noise Uniforms - bool uNoiseEnabled; - int uNoiseSteps; float uNoiseIntensity; + int uNoiseSteps; int uNoiseDropoff; bool uDitherDhRendering; + bool uNoiseEnabled; }; diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh index c86733ff0..2401f9889 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh @@ -1,4 +1,4 @@ -#version 330 core +#version 150 in uvec4 vPosition; in vec4 vColor; @@ -8,21 +8,17 @@ out vec4 vertexColor; out vec3 vertexWorldPos; out float vertexYPos; -//layout (std140) uniform uIsWhiteWorld { bool uIsWhiteWorld; }; -//layout (std140) uniform uCombinedMatrix { mat4 uCombinedMatrix; }; -//layout (std140) uniform uModelOffset { vec3 uModelOffset; }; -//layout (std140) uniform uWorldYOffset { float uWorldYOffset; }; -//layout (std140) uniform uMircoOffset { float uMircoOffset; }; -//layout (std140) uniform uEarthRadius { float uEarthRadius; }; - layout (std140) uniform vertUniformBlock { bool uIsWhiteWorld; - mat4 uCombinedMatrix; - vec3 uModelOffset; + float uWorldYOffset; float uMircoOffset; float uEarthRadius; + + vec3 uModelOffset; + + mat4 uCombinedMatrix; }; uniform sampler2D uLightMap; From 1a2c0b0be1f0df3f2cb0e4dd2a815e8718175d5d Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 28 Feb 2026 11:34:39 -0600 Subject: [PATCH 07/46] re-add vanilla fading --- .../core/api/internal/ClientApi.java | 84 ++++++++++--------- .../core/render/renderer/McLodRenderer.java | 8 +- .../render/IMcFadeRenderer.java | 5 +- .../render/IMcLodRenderer.java | 2 + .../distanthorizons/shaders/apply/frag.fsh | 29 +++++++ .../distanthorizons/shaders/apply/vert.vsh | 12 +++ .../distanthorizons/shaders/copy/frag.fsh | 13 +++ .../distanthorizons/shaders/copy/vert.vsh | 12 +++ .../shaders/fade/{frag.fsh => depth_test.fsh} | 0 .../{vanillaFade.fsh => vanilla_fade.fsh} | 15 ++-- 10 files changed, 131 insertions(+), 49 deletions(-) create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh rename core/src/main/resources/assets/distanthorizons/shaders/fade/{frag.fsh => depth_test.fsh} (100%) rename core/src/main/resources/assets/distanthorizons/shaders/fade/{vanillaFade.fsh => vanilla_fade.fsh} (99%) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 682f842df..bc60eb930 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -20,6 +20,7 @@ package com.seibel.distanthorizons.core.api.internal; import com.seibel.distanthorizons.api.DhApi; +import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode; import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState; @@ -37,6 +38,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; @@ -643,28 +645,27 @@ public class ClientApi */ public void renderFadeOpaque() { - //IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); - //if (fadeRenderer == null) - //{ - // return; - //} - //fadeRenderer.render(); + IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + if (fadeRenderer == null) + { + return; + } - - //// only fade when DH is rendering - //if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED - // && - // ( - // // only fade when requested - // Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() == EDhApiMcRenderingFadeMode.DOUBLE_PASS - // // or if LOD-only mode is enabled (fading is used to remove the MC render pass) - // || Config.Client.Advanced.Debugging.lodOnlyMode.get() - // ) - // // don't fade when Iris shaders are active, otherwise the rendering can get weird - // && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) - //{ - // VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); - //} + // only fade when DH is rendering + if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED + && + ( + // only fade when requested + Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() == EDhApiMcRenderingFadeMode.DOUBLE_PASS + // or if LOD-only mode is enabled (fading is used to remove the MC render pass) + || Config.Client.Advanced.Debugging.lodOnlyMode.get() + ) + // don't fade when Iris shaders are active, otherwise the rendering can get weird + && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) + { + fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); + //VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); + } } /** * The second fade pass. @@ -673,25 +674,30 @@ public class ClientApi */ public void renderFadeTransparent() { + IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + if (fadeRenderer == null) + { + return; + } - - //// only fade when DH is rendering - //if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED) - //{ - // boolean renderFade = - // ( - // // only fade when requested - // Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() != EDhApiMcRenderingFadeMode.NONE - // // or if LOD-only mode is enabled (fading is used to remove the MC render pass) - // || Config.Client.Advanced.Debugging.lodOnlyMode.get() - // ) - // // don't fade when Iris shaders are active, otherwise the rendering can get weird - // && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); - // if (renderFade) - // { - // VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); - // } - //} + // only fade when DH is rendering + if (Config.Client.Advanced.Debugging.rendererMode.get() != EDhApiRendererMode.DISABLED) + { + boolean renderFade = + ( + // only fade when requested + Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.get() != EDhApiMcRenderingFadeMode.NONE + // or if LOD-only mode is enabled (fading is used to remove the MC render pass) + || Config.Client.Advanced.Debugging.lodOnlyMode.get() + ) + // don't fade when Iris shaders are active, otherwise the rendering can get weird + && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); + if (renderFade) + { + fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); + //VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); + } + } } ///endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 85a9b19a3..9d4cd0cf8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -157,6 +157,10 @@ public class McLodRenderer if (!runningDeferredPass) { + lodRenderer.clearColor(); + lodRenderer.clearDepth(); + + //=========================// // opaque and non-deferred // // transparent rendering // @@ -235,8 +239,6 @@ public class McLodRenderer //DebugRenderer.INSTANCE.render(combinedMatrix); } - lodRenderer.clearDepth(); - } else { @@ -326,6 +328,8 @@ public class McLodRenderer lodRenderer.render(renderEventParam, opaquePass, modelPos, vbos, profilerWrapper); } } + + lodRenderer.applyToMcTexture(); } else { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java index 4180fc986..fd372f4f6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java @@ -19,11 +19,14 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IMcFadeRenderer extends IBindable { - void render(); + void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java index dbcadf849..3810c2ac7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -33,6 +33,8 @@ public interface IMcLodRenderer extends IBindable int getVertexSize(); + void applyToMcTexture(); void clearDepth(); + void clearColor(); } diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh new file mode 100644 index 000000000..c5a5d3635 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh @@ -0,0 +1,29 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +uniform sampler2D uDhColorTexture; +uniform sampler2D uDhDepthTexture; + +// DH apply frag +void main() +{ + //fragColor = texture(uApplyTexture, TexCoord); + + fragColor = vec4(0.0); + + // a fragment depth of "1" means the fragment wasn't drawn to, + // only update fragments that were drawn to + float fragmentDepth = texture(uDhDepthTexture, TexCoord).r; + if (fragmentDepth != 1) + { + fragColor = texture(uDhColorTexture, TexCoord); + } + else + { + // use the original MC texture if no LODs were drawn to this fragment + discard; + } +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh new file mode 100644 index 000000000..09789a24b --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh @@ -0,0 +1,12 @@ +#version 150 core + +in vec2 vPosition; + +out vec2 TexCoord; + +// DH apply +void main() +{ + gl_Position = vec4(vPosition, 0.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh new file mode 100644 index 000000000..9cbaf97f2 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh @@ -0,0 +1,13 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +uniform sampler2D uCopyTexture; + +// DH copy frag +void main() +{ + fragColor = texture(uCopyTexture, TexCoord); +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh new file mode 100644 index 000000000..d9b009b3b --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh @@ -0,0 +1,12 @@ +#version 150 core + +in vec2 vPosition; + +out vec2 TexCoord; + +// DH copy +void main() +{ + gl_Position = vec4(vPosition, 0.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fade/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanilla_fade.fsh similarity index 99% rename from core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/fade/vanilla_fade.fsh index 186ef51e2..da8d123ae 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanillaFade.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/vanilla_fade.fsh @@ -5,21 +5,22 @@ in vec2 TexCoord; out vec4 fragColor; uniform sampler2D uMcDepthTexture; -uniform sampler2D uDhDepthTexture; uniform sampler2D uCombinedMcDhColorTexture; + +uniform sampler2D uDhDepthTexture; uniform sampler2D uDhColorTexture; layout (std140) uniform fragUniformBlock { - // inverted model view matrix and projection matrix - mat4 uDhInvMvmProj; - mat4 uMcInvMvmProj; - + bool uOnlyRenderLods; + float uStartFadeBlockDistance; float uEndFadeBlockDistance; float uMaxLevelHeight; - - bool uOnlyRenderLods; + + // inverted model view matrix and projection matrix + mat4 uDhInvMvmProj; + mat4 uMcInvMvmProj; }; From 3f509be195bad4dc3988c8805f5bfb56d375a9dc Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 28 Feb 2026 11:34:48 -0600 Subject: [PATCH 08/46] remove unneeded partial ticks from old vanilla fade --- .../core/render/renderer/VanillaFadeRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java index 45a1b5ff7..dfa79ad35 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java @@ -119,7 +119,7 @@ public class VanillaFadeRenderer // render // //========// - public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) + public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level) { int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); if (depthTextureId == -1) @@ -156,7 +156,7 @@ public class VanillaFadeRenderer VanillaFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; VanillaFadeShader.INSTANCE.setProjectionMatrix(mcModelViewMatrix, mcProjectionMatrix); VanillaFadeShader.INSTANCE.setLevelMaxHeight(level.getMaxHeight()); - VanillaFadeShader.INSTANCE.render(partialTicks); + VanillaFadeShader.INSTANCE.render(0); // Applying the fade texture is only needed if MC is drawing to their own frame buffer, // otherwise we can directly render to their texture @@ -167,7 +167,7 @@ public class VanillaFadeRenderer FadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; FadeApplyShader.INSTANCE.readFramebuffer = DhFadeShader.INSTANCE.frameBuffer; FadeApplyShader.INSTANCE.drawFramebuffer = MC_RENDER.getTargetFramebuffer(); - FadeApplyShader.INSTANCE.render(partialTicks); + FadeApplyShader.INSTANCE.render(0); } profiler.pop(); From 200e089a3336ea61c4012f762c6e19d6c5c6c1bb Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 28 Feb 2026 12:13:34 -0600 Subject: [PATCH 09/46] re-add lighting --- .../render/IMcLodRenderer.java | 4 ++-- .../shaders/fade/depth_test.fsh | 24 ------------------- .../distanthorizons/shaders/lod/frag.fsh | 2 +- .../distanthorizons/shaders/lod/vert.vsh | 20 ++++++---------- 4 files changed, 10 insertions(+), 40 deletions(-) delete mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java index 3810c2ac7..681deac04 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -19,15 +19,15 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IMcLodRenderer extends IBindable { void render( - DhApiRenderParam renderEventParam, boolean opaquePass, + RenderParams renderEventParam, boolean opaquePass, DhApiVec3f modelPos, IVertexBufferWrapper[] bufferList, IProfilerWrapper profiler); diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh deleted file mode 100644 index cf8963b19..000000000 --- a/core/src/main/resources/assets/distanthorizons/shaders/fade/depth_test.fsh +++ /dev/null @@ -1,24 +0,0 @@ -#version 150 core - -in vec2 TexCoord; -in vec4 fColor; - -out vec4 fragColor; - -uniform sampler2D uDhDepthTexture; - -// DH fade frag test -void main() -{ - float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; - if (dhFragmentDepth == 1) - { - // no MC depth - fragColor = fColor; - } - else - { - // MC depth drawn - fragColor = vec4(1, 1, 1, 1); // white - } -} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh index 5431a2ce0..86be28a6b 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh @@ -2,7 +2,7 @@ in vec4 vertexColor; in vec3 vertexWorldPos; -in vec4 vPos; +in vec3 vPos; in vec4 gl_FragCoord; out vec4 fragColor; diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh index 2401f9889..56d3b60e9 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh @@ -1,9 +1,12 @@ #version 150 -in uvec4 vPosition; +in uvec3 vPosition; +in uint meta; // contains light and micro-offset data in vec4 vColor; +in int irisMaterial; +in int irisNormal; -out vec4 vPos; +out vec3 vPos; out vec4 vertexColor; out vec3 vertexWorldPos; out float vertexYPos; @@ -24,14 +27,7 @@ layout (std140) uniform vertUniformBlock uniform sampler2D uLightMap; /** - * Vertex Shader - * - * author: James Seibel - * author: TomTheFurry - * author: stduhpf - * updated: coolGi - * - * version: 2025-12-22 + * LOD terrain Vertex Shader */ void main() { @@ -41,8 +37,6 @@ void main() vertexYPos = vPosition.y + uWorldYOffset; - uint meta = vPosition.a; - uint mirco = (meta & 0xFF00u) >> 8u; // mirco offset which is a xyz 2bit value // 0b00 = no offset // 0b01 = positive offset @@ -72,7 +66,7 @@ void main() uint lights = meta & 0xFFu; float skyLight = (float(lights/16u)+0.5) / 16.0; float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0; - vertexColor = vec4(1.0); //vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); + vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); if (!uIsWhiteWorld) { From 3d9ae5f088d24387152bf336e752d041d5a5fb8d Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 1 Mar 2026 19:32:54 -0600 Subject: [PATCH 10/46] generic object rendering --- .../core/level/AbstractDhLevel.java | 3 +- .../core/level/ClientLevelModule.java | 5 +- .../core/level/DhClientLevel.java | 3 +- .../core/level/DhClientServerLevel.java | 3 +- .../core/level/DhServerLevel.java | 3 +- .../distanthorizons/core/level/IDhLevel.java | 3 +- .../core/logging/f3/F3Screen.java | 3 +- .../core/render/QuadTree/LodQuadTree.java | 3 +- .../glObject/buffer/QuadElementBuffer.java | 1 + .../core/render/renderer/LodRenderer.java | 3 +- .../core/render/renderer/McLodRenderer.java | 16 +-- .../core/render/renderer/RenderParams.java | 3 +- .../renderer/generic/BeaconRenderHandler.java | 3 +- .../renderer/generic/CloudRenderHandler.java | 25 ++--- .../generic/GenericObjectRenderer.java | 25 +++-- .../generic/IInstancedVboContainer.java | 38 +++++++ .../generic/InstancedVboContainer.java | 25 ++--- .../renderer/generic/RenderableBoxGroup.java | 22 ++-- .../wrapperInterfaces/IWrapperFactory.java | 6 ++ .../render/IMcGenericRenderer.java | 34 ++++++ .../distanthorizons/shaders/generic/frag.fsh | 10 ++ .../distanthorizons/shaders/generic/vert.vsh | 101 ++++++++++++++++++ 22 files changed, 269 insertions(+), 69 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java index 84dcbf3c0..b1b786924 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java @@ -39,6 +39,7 @@ import com.seibel.distanthorizons.core.sql.repo.ChunkHashRepo; import com.seibel.distanthorizons.core.util.KeyedLockContainer; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.logging.DhLogger; import org.jetbrains.annotations.Nullable; @@ -118,7 +119,7 @@ public abstract class AbstractDhLevel implements IDhLevel /** handles any setup that needs the repos to be created */ protected void runRepoReliantSetup() { - GenericObjectRenderer genericRenderer = this.getGenericRenderer(); + IMcGenericRenderer genericRenderer = this.getGenericRenderer(); if (genericRenderer != null) { // only client levels can render clouds diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java index 852bb3a14..1b58f5902 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java @@ -30,7 +30,9 @@ import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -43,6 +45,7 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); private final IDhClientLevel clientLevel; @@ -56,7 +59,7 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu * Destroying the {@link GenericObjectRenderer} would cause any existing bindings to be * erroneously removed. */ - public final GenericObjectRenderer genericRenderer = new GenericObjectRenderer(); + public final IMcGenericRenderer genericRenderer = WRAPPER_FACTORY.createGenericRenderer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java index fcda9f6d0..3acc1a7b0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java @@ -42,6 +42,7 @@ import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import org.jetbrains.annotations.NotNull; @@ -298,7 +299,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel public ISaveStructure getSaveStructure() { return this.saveStructure; } @Override - public GenericObjectRenderer getGenericRenderer() { return this.clientside.genericRenderer; } + public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } @Override public RenderBufferHandler getRenderBufferHandler() { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java index d1ff86052..d692ffee9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java @@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.jetbrains.annotations.Nullable; @@ -138,7 +139,7 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli @Override - public GenericObjectRenderer getGenericRenderer() { return this.clientside.genericRenderer; } + public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } @Override public RenderBufferHandler getRenderBufferHandler() { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java index 2dcef675f..a4ef3c7c1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java @@ -24,6 +24,7 @@ import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManag import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.jetbrains.annotations.Nullable; @@ -69,7 +70,7 @@ public class DhServerLevel extends AbstractDhServerLevel //=========// @Override - public GenericObjectRenderer getGenericRenderer() + public IMcGenericRenderer getGenericRenderer() { // server-only levels don't support rendering return null; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java index ea01a0d5b..b687537ec 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java @@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRend import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,7 +93,7 @@ public interface IDhLevel extends AutoCloseable, GeneratedFullDataSourceProvider * Not supported on the server-side. */ @Nullable - GenericObjectRenderer getGenericRenderer(); + IMcGenericRenderer getGenericRenderer(); /** * Will return null if the renderer isn't set up yet.
* Not supported on the server-side. diff --git a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java index 25e1a97eb..a66f3a4d6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java @@ -36,6 +36,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.util.StringUtil; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -203,7 +204,7 @@ public class F3Screen } // Generic rendering - GenericObjectRenderer genericRenderer = level.getGenericRenderer(); + IMcGenericRenderer genericRenderer = level.getGenericRenderer(); if (genericRenderer != null) { messageList.add(genericRenderer.getVboRenderDebugMenuString()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java index db02c5424..0e06c6c5e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java @@ -44,6 +44,7 @@ import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode; import com.seibel.distanthorizons.core.util.objects.quadTree.QuadTree; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.coreapi.util.MathUtil; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongIterator; @@ -141,7 +142,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen this.fullDataSourceProvider = fullDataSourceProvider; this.blockRenderDistanceDiameter = viewDiameterInBlocks; - GenericObjectRenderer genericObjectRenderer = this.level.getGenericRenderer(); + IMcGenericRenderer genericObjectRenderer = this.level.getGenericRenderer(); this.beaconRenderHandler = (genericObjectRenderer != null) ? new BeaconRenderHandler(genericObjectRenderer) : null; Config.Common.WorldGenerator.enableDistantGeneration.addListener(this); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java index 341920e01..3176c01ea 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java @@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles; import java.nio.ByteBuffer; import java.nio.ByteOrder; +/** AKA Index Buffer TODO RENAME */ public class QuadElementBuffer extends GLElementBuffer { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 5251e851d..c1adfda11 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -51,6 +51,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; @@ -159,7 +160,7 @@ public class LodRenderer } RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; - GenericObjectRenderer genericRenderer = renderParams.genericRenderer; + IMcGenericRenderer genericRenderer = renderParams.genericRenderer; ILightMapWrapper lightmap = renderParams.lightmap; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 9d4cd0cf8..9059baaa0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -28,10 +28,12 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; +import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; @@ -114,7 +116,7 @@ public class McLodRenderer } RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; - //GenericObjectRenderer genericRenderer = renderParams.genericRenderer; + IMcGenericRenderer genericRenderer = renderParams.genericRenderer; @@ -174,8 +176,8 @@ public class McLodRenderer // custom objects with SSAO if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) { - //profiler.popPush("Custom Objects"); - //genericRenderer.render(renderParams, profiler, true); + profiler.popPush("Custom Objects"); + genericRenderer.render(renderParams, profiler, true); } // SSAO @@ -188,8 +190,8 @@ public class McLodRenderer // custom objects without SSAO if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) { - //profiler.popPush("Custom Objects"); - //genericRenderer.render(renderParams, profiler, false); + profiler.popPush("Custom Objects"); + genericRenderer.render(renderParams, profiler, false); } // combined pass transparent rendering @@ -239,6 +241,8 @@ public class McLodRenderer //DebugRenderer.INSTANCE.render(combinedMatrix); } + lodRenderer.applyToMcTexture(); + } else { @@ -328,8 +332,6 @@ public class McLodRenderer lodRenderer.render(renderEventParam, opaquePass, modelPos, vbos, profilerWrapper); } } - - lodRenderer.applyToMcTexture(); } else { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java index 516592d91..d3a8d9857 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java @@ -19,6 +19,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftCli import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; /** @@ -41,7 +42,7 @@ public class RenderParams extends DhApiRenderParam public IClientLevelWrapper clientLevelWrapper; public ILightMapWrapper lightmap; public RenderBufferHandler renderBufferHandler; - public GenericObjectRenderer genericRenderer; + public IMcGenericRenderer genericRenderer; public Vec3d exactCameraPosition; /** @see DhRenderState#vanillaFogEnabled */ public boolean vanillaFogEnabled; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java index 61c325a9a..00d4a8b5e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java @@ -36,6 +36,7 @@ import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.core.logging.DhLogger; import org.jetbrains.annotations.NotNull; @@ -77,7 +78,7 @@ public class BeaconRenderHandler //=============// //region - public BeaconRenderHandler(@NotNull GenericObjectRenderer renderer) + public BeaconRenderHandler(@NotNull IMcGenericRenderer renderer) { this.activeBeaconBoxRenderGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0)); this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java index 5286f26e4..cef2e1ae6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java @@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -80,7 +81,7 @@ public class CloudRenderHandler = new IDhApiRenderableBoxGroup[(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1][(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1]; private final IDhClientLevel level; - private final GenericObjectRenderer renderer; + private final IMcGenericRenderer renderer; /** cached array so we don't need to re-create it each frame for each cloud group */ private final Vec3d[] cullingCorners = new Vec3d[] @@ -102,7 +103,7 @@ public class CloudRenderHandler //=============// //region - public CloudRenderHandler(IDhClientLevel level, GenericObjectRenderer renderer) + public CloudRenderHandler(IDhClientLevel level, IMcGenericRenderer renderer) { this.level = level; this.renderer = renderer; @@ -316,16 +317,16 @@ public class CloudRenderHandler return; } - if (!this.renderer.getInstancedRenderingAvailable()) - { - if (!this.disabledWarningLogged) - { - this.disabledWarningLogged = true; - LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled."); - } - boxGroup.setActive(false); - return; - } + //if (!this.renderer.getInstancedRenderingAvailable()) + //{ + // if (!this.disabledWarningLogged) + // { + // this.disabledWarningLogged = true; + // LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled."); + // } + // boxGroup.setActive(false); + // return; + //} IClientLevelWrapper clientLevelWrapper = this.level.getClientLevelWrapper(); if (clientLevelWrapper == null) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java index a3af4bbc6..8e3ea5488 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java @@ -38,12 +38,14 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; import com.seibel.distanthorizons.coreapi.ModInfo; @@ -63,7 +65,7 @@ import java.util.concurrent.ConcurrentHashMap; * @see IDhApiCustomRenderRegister * @see DhApiRenderableBox */ -public class GenericObjectRenderer implements IDhApiCustomRenderRegister +public class GenericObjectRenderer implements IMcGenericRenderer { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); @@ -386,7 +388,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister * if true that means this render call is happening before the SSAO pass * and any objects rendered in this pass will have SSAO applied to them. */ - public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao) + @Override + public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao) { // render setup // profiler.push("setup"); @@ -472,7 +475,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister boxGroup.tryUpdateInstancedDataAsync(); // skip groups that haven't been uploaded yet - if (boxGroup.instancedVbos.state != InstancedVboContainer.EState.RENDER) + if (boxGroup.instancedVbos.getState() != InstancedVboContainer.EState.RENDER) { continue; } @@ -554,27 +557,29 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // Bind instance data // profiler.popPush("binding"); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.color); + InstancedVboContainer container = (InstancedVboContainer)(boxGroup.instancedVbos); + + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color); GL32.glEnableVertexAttribArray(1); GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0); this.vertexAttribDivisor(1, 1); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.scale); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale); GL32.glEnableVertexAttribArray(2); this.vertexAttribDivisor(2, 1); GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.chunkPos); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos); GL32.glEnableVertexAttribArray(3); this.vertexAttribDivisor(3, 1); GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.subChunkPos); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos); GL32.glEnableVertexAttribArray(4); this.vertexAttribDivisor(4, 1); GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instancedVbos.material); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material); GL32.glEnableVertexAttribArray(5); this.vertexAttribDivisor(5, 1); GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0); @@ -582,9 +587,9 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // Draw instanced profiler.popPush("render"); - if (boxGroup.instancedVbos.uploadedBoxCount > 0) + if (container.uploadedBoxCount > 0) { - GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, boxGroup.instancedVbos.uploadedBoxCount); + GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java new file mode 100644 index 000000000..7a8a45935 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java @@ -0,0 +1,38 @@ +package com.seibel.distanthorizons.core.render.renderer.generic; + +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; + +import java.util.List; + +public interface IInstancedVboContainer extends AutoCloseable +{ + void uploadDataToGpu(); + + void updateVertexData(List uploadBoxList); + + EState getState(); + void setState(EState state); + + @Override + void close(); + + + + //================// + // helper classes // + //================// + //region + + enum EState + { + NEW, + UPDATING_DATA, + READY_TO_UPLOAD, + RENDER, + + ERROR, + } + + //endregion + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java index 744e3d64c..ff3b1aef9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java @@ -17,7 +17,7 @@ import java.util.List; * * @see RenderableBoxGroup */ -public class InstancedVboContainer implements AutoCloseable +public class InstancedVboContainer implements IInstancedVboContainer { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); @@ -40,7 +40,11 @@ public class InstancedVboContainer implements AutoCloseable public int uploadedBoxCount = 0; - public EState state = EState.NEW; + private EState state = EState.NEW; + @Override + public EState getState() { return this.state; } + @Override + public void setState(EState state) { this.state = state; } @@ -171,23 +175,6 @@ public class InstancedVboContainer implements AutoCloseable - //================// - // helper classes // - //================// - //region - - public enum EState - { - NEW, - UPDATING_DATA, - READY_TO_UPLOAD, - RENDER, - - ERROR, - } - - //endregion - } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java index 56f7a0d17..43365da5d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java @@ -12,6 +12,7 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import org.jetbrains.annotations.Nullable; @@ -35,6 +36,7 @@ public class RenderableBoxGroup private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0); @@ -67,9 +69,9 @@ public class RenderableBoxGroup public Consumer afterRenderFunc; // instance data - public InstancedVboContainer instancedVbos = new InstancedVboContainer(); + public IInstancedVboContainer instancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); /** double buffering for thread safety and to prevent locking the render thread during update */ - private InstancedVboContainer altInstancedVbos = new InstancedVboContainer(); + private IInstancedVboContainer altInstancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); @@ -195,12 +197,12 @@ public class RenderableBoxGroup public void tryUpdateInstancedDataAsync() { // if the alt container is done, swap it in - if (this.altInstancedVbos.state == InstancedVboContainer.EState.READY_TO_UPLOAD) + if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.READY_TO_UPLOAD) { this.altInstancedVbos.uploadDataToGpu(); // swap VBO references for rendering - InstancedVboContainer temp = this.instancedVbos; + IInstancedVboContainer temp = this.instancedVbos; this.instancedVbos = this.altInstancedVbos; this.altInstancedVbos = temp; @@ -224,15 +226,15 @@ public class RenderableBoxGroup } // if the alternate container is already updating, don't double-queue it - if (this.altInstancedVbos.state == InstancedVboContainer.EState.UPDATING_DATA) + if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.UPDATING_DATA) { return; } - this.altInstancedVbos.state = InstancedVboContainer.EState.UPDATING_DATA; + this.altInstancedVbos.setState(InstancedVboContainer.EState.UPDATING_DATA); - this.altInstancedVbos.tryRunRenderThreadSetup(); + //this.altInstancedVbos.tryRunRenderThreadSetup(); // copy over the box list so we can upload without concurrent modification issues this.uploadBoxList.clear(); @@ -252,14 +254,14 @@ public class RenderableBoxGroup catch (Exception e) { LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e); - this.altInstancedVbos.state = InstancedVboContainer.EState.ERROR; + this.altInstancedVbos.setState(InstancedVboContainer.EState.ERROR); } }); } catch (RejectedExecutionException ignore) { // the executor was shut down, it should be back up shortly and able to accept new jobs - this.altInstancedVbos.state = InstancedVboContainer.EState.NEW; + this.altInstancedVbos.setState(InstancedVboContainer.EState.NEW); } } @@ -341,7 +343,7 @@ public class RenderableBoxGroup //region @Override - public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:["+this.originBlockPos.x+","+this.originBlockPos.y+","+this.originBlockPos.z+"], size:["+this.size()+"], active:["+this.active+"]"; } + public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:[("+this.originBlockPos.x+", "+this.originBlockPos.y+", "+this.originBlockPos.z+")], size:["+this.size()+"], active:["+this.active+"]"; } @Override public void close() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index f7aefe454..200a83aa4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -21,8 +21,10 @@ package com.seibel.distanthorizons.core.wrapperInterfaces; import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory; import com.seibel.distanthorizons.core.level.IDhLevel; +import com.seibel.distanthorizons.core.render.renderer.generic.IInstancedVboContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; @@ -107,4 +109,8 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable IVertexBufferWrapper createVboWrapper(); + IInstancedVboContainer createInstancedVboContainer(); + + IMcGenericRenderer createGenericRenderer(); + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java new file mode 100644 index 000000000..8edbe9f73 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java @@ -0,0 +1,34 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcGenericRenderer extends IDhApiCustomRenderRegister, IBindable +{ + void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao); + + String getVboRenderDebugMenuString(); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh new file mode 100644 index 000000000..c3d2ac8c4 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh @@ -0,0 +1,10 @@ +#version 150 core + +in vec4 fColor; + +out vec4 fragColor; + +void main() +{ + fragColor = fColor; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh new file mode 100644 index 000000000..68931fe9a --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh @@ -0,0 +1,101 @@ +#version 330 core + +//layout (location = 1) in vec4 aColor; // RGBA_FLOAT_COLOR +//layout (location = 2) in vec3 aScale; // VEC3_SCALE +//layout (location = 3) in ivec3 aTranslateChunk; // IVEC3_SCALE +//layout (location = 4) in vec3 aTranslateSubChunk; // VEC3_SCALE +//layout (location = 5) in int aMaterial; // IRIS_MATERIAL + +//uniform sampler2D /*vec4*/ uColorMap; +//uniform sampler2D /*vec3*/ uScaleMap; +//uniform sampler2D /*int*/ uTranslateChunkXMap; +//uniform sampler2D /*int*/ uTranslateChunkYMap; +//uniform sampler2D /*int*/ uTranslateChunkZMap; +//uniform sampler2D /*vec3*/ uTranslateSubChunkMap; +//uniform sampler2D /*int*/ uMaterialMap; +// +//in vec3 vPosition; + +in vec3 vPosition; +in vec4 aColor; // RGBA_FLOAT_COLOR +in int aMaterial; // IRIS_MATERIAL + +layout (std140) uniform vertUniformBlock +{ + ivec3 uOffsetChunk; + vec3 uOffsetSubChunk; + ivec3 uCameraPosChunk; + vec3 uCameraPosSubChunk; + + mat4 uProjectionMvm; + int uSkyLight; + int uBlockLight; + + float uNorthShading; + float uSouthShading; + float uEastShading; + float uWestShading; + float uTopShading; + float uBottomShading; +}; + +uniform sampler2D uLightMap; + +out vec4 fColor; + +void main() +{ + vec3 aScale = vec3(1); + + if (aMaterial == 999) + { + aScale = vec3(2); + } + +// vec4 aColor = texelFetch(uColorMap, ivec2(gl_InstanceID,0), 0); +// vec3 aScale = texelFetch(uScaleMap, ivec2(gl_InstanceID,0), 0).xyz; +// +// float chunkX = int(texelFetch(uTranslateChunkXMap, ivec2(gl_InstanceID,0), 0).x); +// float chunkY = int(texelFetch(uTranslateChunkYMap, ivec2(gl_InstanceID,0), 0).x); +// float chunkZ = int(texelFetch(uTranslateChunkZMap, ivec2(gl_InstanceID,0), 0).x); +// ivec3 aTranslateChunk = ivec3(chunkX, chunkY, chunkZ); +// +// vec3 aTranslateSubChunk = texelFetch(uTranslateSubChunkMap, ivec2(gl_InstanceID,0), 0).xyz; +// int aMaterial = int(texelFetch(uMaterialMap, ivec2(gl_InstanceID,0), 0).x); + + // aTranslate - moves the vertex to the boxGroup's relative position + // uOffset - moves the vertex to the boxGroup's world position + // uCameraPos - moves the vertex into camera space + vec3 trans = (uOffsetChunk - uCameraPosChunk) * 16.0f; + // separate float and int values are to fix percission loss at extreme distances from the origin (IE 10,000,000+) + // luckily large translate values minus large cameraPos generally equal values that cleanly fit in a float + trans += (uOffsetSubChunk - uCameraPosSubChunk); + + // combination translation and scaling matrix + mat4 transform = mat4( + aScale.x, 0.0, 0.0, 0.0, + 0.0, aScale.y, 0.0, 0.0, + 0.0, 0.0, aScale.z, 0.0, + trans.x, trans.y, trans.z, 1.0 + ); + + gl_Position = uProjectionMvm * transform * vec4(vPosition, 1.0); + + float blockLight = (float(uBlockLight)+0.5) / 16.0; + float skyLight = (float(uSkyLight)+0.5) / 16.0; + vec4 lightColor = vec4(texture(uLightMap, vec2(blockLight, skyLight)).xyz, 1.0); + + + fColor = lightColor * aColor; + + int vertexIndex = gl_VertexID % 24; + + // apply directional shading + if (vertexIndex >= 0 && vertexIndex < 4) { fColor.rgb *= uNorthShading; } + else if (vertexIndex >= 4 && vertexIndex < 8) { fColor.rgb *= uSouthShading; } + else if (vertexIndex >= 8 && vertexIndex < 12) { fColor.rgb *= uWestShading; } + else if (vertexIndex >= 12 && vertexIndex < 16) { fColor.rgb *= uEastShading; } + else if (vertexIndex >= 16 && vertexIndex < 20) { fColor.rgb *= uBottomShading; } + else if (vertexIndex >= 20 && vertexIndex < 24) { fColor.rgb *= uTopShading; } + +} From 84c212a78040457ca2fb88c998dc95c4758cb1f1 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 2 Mar 2026 07:45:25 -0600 Subject: [PATCH 11/46] add SSAO --- .../core/render/renderer/McLodRenderer.java | 10 +- .../render/IMcSsaoRenderer.java | 32 ++++ .../distanthorizons/shaders/ssao/ao.fsh | 137 ++++++++++++++++++ .../distanthorizons/shaders/ssao/apply.fsh | 79 ++++++++++ .../shaders/ssao/quad_apply.vsh | 15 ++ 5 files changed, 267 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 9059baaa0..fd95c07cf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -33,10 +33,7 @@ import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.*; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.util.math.Vec3f; @@ -150,6 +147,7 @@ public class McLodRenderer } IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); + IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); @@ -183,8 +181,8 @@ public class McLodRenderer // SSAO if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get()) { - //profiler.popPush("LOD SSAO"); - //SSAORenderer.INSTANCE.render(new Mat4f(renderParams.dhProjectionMatrix), renderParams.partialTicks); + profiler.popPush("LOD SSAO"); + ssaoRenderer.render(renderParams.dhProjectionMatrix); } // custom objects without SSAO diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java new file mode 100644 index 000000000..a3931299d --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java @@ -0,0 +1,32 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcSsaoRenderer extends IBindable +{ + + void render(DhApiMat4f dhProjectionMatrix); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh new file mode 100644 index 000000000..517523342 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh @@ -0,0 +1,137 @@ +#version 150 core +#extension GL_ARB_derivative_control : enable + +#define SAMPLE_MAX 64 + +#define saturate(x) (clamp((x), 0.0, 1.0)) + +in vec2 TexCoord; + +out vec4 fragColor; + + +layout (std140) uniform fragUniformBlock +{ + int uSampleCount; + + float uRadius; + float uStrength; + float uMinLight; + float uBias; + float uFadeDistanceInBlocks; + + mat4 uInvProj; + mat4 uProj; +}; + +uniform sampler2D uDhDepthTexture; + +const float EPSILON = 1.e-6; +const float GOLDEN_ANGLE = 2.39996323; +const vec3 MAGIC = vec3(0.06711056, 0.00583715, 52.9829189); +const float PI = 3.1415926538; +const float TAU = PI * 2.0; + + +vec3 unproject(vec4 pos) +{ + return pos.xyz / pos.w; +} + +float InterleavedGradientNoise(const in vec2 pixel) +{ + float x = dot(pixel, MAGIC.xy); + return fract(MAGIC.z * fract(x)); +} + +vec3 calcViewPosition(const in vec3 clipPos) +{ + vec4 viewPos = uInvProj * vec4(clipPos * 2.0 - 1.0, 1.0); + return viewPos.xyz / viewPos.w; +} + +float GetSpiralOcclusion(const in vec2 uv, const in vec3 viewPos, const in vec3 viewNormal) +{ + float dither = InterleavedGradientNoise(gl_FragCoord.xy); + float rotatePhase = dither * TAU; + float rStep = uRadius / uSampleCount; + + vec2 offset; + + float ao = 0.0; + int sampleCount = 0; + float radius = rStep; + for (int i = 0; i < clamp(uSampleCount, 1, SAMPLE_MAX); i++) { + vec2 offset = vec2( + sin(rotatePhase), + cos(rotatePhase) + ) * radius; + + radius += rStep; + rotatePhase += GOLDEN_ANGLE; + + vec3 sampleViewPos = viewPos + vec3(offset, -0.1); + vec3 sampleClipPos = unproject(uProj * vec4(sampleViewPos, 1.0)) * 0.5 + 0.5; + sampleClipPos = saturate(sampleClipPos); + + float sampleClipDepth = textureLod(uDhDepthTexture, sampleClipPos.xy, 0.0).r; + if (sampleClipDepth >= 1.0 - EPSILON) continue; + + sampleClipPos.z = sampleClipDepth; + sampleViewPos = unproject(uInvProj * vec4(sampleClipPos * 2.0 - 1.0, 1.0)); + + vec3 diff = sampleViewPos - viewPos; + float sampleDist = length(diff); + vec3 sampleNormal = diff / sampleDist; + + float sampleNoLm = max(dot(viewNormal, sampleNormal) - uBias, 0.0); + float aoF = 1.0 - saturate(sampleDist / uRadius); + ao += sampleNoLm * aoF; + sampleCount++; + } + + ao /= max(sampleCount, 1); + ao = smoothstep(0.0, uStrength, ao); + + return ao * (1.0 - uMinLight); +} + + +void main() +{ + float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; + float occlusion = 0.0; + + // Do not apply to sky + if (fragmentDepth < 1.0) + { + vec3 viewPos = calcViewPosition(vec3(TexCoord, fragmentDepth)); + + // fading is done to prevent banding/noise + // at super far distance + float distanceFromCamera = length(viewPos); + float fadeDistance = uFadeDistanceInBlocks; + if (distanceFromCamera < fadeDistance) + { + #ifdef GL_ARB_derivative_control + // Get higher precision derivatives when available + vec3 viewNormal = cross(dFdxFine(viewPos.xyz), dFdyFine(viewPos.xyz)); + #else + vec3 viewNormal = cross(dFdx(viewPos.xyz), dFdy(viewPos.xyz)); + #endif + + viewNormal = normalize(viewNormal); + occlusion = GetSpiralOcclusion(TexCoord, viewPos, viewNormal); + + // linearly fade with distance + occlusion *= (fadeDistance - distanceFromCamera) / fadeDistance; + } + else + { + // we're out of range, no need to do any SSAO calculations + occlusion = 0.0; + } + } + + fragColor = vec4(vec3(1.0 - occlusion), 1.0); +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh new file mode 100644 index 000000000..dc48356f3 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh @@ -0,0 +1,79 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +uniform sampler2D uSsaoColorTexture; +uniform sampler2D uDhDepthTexture; + +uniform vec2 gViewSize; +uniform int gBlurRadius; +uniform float gNear; +uniform float gFar; + + +float linearizeDepth(const in float depth) { + return (gNear * gFar) / (depth * (gNear - gFar) + gFar); +} + +float Gaussian(const in float sigma, const in float x) { + return exp(-(x*x) / (2.0 * (sigma*sigma))); +} + +float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, const in float g_sigmaV) { + float g_sigmaX = 1.6; + float g_sigmaY = 1.6; + + int radius = clamp(gBlurRadius, 1, 3); + + vec2 pixelSize = 1.0 / gViewSize; + + float accum = 0.0; + float total = 0.0; + for (int iy = -radius; iy <= radius; iy++) { + float fy = Gaussian(g_sigmaY, iy); + + for (int ix = -radius; ix <= radius; ix++) { + float fx = Gaussian(g_sigmaX, ix); + + vec2 sampleTex = texcoord + ivec2(ix, iy) * pixelSize; + float sampleValue = textureLod(uSsaoColorTexture, sampleTex, 0).r; + float sampleDepth = textureLod(uDhDepthTexture, sampleTex, 0).r; + float sampleLinearDepth = linearizeDepth(sampleDepth); + + float depthDiff = abs(sampleLinearDepth - linearDepth); + float fv = Gaussian(g_sigmaV, depthDiff); + + float weight = fx*fy*fv; + accum += weight * sampleValue; + total += weight; + } + } + + if (total <= 1.e-4) return 1.0; + return accum / total; +} + + +void main() +{ + fragColor = vec4(1.0); + + float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; + + // a fragment depth of "1" means the fragment wasn't drawn to, + // we only want to apply SSAO to LODs, not to the sky outside the LODs + if (fragmentDepth < 1) + { + if (gBlurRadius > 0) + { + float fragmentDepthLinear = linearizeDepth(fragmentDepth); + fragColor.a = BilateralGaussianBlur(TexCoord, fragmentDepthLinear, 1.6); + } + else + { + fragColor.a = texelFetch(uSsaoColorTexture, ivec2(gl_FragCoord.xy), 0).r; + } + } +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh new file mode 100644 index 000000000..3f614c123 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh @@ -0,0 +1,15 @@ +#version 150 core + +in vec2 vPosition; + +out vec2 TexCoord; + +/** + * This is specifically used by application shaders. + * IE post process or pixel transfer shaders, anything that is rendered using a single rectangle. + */ +void main() +{ + gl_Position = vec4(vPosition, 1.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file From 225c2df8df18a241aed931c81dd260ec55d44f8b Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 3 Mar 2026 07:47:58 -0600 Subject: [PATCH 12/46] add fog --- .../core/render/renderer/McLodRenderer.java | 14 +- .../render/renderer/shaders/FogShader.java | 4 +- .../render/IMcFogRenderer.java | 30 ++ .../distanthorizons/shaders/fog/apply.fsh | 27 ++ .../distanthorizons/shaders/fog/fog.fsh | 299 ++++++++++++++++++ .../shaders/fog/quad_apply.vsh | 15 + 6 files changed, 381 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index fd95c07cf..701b42ca9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; +import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -148,6 +149,7 @@ public class McLodRenderer IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); + IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class); @@ -214,12 +216,12 @@ public class McLodRenderer // this is done to fix issues with: underwater fog, blindness effect, etc. || renderParams.vanillaFogEnabled) { - //profiler.popPush("LOD Fog"); - // - //Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - //combinedMatrix.multiply(renderParams.dhModelViewMatrix); - // - //FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); + profiler.popPush("LOD Fog"); + + Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); + combinedMatrix.multiply(renderParams.dhModelViewMatrix); + + fogRenderer.render(combinedMatrix, renderParams.partialTicks); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 3f18283fe..3bc83af45 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -243,9 +243,9 @@ public class FogShader extends AbstractShaderRenderer return fogColor; } - public void setProjectionMatrix(Mat4f projectionMatrix) + public void setProjectionMatrix(Mat4f modelViewProjectionMatrix) { - this.inverseMvmProjMatrix = new Mat4f(projectionMatrix); + this.inverseMvmProjMatrix = new Mat4f(modelViewProjectionMatrix); this.inverseMvmProjMatrix.invert(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java new file mode 100644 index 000000000..05a33cde9 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java @@ -0,0 +1,30 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcFogRenderer extends IBindable +{ + + void render(DhApiMat4f modelViewProjectionMatrix, float partialTicks); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh new file mode 100644 index 000000000..c9316b8ee --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh @@ -0,0 +1,27 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +uniform sampler2D uColorTexture; +uniform sampler2D uDhDepthTexture; + + +/** + * Fog application shader + * + * This merges the rendered fog onto DH's rendered LODs + */ +void main() +{ + fragColor = vec4(0.0); + + // a fragment depth of "1" means the fragment wasn't drawn to, + // only update fragments that were drawn to + float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; + if (fragmentDepth != 1) + { + fragColor = texture(uColorTexture, TexCoord); + } +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh new file mode 100644 index 000000000..9b0614970 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh @@ -0,0 +1,299 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +layout (std140) uniform fragUniformBlock +{ + // fog uniforms + vec4 uFogColor; + float uFogScale; + float uFogVerticalScale; + int uFogDebugMode; + int uFogFalloffType; + + // fog config + float uFarFogStart; + float uFarFogLength; + float uFarFogMin; + float uFarFogRange; + float uFarFogDensity; + + // height fog config + float uHeightFogStart; + float uHeightFogLength; + float uHeightFogMin; + float uHeightFogRange; + float uHeightFogDensity; + + // ??? + bool uHeightFogEnabled; + int uHeightFogFalloffType; + bool uHeightBasedOnCamera; + float uHeightFogBaseHeight; + bool uHeightFogAppliesUp; + bool uHeightFogAppliesDown; + bool uUseSphericalFog; + int uHeightFogMixingMode; + float uCameraBlockYPos; + + // inverted model view matrix and projection matrix + mat4 uInvMvmProj; +}; + +uniform sampler2D uDhDepthTexture; + + + +//====================// +// method definitions // +//====================// + +vec3 calcViewPosition(float fragmentDepth); + +float getFarFogThickness(float dist); +float getHeightFogThickness(float dist); +float calculateHeightFogDepth(float worldYPos); +float mixFogThickness(float far, float height); + +float linearFog(float worldDist, float fogStart, float fogLength, float fogMin, float fogRange); +float exponentialFog(float x, float fogStart, float fogLength, float fogMin, float fogRange, float fogDensity); +float exponentialSquaredFog(float x, float fogStart, float fogLength, float fogMin, float fogRange, float fogDensity); + + + +//======// +// main // +//======// + +/** + * Fragment shader for fog. + * This should be run last so it applies above other affects like Ambient Occlusioning + */ +void main() +{ + float fragmentDepth = texture(uDhDepthTexture, TexCoord).r; + fragColor = vec4(uFogColor.rgb, 0.0); + + // a fragment depth of "1" means the fragment wasn't drawn to, + // we only want to apply Fog to LODs, not to the sky outside the LODs + if (fragmentDepth < 1.0) + { + int fogDebugMode = uFogDebugMode; + if (fogDebugMode == 0) + { + // render fog based on distance from the camera + vec3 vertexWorldPos = calcViewPosition(fragmentDepth); + + float horizontalWorldDistance = length(vertexWorldPos.xz) * uFogScale; + float worldDistance = length(vertexWorldPos.xyz) * uFogScale; + float activeDistance = uUseSphericalFog ? worldDistance : horizontalWorldDistance; + + + // far fog + float farFogThickness = getFarFogThickness(activeDistance); + + // height fog + float heightFogDepth = calculateHeightFogDepth(vertexWorldPos.y); + float heightFogThickness = getHeightFogThickness(heightFogDepth); + + // combined fog + float mixedFogThickness = mixFogThickness(farFogThickness, heightFogThickness); + fragColor.a = clamp(mixedFogThickness, 0.0, 1.0); + } + else if (fogDebugMode == 1) + { + // test code + + // render everything with the fog color + fragColor.a = 1.0; + } + else + { + // test code. + + // this can be fired by manually changing the fullFogMode to a (normally) + // invalid value (like 7). + // By having a separate if statement defined by + // a uniform we don't have to worry about GLSL optimizing away different + // options when testing, causing a bunch of headaches if we just want to render the screen red. + + float depthValue = textureLod(uDhDepthTexture, TexCoord, 0).r; + fragColor.rgb = vec3(depthValue); // Convert depth value to grayscale color + fragColor.a = 1.0; + } + } +} + + + +//================// +// helper methods // +//================// + +vec3 calcViewPosition(float fragmentDepth) +{ + vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); + ndc.xyz = ndc.xyz * 2.0 - 1.0; + + vec4 eyeCoord = uInvMvmProj * ndc; + return eyeCoord.xyz / eyeCoord.w; +} + + + +//=========// +// far fog // +//=========// + +float getFarFogThickness(float dist) +{ + if (uFogFalloffType == 0) // LINEAR + { + return linearFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange); + } + else if (uFogFalloffType == 1) // EXPONENTIAL + { + return exponentialFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange, uFarFogDensity); + } + else // EXPONENTIAL_SQUARED + { + return exponentialSquaredFog(dist, uFarFogStart, uFarFogLength, uFarFogMin, uFarFogRange, uFarFogDensity); + } +} + +float getHeightFogThickness(float dist) +{ + if (!uHeightFogEnabled) + { + return 0.0; + } + + if (uHeightFogFalloffType == 0) // LINEAR + { + return linearFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange); + } + else if (uHeightFogFalloffType == 1) // EXPONENTIAL + { + return exponentialFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange, uHeightFogDensity); + } + else // EXPONENTIAL_SQUARED + { + return exponentialSquaredFog(dist, uHeightFogStart, uHeightFogLength, uHeightFogMin, uHeightFogRange, uHeightFogDensity); + } +} + +float linearFog(float worldDist, float fogStart, float fogLength, float fogMin, float fogRange) +{ + worldDist = (worldDist - fogStart) / fogLength; + worldDist = clamp(worldDist, 0.0, 1.0); + return fogMin + fogRange * worldDist; +} + +float exponentialFog( + float x, float fogStart, float fogLength, + float fogMin, float fogRange, float fogDensity) +{ + x = max((x-fogStart)/fogLength, 0.0) * fogDensity; + return fogMin + fogRange - fogRange/exp(x); +} + +float exponentialSquaredFog( + float x, float fogStart, float fogLength, + float fogMin, float fogRange, float fogDensity) +{ + x = max((x-fogStart)/fogLength, 0.0) * fogDensity; + return fogMin + fogRange - fogRange/exp(x*x); +} + + + +//============// +// height fog // +//============// + +/** 1 = full fog, 0 = no fog */ +float calculateHeightFogDepth(float worldYPos) +{ + // worldYPos -65 - 384 + + + //worldYPos = worldYPos * -1; // negative, fog below height; positive, fog above height + //return worldYPos * uFogVerticalScale; // "* uFogVerticalScale" is done to convert world position to a percent of the world height; + + if (!uHeightFogEnabled) + { + // ignore the height + return 0.0; + } + + + if (!uHeightBasedOnCamera) + { + worldYPos -= (uHeightFogBaseHeight - uCameraBlockYPos); + } + + + if (uHeightFogAppliesDown && uHeightFogAppliesUp) + { + return abs(worldYPos) * uFogVerticalScale; + } + else if (uHeightFogAppliesDown) + { + // apploy fog below given height + return -worldYPos * uFogVerticalScale; + } + else if (uHeightFogAppliesUp) + { + // apply fog above given height + return worldYPos * uFogVerticalScale; + } + else + { + // shouldn't happen, + return 0.0; + } + +} + +float mixFogThickness(float far, float height) +{ + switch (uHeightFogMixingMode) + { + case 0: // BASIC + case 1: // IGNORE_HEIGHT + return far; + + case 2: // MAX + return max(far, height); + + case 3: // ADDITION + return (far + height); + + case 4: // MULTIPLY + return far * height; + + case 5: // INVERSE_MULTIPLY + return (1.0 - (1.0-far)*(1.0-height)); + + case 6: // LIMITED_ADDITION + return (far + max(far, height)); + + case 7: // MULTIPLY_ADDITION + return (far + far*height); + + case 8: // INVERSE_MULTIPLY_ADDITION + return (far + 1.0 - (1.0-far)*(1.0-height)); + + case 9: // AVERAGE + return (far*0.5 + height*0.5); + } + + // shouldn't happen, but default to BASIC / IGNORE_HEIGHT + // if an invalid option is selected + return far; +} + + + diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh new file mode 100644 index 000000000..3f614c123 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh @@ -0,0 +1,15 @@ +#version 150 core + +in vec2 vPosition; + +out vec2 TexCoord; + +/** + * This is specifically used by application shaders. + * IE post process or pixel transfer shaders, anything that is rendered using a single rectangle. + */ +void main() +{ + gl_Position = vec4(vPosition, 1.0, 1.0); + TexCoord = vPosition.xy * 0.5 + 0.5; +} \ No newline at end of file From c3dce412fae3d4247a6852dc1ca64c9a49b83349 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 4 Mar 2026 07:38:49 -0600 Subject: [PATCH 13/46] Add far fade --- .../core/api/internal/ClientApi.java | 6 +- .../core/render/renderer/McLodRenderer.java | 8 +-- .../render/IMcFarFadeRenderer.java | 31 +++++++++ ...derer.java => IMcVanillaFadeRenderer.java} | 3 +- .../distanthorizons/shaders/fade/dh_fade.fsh | 67 +++++++++++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcFadeRenderer.java => IMcVanillaFadeRenderer.java} (88%) create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index bc60eb930..c119e2375 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -38,7 +38,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcFadeRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcVanillaFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; @@ -645,7 +645,7 @@ public class ClientApi */ public void renderFadeOpaque() { - IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + IMcVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcVanillaFadeRenderer.class); if (fadeRenderer == null) { return; @@ -674,7 +674,7 @@ public class ClientApi */ public void renderFadeTransparent() { - IMcFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcFadeRenderer.class); + IMcVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcVanillaFadeRenderer.class); if (fadeRenderer == null) { return; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 701b42ca9..2c5fd540c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -150,6 +150,7 @@ public class McLodRenderer IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class); + IMcFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IMcFarFadeRenderer.class); @@ -205,10 +206,9 @@ public class McLodRenderer // far plane clip fading if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get()) { - //profiler.popPush("Fade Far Clip Fade"); - //DhFadeRenderer.INSTANCE.render( - // new Mat4f(renderParams.mcModelViewMatrix), new Mat4f(renderParams.mcProjectionMatrix), - // renderParams.partialTicks, profiler); + profiler.popPush("Fade Far Clip Fade"); + farFadeRenderer.render( + new Mat4f(renderParams.mcModelViewMatrix), new Mat4f(renderParams.mcProjectionMatrix)); } // fog diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java new file mode 100644 index 000000000..c7df69ff9 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java @@ -0,0 +1,31 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IMcFarFadeRenderer extends IBindable +{ + + void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix); + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java similarity index 88% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java index fd372f4f6..18e49a85b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java @@ -19,12 +19,11 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcFadeRenderer extends IBindable +public interface IMcVanillaFadeRenderer extends IBindable { void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level); diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh new file mode 100644 index 000000000..a88b324c5 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh @@ -0,0 +1,67 @@ +#version 150 core + +in vec2 TexCoord; + +out vec4 fragColor; + +layout (std140) uniform fragUniformBlock +{ + float uStartFadeBlockDistance; + float uEndFadeBlockDistance; + + // inverted model view matrix and projection matrix + mat4 uDhInvMvmProj; +}; + +uniform sampler2D uMcColorTexture; +uniform sampler2D uDhDepthTexture; +uniform sampler2D uDhColorTexture; + + +vec3 calcViewPosition(float fragmentDepth, mat4 invMvmProj) +{ + // normalized device coordinates + vec4 ndc = vec4(TexCoord.xy, fragmentDepth, 1.0); + ndc.xyz = ndc.xyz * 2.0 - 1.0; + + vec4 eyeCoord = invMvmProj * ndc; + return eyeCoord.xyz / eyeCoord.w; +} + +/** + * Used to fade out vanilla chunks so the transition + * between DH and vanilla is smoother. + */ +void main() +{ + // includes both the vanilla chunks as well as DH + vec4 combinedMcDhColor = texture(uMcColorTexture, TexCoord); + // just the DH render pass + vec4 dhColor = texture(uDhColorTexture, TexCoord); + + + + // the DH texture will have white if nothing was written to that pixel. + if (dhColor == vec4(1)) + { + // if not done vanilla clouds will render incorrectly at night + dhColor = combinedMcDhColor; + } + + + float dhFragmentDepth = texture(uDhDepthTexture, TexCoord).r; + vec3 dhVertexWorldPos = calcViewPosition(dhFragmentDepth, uDhInvMvmProj); + float dhFragmentDistance = length(dhVertexWorldPos.xzy); + + + float startFade = uEndFadeBlockDistance; + float endFade = uStartFadeBlockDistance; + + // Smoothly transition between combinedMcDhColor and uDhColorTexture + // as the depth increases from the camera + float fadeStep = smoothstep(startFade, endFade, dhFragmentDistance); + fragColor = mix(combinedMcDhColor, dhColor, fadeStep); + fragColor.a = 1.0; + +} + From 2a554395f78b5872646d6ace51b22992bca233a3 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 4 Mar 2026 18:07:49 -0600 Subject: [PATCH 14/46] debug rendering --- .../core/api/internal/ClientApi.java | 16 + .../core/render/QuadTree/LodQuadTree.java | 1 - .../core/render/renderer/DebugRenderer.java | 295 ++++++++++-------- .../core/render/renderer/LodRenderer.java | 2 +- .../core/render/renderer/McLodRenderer.java | 12 +- .../render/IMcDebugRenderer.java | 33 ++ .../distanthorizons/shaders/debug/frag.fsh | 14 + .../distanthorizons/shaders/debug/vert.vsh | 14 + 8 files changed, 246 insertions(+), 141 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh create mode 100644 core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index c119e2375..b07040735 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -421,6 +421,22 @@ public class ClientApi + //===========// + // debugging // + //===========// + //region + + //DhApiTerrainDataRepo.asyncDebugMethod( + // RENDER_STATE.clientLevelWrapper, + // MC_CLIENT.getPlayerBlockPos().getX(), + // MC_CLIENT.getPlayerBlockPos().getY(), + // MC_CLIENT.getPlayerBlockPos().getZ() + //); + + //endregion + + + //=====================// // render thread tasks // //=====================// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java index 0e06c6c5e..c1108f6fa 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java @@ -36,7 +36,6 @@ import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.WorldGenUtil; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java index 10f1e8b42..69d64ce3c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java @@ -19,7 +19,6 @@ package com.seibel.distanthorizons.core.render.renderer; -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.types.ConfigEntry; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; @@ -29,21 +28,19 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.math.Vec3f; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL32; import java.awt.*; import java.lang.ref.WeakReference; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; import java.util.concurrent.PriorityBlockingQueue; /** @@ -66,13 +63,12 @@ public class DebugRenderer // rendering setup private ShaderProgram basicShader; - //private GLVertexBuffer vertexBuffer; private GLElementBuffer outlineIndexBuffer; private AbstractVertexAttribute va; private boolean init = false; // used when rendering - private Mat4f transformationMatrixThisFrame; + private Mat4f dhMvmProjMatrixThisFrame; private Vec3f camPosFloatThisFrame; @@ -81,39 +77,39 @@ public class DebugRenderer - /** A box from 0,0,0 to 1,1,1 */ - private static final float[] BOX_VERTICES = { - //region - // Pos x y z - 0, 0, 0, - 1, 0, 0, - 1, 1, 0, - 0, 1, 0, - 0, 0, 1, - 1, 0, 1, - 1, 1, 1, - 0, 1, 1, - //endregion - }; - - private static final int[] BOX_OUTLINE_INDICES = { - //region - 0, 1, - 1, 2, - 2, 3, - 3, 0, - - 4, 5, - 5, 6, - 6, 7, - 7, 4, - - 0, 4, - 1, 5, - 2, 6, - 3, 7, - //endregion - }; + ///** A box from 0,0,0 to 1,1,1 */ + //private static final float[] BOX_VERTICES = { + // //region + // // Pos x y z + // 0, 0, 0, + // 1, 0, 0, + // 1, 1, 0, + // 0, 1, 0, + // 0, 0, 1, + // 1, 0, 1, + // 1, 1, 1, + // 0, 1, 1, + // //endregion + //}; + // + //private static final int[] BOX_OUTLINE_INDICES = { + // //region + // 0, 1, + // 1, 2, + // 2, 3, + // 3, 0, + // + // 4, 5, + // 5, 6, + // 6, 7, + // 7, 4, + // + // 0, 4, + // 1, 5, + // 2, 6, + // 3, 7, + // //endregion + //}; @@ -124,48 +120,45 @@ public class DebugRenderer private DebugRenderer() { } - public void init() - { - if (this.init) - { - return; - } - this.init = true; - - this.va = AbstractVertexAttribute.create(); - this.va.bind(); - // Pos - this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false)); - this.va.completeAndCheck(Float.BYTES * 3); - this.basicShader = new ShaderProgram( - "shaders/debug/vert.vert", - "shaders/debug/frag.frag", - "vPosition" - ); - this.createBuffer(); - } - - private void createBuffer() - { - // box vertices - ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES); - boxVerticesBuffer.order(ByteOrder.nativeOrder()); - boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); - boxVerticesBuffer.rewind(); - //this.vertexBuffer = new GLVertexBuffer(false); - //this.vertexBuffer.bind(); - //this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); - - - // outline vertex indexes - ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES); - boxOutlineBuffer.order(ByteOrder.nativeOrder()); - boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES); - boxOutlineBuffer.rewind(); - this.outlineIndexBuffer = new GLElementBuffer(false); - this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW); - - } + //public void init() + //{ + // if (this.init) + // { + // return; + // } + // this.init = true; + // + // this.va = AbstractVertexAttribute.create(); + // this.va.bind(); + // // Pos + // this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false)); + // this.va.completeAndCheck(Float.BYTES * 3); + // this.basicShader = new ShaderProgram( + // "shaders/debug/vert.vert", + // "shaders/debug/frag.frag", + // "vPosition" + // ); + // this.createBuffer(); + //} + // + //private void createBuffer() + //{ + // // box vertices + // ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES); + // boxVerticesBuffer.order(ByteOrder.nativeOrder()); + // boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); + // boxVerticesBuffer.rewind(); + // + // + // // outline vertex indexes + // ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES); + // boxOutlineBuffer.order(ByteOrder.nativeOrder()); + // boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES); + // boxOutlineBuffer.rewind(); + // this.outlineIndexBuffer = new GLElementBuffer(false); + // this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW); + // + //} //endregion @@ -201,60 +194,100 @@ public class DebugRenderer //===========// //region - public void render(Mat4f transform) + public void render(RenderParams renderEventParam) { - this.transformationMatrixThisFrame = transform; - Vec3d camPos = MC_RENDER.getCameraExactPosition(); - this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); + //this.dhMvmProjMatrixThisFrame = dhMvmProjMatrix; + //Vec3d camPos = MC_RENDER.getCameraExactPosition(); + //this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); + + //this.init(); + + //GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); + //GLMC.enableDepthTest(); + // + //this.basicShader.bind(); + //this.va.bind(); + // + // + //this.outlineIndexBuffer.bind(); + this.rendererLists.render(this); + + + // particle rendering + BoxParticle head = null; + while ((head = this.particles.poll()) != null && head.isDead()) + { /* remove dead particles */ } + if (head != null) + { + // re-add the popped off head + this.particles.add(head); + } - this.init(); + IMcDebugRenderer renderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); + renderer.render(renderEventParam, this.particles); - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); - GLMC.enableDepthTest(); - - this.basicShader.bind(); - this.va.bind(); - //this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId()); - - - this.outlineIndexBuffer.bind(); - this.rendererLists.render(this); - - - // particle rendering - BoxParticle head = null; - while ((head = this.particles.poll()) != null && head.isDead()) - { /* remove dead particles */ } - if (head != null) - { - // re-add the popped off head - this.particles.add(head); - } - - - // box rendering - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - for (BoxParticle particle : this.particles) - { - // a new box is created each time since the height will be different based on the time it's lived - this.renderBox(particle.createNewRenderBox()); - } } + @Deprecated // TODO this should add all the boxes to a list so we can render them as a batch instead of individual draw calls public void renderBox(Box box) { - Mat4f boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z); - boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z)); - - Mat4f transformMatrix = this.transformationMatrixThisFrame.copy(); - transformMatrix.multiply(boxTransform); - this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix); - - this.basicShader.setUniform(this.basicShader.getUniformLocation("uColor"), box.color); - - GL32.glDrawElements(GL32.GL_LINES, BOX_OUTLINE_INDICES.length, GL32.GL_UNSIGNED_INT, 0); + IMcDebugRenderer renderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); + renderer.render(box); } + //public void render(Mat4f dhMvmProjMatrix) + //{ + // this.dhMvmProjMatrixThisFrame = dhMvmProjMatrix; + // Vec3d camPos = MC_RENDER.getCameraExactPosition(); + // this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); + // + // this.init(); + // + // GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); + // GLMC.enableDepthTest(); + // + // this.basicShader.bind(); + // this.va.bind(); + // + // + // this.outlineIndexBuffer.bind(); + // this.rendererLists.render(this); + // + // + // // particle rendering + // BoxParticle head = null; + // while ((head = this.particles.poll()) != null && head.isDead()) + // { /* remove dead particles */ } + // if (head != null) + // { + // // re-add the popped off head + // this.particles.add(head); + // } + // + // + // // box rendering + // GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); + // for (BoxParticle particle : this.particles) + // { + // // a new box is created each time since the height will be different based on the time it's lived + // this.renderBox(particle.createNewRenderBox()); + // } + //} + // + //public void renderBox(Box box) + //{ + // Mat4f boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z); + // boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z)); + // + // Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy(); + // transformMatrix.multiply(boxTransform); + // this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix); + // + // this.basicShader.setUniform(this.basicShader.getUniformLocation("uColor"), box.color); + // + // GL32.glDrawElements(GL32.GL_LINES, BOX_OUTLINE_INDICES.length, GL32.GL_UNSIGNED_INT, 0); + //} + //endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index c1adfda11..ce6212a80 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -298,7 +298,7 @@ public class LodRenderer combinedMatrix.multiply(renderParams.dhModelViewMatrix); // Note: this can be very slow if a lot of boxes are being rendered - DebugRenderer.INSTANCE.render(combinedMatrix); + //DebugRenderer.INSTANCE.render(combinedMatrix); // TODO } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 2c5fd540c..501b2e9cf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -28,7 +28,6 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; @@ -232,13 +231,10 @@ public class McLodRenderer if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get()) { - //profiler.popPush("Debug wireframes"); - // - //Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - //combinedMatrix.multiply(renderParams.dhModelViewMatrix); - // - //// Note: this can be very slow if a lot of boxes are being rendered - //DebugRenderer.INSTANCE.render(combinedMatrix); + profiler.popPush("Debug wireframes"); + + // Note: this can be very slow if a lot of boxes are being rendered + DebugRenderer.INSTANCE.render(renderParams); } lodRenderer.applyToMcTexture(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java new file mode 100644 index 000000000..01e59399a --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java @@ -0,0 +1,33 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +import java.util.Collection; + +public interface IMcDebugRenderer extends IBindable +{ + void render(RenderParams renderEventParam, Collection boxCollection); + void render(DebugRenderer.Box box); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh new file mode 100644 index 000000000..253b92fd5 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh @@ -0,0 +1,14 @@ +#version 150 core + +layout (std140) uniform uniformBlock +{ + mat4 uTransform; + vec4 uColor; +}; + +out vec4 fragColor; + +void main() +{ + fragColor = uColor; +} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh new file mode 100644 index 000000000..7ff5df869 --- /dev/null +++ b/core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh @@ -0,0 +1,14 @@ +#version 150 core + +layout (std140) uniform uniformBlock +{ + mat4 uTransform; + vec4 uColor; +}; + +in vec3 vPosition; + +void main() +{ + gl_Position = uTransform * vec4(vPosition, 1.0); +} \ No newline at end of file From 40703db76323a6eb132a9c794971278aad4bd36e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 5 Mar 2026 07:22:22 -0600 Subject: [PATCH 15/46] uncomment deferred rendering --- .../core/render/renderer/McLodRenderer.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index 501b2e9cf..cedc83658 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -242,28 +242,28 @@ public class McLodRenderer } else { - ////====================// - //// deferred rendering // - ////====================// - // - //if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) - //{ - // profiler.popPush("LOD Transparent"); - // this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ false); - // - // - // if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() - // // this is done to fix issues with: underwater fog, blindness effect, etc. - // || renderParams.vanillaFogEnabled) - // { - // profiler.popPush("LOD Fog"); - // - // Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - // combinedMatrix.multiply(renderParams.dhModelViewMatrix); - // - // FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); - // } - //} + //====================// + // deferred rendering // + //====================// + + if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) + { + profiler.popPush("LOD Transparent"); + this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); + + + if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() + // this is done to fix issues with: underwater fog, blindness effect, etc. + || renderParams.vanillaFogEnabled) + { + profiler.popPush("LOD Fog"); + + Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); + combinedMatrix.multiply(renderParams.dhModelViewMatrix); + + FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); + } + } } From d3f28f064b9966a9527ffe584662b221fb92e6b6 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 5 Mar 2026 07:23:02 -0600 Subject: [PATCH 16/46] fix chunk update queue count flipped --- .../api/internal/chunkUpdating/WorldChunkUpdateManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/chunkUpdating/WorldChunkUpdateManager.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/chunkUpdating/WorldChunkUpdateManager.java index 4a1cfc54b..35e3cc514 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/chunkUpdating/WorldChunkUpdateManager.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/chunkUpdating/WorldChunkUpdateManager.java @@ -168,7 +168,7 @@ public class WorldChunkUpdateManager // replace the first line with the number of total/active queues // (helpful if we need to diagnose a leak due to a massive number of queue level wrappers) - stringList.set(0, "Chunk Update Queues: "+totalQueueCountRef.get()+"/"+activeQueueCountRef.get()); + stringList.set(0, "Chunk Update Queues: "+activeQueueCountRef.get()+"/"+totalQueueCountRef.get()); return stringList; } From 0f539f3a6f9ca370dab13c51115e6708211f7fc9 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 5 Mar 2026 17:32:19 -0600 Subject: [PATCH 17/46] start separating out uniform logic --- .../bufferBuilding/LodBufferContainer.java | 8 +++++ .../core/render/renderer/McLodRenderer.java | 22 ++----------- .../wrapperInterfaces/IWrapperFactory.java | 3 ++ .../ILodContainerUniformBufferWrapper.java | 28 +++++++++++++++++ .../render/IMcLodRenderer.java | 4 ++- .../render/IUniformBufferWrapper.java | 31 +++++++++++++++++++ .../distanthorizons/shaders/lod/vert.vsh | 9 ++++-- 7 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index 0a8ecf4a9..c963b2132 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -28,7 +28,9 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import org.lwjgl.system.MemoryUtil; @@ -46,6 +48,8 @@ public class LodBufferContainer implements AutoCloseable { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); + /** number of bytes a single quad takes */ public static final int QUADS_BYTE_SIZE = LodUtil.DH_VERTEX_FORMAT.getByteSize() * 4; /** how big a single VBO can be in bytes */ @@ -63,6 +67,8 @@ public class LodBufferContainer implements AutoCloseable public IVertexBufferWrapper[] vbos; public IVertexBufferWrapper[] vbosTransparent; + public ILodContainerUniformBufferWrapper uniforms = WRAPPER_FACTORY.createLodContainerUniformWrapper(); + private final AtomicReference> uploadFutureRef = new AtomicReference<>(null); @@ -305,6 +311,8 @@ public class LodBufferContainer implements AutoCloseable buffer.close(); } } + + this.uniforms.close(); }); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java index cedc83658..a3930e327 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java @@ -237,6 +237,7 @@ public class McLodRenderer DebugRenderer.INSTANCE.render(renderParams); } + profiler.popPush("Apply to MC"); lodRenderer.applyToMcTexture(); } @@ -307,26 +308,7 @@ public class McLodRenderer SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); if (lodBufferContainer != null) { - for (int lodIndex = 0; lodIndex < lodBufferContainer.size(); lodIndex++) - { - LodBufferContainer bufferContainer = lodBufferContainer.get(lodIndex); - // TODO match buffer builder debugger - //if (bufferContainer.pos != DhSectionPos.encode((byte)6, 1,0)) - //{ - // continue; - //} - - Vec3d camPos = renderEventParam.exactCameraPosition; - Vec3f modelPos = new Vec3f( - (float) (bufferContainer.minCornerBlockPos.getX() - camPos.x), - (float) (bufferContainer.minCornerBlockPos.getY() - camPos.y), - (float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z)); - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos)); - - IVertexBufferWrapper[] vbos = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent; - lodRenderer.render(renderEventParam, opaquePass, modelPos, vbos, profilerWrapper); - } + lodRenderer.render(renderEventParam, opaquePass, lodBufferContainer, profilerWrapper); } } else diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index 200a83aa4..0f99327d7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -24,7 +24,9 @@ import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.render.renderer.generic.IInstancedVboContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; @@ -108,6 +110,7 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable IVertexBufferWrapper createVboWrapper(); + ILodContainerUniformBufferWrapper createLodContainerUniformWrapper(); IInstancedVboContainer createInstancedVboContainer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java new file mode 100644 index 000000000..6eedda0e2 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java @@ -0,0 +1,28 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; + +public interface ILodContainerUniformBufferWrapper extends IUniformBufferWrapper +{ + void createBufferData(RenderParams renderEventParam, LodBufferContainer bufferContainer); +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java index 681deac04..075c77e96 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -20,7 +20,9 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; +import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; @@ -28,7 +30,7 @@ public interface IMcLodRenderer extends IBindable { void render( RenderParams renderEventParam, boolean opaquePass, - DhApiVec3f modelPos, IVertexBufferWrapper[] bufferList, + SortedArraySet bufferContainers, IProfilerWrapper profiler); int getVertexSize(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java new file mode 100644 index 000000000..feb41fd72 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java @@ -0,0 +1,31 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public interface IUniformBufferWrapper extends IBindable, AutoCloseable +{ + void upload(); + + @Override + void close(); + +} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh index 56d3b60e9..3b5fdf531 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh @@ -11,7 +11,12 @@ out vec4 vertexColor; out vec3 vertexWorldPos; out float vertexYPos; -layout (std140) uniform vertUniformBlock +layout (std140) uniform vertUniqueUniformBlock +{ + vec3 uModelOffset; +}; + +layout (std140) uniform vertSharedUniformBlock { bool uIsWhiteWorld; @@ -19,8 +24,6 @@ layout (std140) uniform vertUniformBlock float uMircoOffset; float uEarthRadius; - vec3 uModelOffset; - mat4 uCombinedMatrix; }; From e790bfb7e8ed309a0f1a490b4fd4a74e05db5ca7 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 7 Mar 2026 14:32:02 -0600 Subject: [PATCH 18/46] merge apply shaders --- .../assets/distanthorizons/shaders/apply/frag.fsh | 10 ++++------ .../assets/distanthorizons/shaders/apply/vert.vsh | 5 ++++- .../assets/distanthorizons/shaders/ssao/apply.fsh | 12 ++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh index c5a5d3635..2b0745aec 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh @@ -4,22 +4,20 @@ in vec2 TexCoord; out vec4 fragColor; -uniform sampler2D uDhColorTexture; -uniform sampler2D uDhDepthTexture; +uniform sampler2D uSourceColorTexture; +uniform sampler2D uSourceDepthTexture; // DH apply frag void main() { - //fragColor = texture(uApplyTexture, TexCoord); - fragColor = vec4(0.0); // a fragment depth of "1" means the fragment wasn't drawn to, // only update fragments that were drawn to - float fragmentDepth = texture(uDhDepthTexture, TexCoord).r; + float fragmentDepth = texture(uSourceDepthTexture, TexCoord).r; if (fragmentDepth != 1) { - fragColor = texture(uDhColorTexture, TexCoord); + fragColor = texture(uSourceColorTexture, TexCoord); } else { diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh index 09789a24b..f58a25234 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh @@ -4,7 +4,10 @@ in vec2 vPosition; out vec2 TexCoord; -// DH apply +/** + * This is specifically used by application shaders. + * IE post process or pixel transfer shaders, anything that is rendered using a single rectangle. + */ void main() { gl_Position = vec4(vPosition, 0.0, 1.0); diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh index dc48356f3..00a404cda 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh @@ -4,8 +4,8 @@ in vec2 TexCoord; out vec4 fragColor; -uniform sampler2D uSsaoColorTexture; -uniform sampler2D uDhDepthTexture; +uniform sampler2D uSourceColorTexture; +uniform sampler2D uSourceDepthTexture; uniform vec2 gViewSize; uniform int gBlurRadius; @@ -38,8 +38,8 @@ float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, float fx = Gaussian(g_sigmaX, ix); vec2 sampleTex = texcoord + ivec2(ix, iy) * pixelSize; - float sampleValue = textureLod(uSsaoColorTexture, sampleTex, 0).r; - float sampleDepth = textureLod(uDhDepthTexture, sampleTex, 0).r; + float sampleValue = textureLod(uSourceColorTexture, sampleTex, 0).r; + float sampleDepth = textureLod(uSourceDepthTexture, sampleTex, 0).r; float sampleLinearDepth = linearizeDepth(sampleDepth); float depthDiff = abs(sampleLinearDepth - linearDepth); @@ -60,7 +60,7 @@ void main() { fragColor = vec4(1.0); - float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; + float fragmentDepth = textureLod(uSourceDepthTexture, TexCoord, 0).r; // a fragment depth of "1" means the fragment wasn't drawn to, // we only want to apply SSAO to LODs, not to the sky outside the LODs @@ -73,7 +73,7 @@ void main() } else { - fragColor.a = texelFetch(uSsaoColorTexture, ivec2(gl_FragCoord.xy), 0).r; + fragColor.a = texelFetch(uSourceColorTexture, ivec2(gl_FragCoord.xy), 0).r; } } } From a5a9a62e8926be4c18049c0774c9796a31fb2d0f Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 8 Mar 2026 21:14:48 -0500 Subject: [PATCH 19/46] Fix ssao application --- .../distanthorizons/shaders/ssao/apply.fsh | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh index 00a404cda..ecc9ba828 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh @@ -7,39 +7,43 @@ out vec4 fragColor; uniform sampler2D uSourceColorTexture; uniform sampler2D uSourceDepthTexture; -uniform vec2 gViewSize; -uniform int gBlurRadius; -uniform float gNear; -uniform float gFar; +layout (std140) uniform applyFragUniformBlock +{ + vec2 uViewSize; + int uBlurRadius; + float uNearClipPlane; // in blocks + float uFarClipPlane; // in blocks +}; -float linearizeDepth(const in float depth) { - return (gNear * gFar) / (depth * (gNear - gFar) + gFar); -} +float linearizeDepth(const in float depth) { return (uNearClipPlane * uFarClipPlane) / (depth * (uNearClipPlane - uFarClipPlane) + uFarClipPlane); } -float Gaussian(const in float sigma, const in float x) { - return exp(-(x*x) / (2.0 * (sigma*sigma))); -} +float Gaussian(const in float sigma, const in float x) { return exp(-(x*x) / (2.0 * (sigma*sigma))); } -float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, const in float g_sigmaV) { +float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, const in float g_sigmaV) +{ float g_sigmaX = 1.6; float g_sigmaY = 1.6; - int radius = clamp(gBlurRadius, 1, 3); + int radius = clamp(uBlurRadius, 1, 3); - vec2 pixelSize = 1.0 / gViewSize; + vec2 pixelSize = 1.0 / uViewSize; float accum = 0.0; float total = 0.0; - for (int iy = -radius; iy <= radius; iy++) { + for (int iy = -radius; iy <= radius; iy++) + { float fy = Gaussian(g_sigmaY, iy); - for (int ix = -radius; ix <= radius; ix++) { + for (int ix = -radius; ix <= radius; ix++) + { float fx = Gaussian(g_sigmaX, ix); - vec2 sampleTex = texcoord + ivec2(ix, iy) * pixelSize; - float sampleValue = textureLod(uSourceColorTexture, sampleTex, 0).r; - float sampleDepth = textureLod(uSourceDepthTexture, sampleTex, 0).r; + vec2 sampleTexCoord = texcoord + ivec2(ix, iy) * pixelSize; + + float sampleValue = textureLod(uSourceColorTexture, sampleTexCoord, 0).r; + + float sampleDepth = textureLod(uSourceDepthTexture, sampleTexCoord, 0).r; float sampleLinearDepth = linearizeDepth(sampleDepth); float depthDiff = abs(sampleLinearDepth - linearDepth); @@ -51,7 +55,10 @@ float BilateralGaussianBlur(const in vec2 texcoord, const in float linearDepth, } } - if (total <= 1.e-4) return 1.0; + if (total <= 1.e-4) + { + return 1.0; + } return accum / total; } @@ -66,7 +73,7 @@ void main() // we only want to apply SSAO to LODs, not to the sky outside the LODs if (fragmentDepth < 1) { - if (gBlurRadius > 0) + if (uBlurRadius > 0) { float fragmentDepthLinear = linearizeDepth(fragmentDepth); fragColor.a = BilateralGaussianBlur(TexCoord, fragmentDepthLinear, 1.6); From bd833ba5106e2b1963e64c249b6e606e596d4367 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 09:57:03 -0500 Subject: [PATCH 20/46] move blaze shader files --- .../shaders/apply/{ => blaze}/frag.fsh | 0 .../shaders/apply/{ => blaze}/vert.vsh | 0 .../shaders/copy/{ => blaze}/frag.fsh | 0 .../shaders/copy/{ => blaze}/vert.vsh | 0 .../shaders/debug/{ => blaze}/frag.fsh | 0 .../shaders/debug/{ => blaze}/vert.vsh | 0 .../shaders/fade/{ => blaze}/dh_fade.fsh | 0 .../shaders/fade/{ => blaze}/vanilla_fade.fsh | 0 .../shaders/fade/{ => blaze}/vert.vsh | 0 .../distanthorizons/shaders/fog/apply.fsh | 27 ------------------- .../shaders/fog/{fog.fsh => blaze/frag.fsh} | 0 .../fog/{quad_apply.vsh => blaze/vert.vsh} | 0 .../shaders/generic/{ => blaze}/frag.fsh | 0 .../shaders/generic/{ => blaze}/vert.vsh | 0 .../shaders/lod/{ => blaze}/frag.fsh | 0 .../shaders/lod/{ => blaze}/vert.vsh | 0 .../shaders/ssao/{ => blaze}/apply.fsh | 0 .../shaders/ssao/{ao.fsh => blaze/frag.fsh} | 0 .../{quadApply.vsh => ssao/blaze/vert.vsh} | 0 .../shaders/ssao/quad_apply.vsh | 15 ----------- .../shaders/test/{ => blaze}/frag.fsh | 0 .../shaders/test/{ => blaze}/vert.vsh | 0 22 files changed, 42 deletions(-) rename core/src/main/resources/assets/distanthorizons/shaders/apply/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/apply/{ => blaze}/vert.vsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/copy/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/copy/{ => blaze}/vert.vsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/debug/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/debug/{ => blaze}/vert.vsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/fade/{ => blaze}/dh_fade.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/fade/{ => blaze}/vanilla_fade.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/fade/{ => blaze}/vert.vsh (100%) delete mode 100644 core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh rename core/src/main/resources/assets/distanthorizons/shaders/fog/{fog.fsh => blaze/frag.fsh} (100%) rename core/src/main/resources/assets/distanthorizons/shaders/fog/{quad_apply.vsh => blaze/vert.vsh} (100%) rename core/src/main/resources/assets/distanthorizons/shaders/generic/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/generic/{ => blaze}/vert.vsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/lod/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/lod/{ => blaze}/vert.vsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/ssao/{ => blaze}/apply.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/ssao/{ao.fsh => blaze/frag.fsh} (100%) rename core/src/main/resources/assets/distanthorizons/shaders/{quadApply.vsh => ssao/blaze/vert.vsh} (100%) delete mode 100644 core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh rename core/src/main/resources/assets/distanthorizons/shaders/test/{ => blaze}/frag.fsh (100%) rename core/src/main/resources/assets/distanthorizons/shaders/test/{ => blaze}/vert.vsh (100%) diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/apply/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/apply/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/apply/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/copy/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/copy/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/copy/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/copy/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/copy/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/copy/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/debug/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/debug/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/debug/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/debug/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/debug/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/debug/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fade/dh_fade.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/dh_fade.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vanilla_fade.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fade/vanilla_fade.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vanilla_fade.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fade/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/fade/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh deleted file mode 100644 index c9316b8ee..000000000 --- a/core/src/main/resources/assets/distanthorizons/shaders/fog/apply.fsh +++ /dev/null @@ -1,27 +0,0 @@ -#version 150 core - -in vec2 TexCoord; - -out vec4 fragColor; - -uniform sampler2D uColorTexture; -uniform sampler2D uDhDepthTexture; - - -/** - * Fog application shader - * - * This merges the rendered fog onto DH's rendered LODs - */ -void main() -{ - fragColor = vec4(0.0); - - // a fragment depth of "1" means the fragment wasn't drawn to, - // only update fragments that were drawn to - float fragmentDepth = textureLod(uDhDepthTexture, TexCoord, 0).r; - if (fragmentDepth != 1) - { - fragColor = texture(uColorTexture, TexCoord); - } -} diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fog/fog.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/fog/quad_apply.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/fog/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/generic/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/generic/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/generic/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/lod/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/lod/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/apply.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/ssao/apply.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/apply.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/ssao/ao.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/quadApply.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/ssao/blaze/vert.vsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh b/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh deleted file mode 100644 index 3f614c123..000000000 --- a/core/src/main/resources/assets/distanthorizons/shaders/ssao/quad_apply.vsh +++ /dev/null @@ -1,15 +0,0 @@ -#version 150 core - -in vec2 vPosition; - -out vec2 TexCoord; - -/** - * This is specifically used by application shaders. - * IE post process or pixel transfer shaders, anything that is rendered using a single rectangle. - */ -void main() -{ - gl_Position = vec4(vPosition, 1.0, 1.0); - TexCoord = vPosition.xy * 0.5 + 0.5; -} \ No newline at end of file diff --git a/core/src/main/resources/assets/distanthorizons/shaders/test/frag.fsh b/core/src/main/resources/assets/distanthorizons/shaders/test/blaze/frag.fsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/test/frag.fsh rename to core/src/main/resources/assets/distanthorizons/shaders/test/blaze/frag.fsh diff --git a/core/src/main/resources/assets/distanthorizons/shaders/test/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/test/blaze/vert.vsh similarity index 100% rename from core/src/main/resources/assets/distanthorizons/shaders/test/vert.vsh rename to core/src/main/resources/assets/distanthorizons/shaders/test/blaze/vert.vsh From a8c15d22c34df7fe12ada0eb8853867bc7aaa5f8 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 11:16:50 -0500 Subject: [PATCH 21/46] rename vbo containers --- .../bufferBuilding/LodBufferContainer.java | 3 +-- .../renderer/generic/GenericObjectRenderer.java | 4 ++-- ...=> IGenericObjectVertexBufferContainer.java} | 4 +++- ...> NativeGlGenericObjectVertexContainer.java} | 4 ++-- .../renderer/generic/RenderableBoxGroup.java | 17 ++++++++--------- .../core/wrapperInterfaces/IWrapperFactory.java | 8 +++----- .../render/IVertexBufferWrapper.java | 2 -- 7 files changed, 19 insertions(+), 23 deletions(-) rename core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/{IInstancedVboContainer.java => IGenericObjectVertexBufferContainer.java} (86%) rename core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/{InstancedVboContainer.java => NativeGlGenericObjectVertexContainer.java} (96%) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index c963b2132..1d71b7812 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -30,7 +30,6 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import org.lwjgl.system.MemoryUtil; @@ -218,7 +217,7 @@ public class LodBufferContainer implements AutoCloseable // get or create the VBO if (vbos[vboIndex] == null) { - vbos[vboIndex] = SingletonInjector.INSTANCE.get(IWrapperFactory.class).createVboWrapper(); + vbos[vboIndex] = SingletonInjector.INSTANCE.get(IWrapperFactory.class).createVboWrapper("distantHorizons:McLodRenderer"); } IVertexBufferWrapper vbo = vbos[vboIndex]; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java index 8e3ea5488..9e4c390e5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java @@ -475,7 +475,7 @@ public class GenericObjectRenderer implements IMcGenericRenderer boxGroup.tryUpdateInstancedDataAsync(); // skip groups that haven't been uploaded yet - if (boxGroup.instancedVbos.getState() != InstancedVboContainer.EState.RENDER) + if (boxGroup.instancedVbos.getState() != NativeGlGenericObjectVertexContainer.EState.RENDER) { continue; } @@ -557,7 +557,7 @@ public class GenericObjectRenderer implements IMcGenericRenderer // Bind instance data // profiler.popPush("binding"); - InstancedVboContainer container = (InstancedVboContainer)(boxGroup.instancedVbos); + NativeGlGenericObjectVertexContainer container = (NativeGlGenericObjectVertexContainer)(boxGroup.instancedVbos); GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color); GL32.glEnableVertexAttribArray(1); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java similarity index 86% rename from core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java rename to core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java index 7a8a45935..b627a5263 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IInstancedVboContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java @@ -4,7 +4,7 @@ import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; import java.util.List; -public interface IInstancedVboContainer extends AutoCloseable +public interface IGenericObjectVertexBufferContainer extends AutoCloseable { void uploadDataToGpu(); @@ -35,4 +35,6 @@ public interface IInstancedVboContainer extends AutoCloseable //endregion + + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java similarity index 96% rename from core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java rename to core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java index ff3b1aef9..870614b2c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/InstancedVboContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java @@ -17,7 +17,7 @@ import java.util.List; * * @see RenderableBoxGroup */ -public class InstancedVboContainer implements IInstancedVboContainer +public class NativeGlGenericObjectVertexContainer implements IGenericObjectVertexBufferContainer { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); @@ -120,7 +120,7 @@ public class InstancedVboContainer implements IInstancedVboContainer this.materialData[i] = box.material; } - this.state = InstancedVboContainer.EState.READY_TO_UPLOAD; + this.state = NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD; } public void uploadDataToGpu() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java index 43365da5d..d96a776f4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java @@ -17,7 +17,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLW import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import org.jetbrains.annotations.Nullable; -import java.awt.*; import java.io.Closeable; import java.util.*; import java.util.List; @@ -69,9 +68,9 @@ public class RenderableBoxGroup public Consumer afterRenderFunc; // instance data - public IInstancedVboContainer instancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); + public IGenericObjectVertexBufferContainer instancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); /** double buffering for thread safety and to prevent locking the render thread during update */ - private IInstancedVboContainer altInstancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); + private IGenericObjectVertexBufferContainer altInstancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); @@ -197,12 +196,12 @@ public class RenderableBoxGroup public void tryUpdateInstancedDataAsync() { // if the alt container is done, swap it in - if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.READY_TO_UPLOAD) + if (this.altInstancedVbos.getState() == NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD) { this.altInstancedVbos.uploadDataToGpu(); // swap VBO references for rendering - IInstancedVboContainer temp = this.instancedVbos; + IGenericObjectVertexBufferContainer temp = this.instancedVbos; this.instancedVbos = this.altInstancedVbos; this.altInstancedVbos = temp; @@ -226,11 +225,11 @@ public class RenderableBoxGroup } // if the alternate container is already updating, don't double-queue it - if (this.altInstancedVbos.getState() == InstancedVboContainer.EState.UPDATING_DATA) + if (this.altInstancedVbos.getState() == NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA) { return; } - this.altInstancedVbos.setState(InstancedVboContainer.EState.UPDATING_DATA); + this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA); @@ -254,14 +253,14 @@ public class RenderableBoxGroup catch (Exception e) { LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e); - this.altInstancedVbos.setState(InstancedVboContainer.EState.ERROR); + this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.ERROR); } }); } catch (RejectedExecutionException ignore) { // the executor was shut down, it should be back up shortly and able to accept new jobs - this.altInstancedVbos.setState(InstancedVboContainer.EState.NEW); + this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.NEW); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index 0f99327d7..6cf1f48c0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -21,12 +21,11 @@ package com.seibel.distanthorizons.core.wrapperInterfaces; import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.render.renderer.generic.IInstancedVboContainer; +import com.seibel.distanthorizons.core.render.renderer.generic.IGenericObjectVertexBufferContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; @@ -35,7 +34,6 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import java.io.IOException; -import java.util.HashSet; /** * This handles creating abstract wrapper objects. @@ -109,10 +107,10 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable - IVertexBufferWrapper createVboWrapper(); + IVertexBufferWrapper createVboWrapper(String name); ILodContainerUniformBufferWrapper createLodContainerUniformWrapper(); - IInstancedVboContainer createInstancedVboContainer(); + IGenericObjectVertexBufferContainer createInstancedVboContainer(); IMcGenericRenderer createGenericRenderer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java index 24ea0bd11..ce2b74a36 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java @@ -30,6 +30,4 @@ public interface IVertexBufferWrapper extends IBindable, AutoCloseable @Override void close(); - int getVertexCount(); - } From fee0aadcbe9d82b9cf6e210b90beb6e08e4ffe44 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 12:19:53 -0500 Subject: [PATCH 22/46] MC -> blaze renaming --- .../core/api/internal/ClientApi.java | 51 +++++++++++-------- .../core/render/DhApiRenderProxy.java | 6 +-- .../core/render/RenderBufferHandler.java | 4 +- ...LodRenderer.java => BlazeLodRenderer.java} | 27 +++------- .../core/render/renderer/DhFadeRenderer.java | 2 +- .../render/renderer/VanillaFadeRenderer.java | 2 +- .../renderer/shaders/DhApplyShader.java | 14 ++--- .../render/renderer/shaders/DhFadeShader.java | 6 +-- .../renderer/shaders/FogApplyShader.java | 6 +-- .../render/renderer/shaders/FogShader.java | 4 +- .../renderer/shaders/SSAOApplyShader.java | 6 +-- .../render/renderer/shaders/SSAOShader.java | 4 +- .../renderer/shaders/VanillaFadeShader.java | 6 +-- .../distanthorizons/core/util/RenderUtil.java | 9 ++-- .../render/IMcFarFadeRenderer.java | 3 +- 15 files changed, 73 insertions(+), 77 deletions(-) rename core/src/main/java/com/seibel/distanthorizons/core/render/renderer/{McLodRenderer.java => BlazeLodRenderer.java} (92%) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index b07040735..2a9eb17ad 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -75,6 +75,7 @@ import java.util.concurrent.ThreadPoolExecutor; public class ClientApi { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + private static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder().maxCountPerSecond(1).build(); public static final ClientApi INSTANCE = new ClientApi(); @@ -503,12 +504,6 @@ public class ClientApi ///endregion - IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); - if (testRenderer == null) - { - return; - } - @@ -596,34 +591,46 @@ public class ClientApi try { // render pass // - - if (!renderingDeferredLayer) + if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) { - boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); - if (!renderingCancelled) + if (!renderingDeferredLayer) { - //testRenderer.render(); + boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); + if (!renderingCancelled) + { + BlazeLodRenderer.INSTANCE.render(renderParams, profiler); + } - McLodRenderer.INSTANCE.render(renderParams, profiler); + if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) + { + ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null); + } } - - if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) + else { - ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null); + boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams); + if (!renderingCancelled) + { + BlazeLodRenderer.INSTANCE.renderDeferred(renderParams, profiler); + } + + + if (DhApi.Delayed.renderProxy.getDeferTransparentRendering()) + { + ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null); + } } } else { - boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams); - if (!renderingCancelled) + IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); + if (testRenderer != null) { - //LodRenderer.INSTANCE.renderDeferred(renderParams, profiler); + testRenderer.render(); } - - - if (DhApi.Delayed.renderProxy.getDeferTransparentRendering()) + else { - ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, null); + RATE_LIMITED_LOGGER.warn("Unable to find singleton ["+IMcTestRenderer.class.getSimpleName()+"]"); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java index 67e622952..cab5d1a0c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java @@ -25,7 +25,7 @@ import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.level.IDhClientLevel; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -85,13 +85,13 @@ public class DhApiRenderProxy implements IDhApiRenderProxy @Override public DhApiResult getDhDepthTextureId() { - int activeTexture = McLodRenderer.INSTANCE.getActiveDepthTextureId(); + int activeTexture = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's depth texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } @Override public DhApiResult getDhColorTextureId() { - int activeTexture = McLodRenderer.INSTANCE.getActiveColorTextureId(); + int activeTexture = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index 05048ee1b..a1ef966ac 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.RenderParams; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -47,7 +47,7 @@ import org.joml.Matrix4fc; import java.util.ArrayList; /** - * This object tells the {@link McLodRenderer} what buffers to render + * This object tells the {@link BlazeLodRenderer} what buffers to render */ public class RenderBufferHandler implements AutoCloseable { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java similarity index 92% rename from core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java index a3930e327..b1227b8cb 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/McLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java @@ -29,19 +29,17 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.*; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; -import com.seibel.distanthorizons.core.util.math.Vec3f; /** * This is where all the magic happens.
* This is where LODs are draw to the world. */ -public class McLodRenderer +public class BlazeLodRenderer { public static final DhLogger LOGGER = new DhLoggerBuilder() .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) @@ -54,7 +52,7 @@ public class McLodRenderer private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - public static final McLodRenderer INSTANCE = new McLodRenderer(); + public static final BlazeLodRenderer INSTANCE = new BlazeLodRenderer(); @@ -66,7 +64,7 @@ public class McLodRenderer // constructor // //=============// - private McLodRenderer() { } + private BlazeLodRenderer() { } @@ -206,8 +204,7 @@ public class McLodRenderer if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get()) { profiler.popPush("Fade Far Clip Fade"); - farFadeRenderer.render( - new Mat4f(renderParams.mcModelViewMatrix), new Mat4f(renderParams.mcProjectionMatrix)); + farFadeRenderer.render(renderParams); } // fog @@ -301,20 +298,10 @@ public class McLodRenderer ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam); - if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) + SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); + if (lodBufferContainer != null) { - // Normal LOD rendering - - SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); - if (lodBufferContainer != null) - { - lodRenderer.render(renderEventParam, opaquePass, lodBufferContainer, profilerWrapper); - } - } - else - { - IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); - testRenderer.render(); + lodRenderer.render(renderEventParam, opaquePass, lodBufferContainer, profilerWrapper); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java index 2017e0a7b..d73a55693 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java @@ -146,7 +146,7 @@ public class DhFadeRenderer FadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; FadeApplyShader.INSTANCE.readFramebuffer = DhFadeShader.INSTANCE.frameBuffer; - FadeApplyShader.INSTANCE.drawFramebuffer = McLodRenderer.INSTANCE.getActiveFramebufferId(); + FadeApplyShader.INSTANCE.drawFramebuffer = BlazeLodRenderer.INSTANCE.getActiveFramebufferId(); FadeApplyShader.INSTANCE.render(partialTicks); } catch (Exception e) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java index dfa79ad35..f3b2af3f5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java @@ -121,7 +121,7 @@ public class VanillaFadeRenderer public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level) { - int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); + int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); if (depthTextureId == -1) { // the renderer hasn't been set up yet diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java index 030a74c7f..7bc27b240 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java @@ -23,14 +23,14 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.glObject.GLState; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import com.seibel.distanthorizons.core.logging.DhLogger; import org.lwjgl.opengl.GL32; /** - * Copies {@link McLodRenderer}'s currently active color and depth texture to Minecraft's framebuffer. + * Copies {@link BlazeLodRenderer}'s currently active color and depth texture to Minecraft's framebuffer. */ public class DhApplyShader extends AbstractShaderRenderer { @@ -117,11 +117,11 @@ public class DhApplyShader extends AbstractShaderRenderer //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveColorTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveColorTextureId()); GL32.glUniform1i(this.gDhColorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 1); // Copy to MC's framebuffer @@ -141,7 +141,7 @@ public class DhApplyShader extends AbstractShaderRenderer return; } - int dhFrameBufferId = McLodRenderer.INSTANCE.getActiveFramebufferId(); + int dhFrameBufferId = BlazeLodRenderer.INSTANCE.getActiveFramebufferId(); if (dhFrameBufferId == -1) { return; @@ -170,11 +170,11 @@ public class DhApplyShader extends AbstractShaderRenderer //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveColorTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveColorTextureId()); GL32.glUniform1i(this.gDhColorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 1); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java index d7bf72b40..aa3740528 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java @@ -21,7 +21,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; @@ -126,8 +126,8 @@ public class DhFadeShader extends AbstractShaderRenderer @Override protected void onRender() { - int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = McLodRenderer.INSTANCE.getActiveColorTextureId(); + int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); + int colorTextureId = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); if (depthTextureId == -1 || colorTextureId == -1) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java index a0b3086b5..e3136f663 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java @@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.renderer.FogRenderer; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; import org.lwjgl.opengl.GL32; @@ -82,7 +82,7 @@ public class FogApplyShader extends AbstractShaderRenderer GL32.glUniform1i(this.colorTextureUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.depthTextureUniform, 1); } @@ -108,7 +108,7 @@ public class FogApplyShader extends AbstractShaderRenderer // apply the rendered Fog to DH's framebuffer GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FogShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, McLodRenderer.INSTANCE.getActiveFramebufferId()); + GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, BlazeLodRenderer.INSTANCE.getActiveFramebufferId()); ScreenQuad.INSTANCE.render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java index 3bc83af45..c7c7181e7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java @@ -25,7 +25,7 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -264,7 +264,7 @@ public class FogShader extends AbstractShaderRenderer GLMC.disableBlend(); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.uDepthMap, 0); // this is necessary for MC 1.16 (IE Legacy OpenGL) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java index 099b0bc9d..77da0c811 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java @@ -21,7 +21,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; @@ -86,7 +86,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer protected void onApplyUniforms(float partialTicks) { GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); GL32.glUniform1i(this.gDepthMapUniform, 0); GLMC.glActiveTexture(GL32.GL_TEXTURE1); @@ -135,7 +135,7 @@ public class SSAOApplyShader extends AbstractShaderRenderer // apply the rendered SSAO to the LODs GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, SSAOShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, McLodRenderer.INSTANCE.getActiveFramebufferId()); + GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, BlazeLodRenderer.INSTANCE.getActiveFramebufferId()); ScreenQuad.INSTANCE.render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java index a0dd90cf5..3026b4968 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java @@ -21,7 +21,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.math.Mat4f; @@ -133,7 +133,7 @@ public class SSAOShader extends AbstractShaderRenderer GLMC.disableBlend(); GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(McLodRenderer.INSTANCE.getActiveDepthTextureId()); + GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); ScreenQuad.INSTANCE.render(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java index 9ea2c4f04..843a4218a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java @@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer.shaders; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.McLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; @@ -156,8 +156,8 @@ public class VanillaFadeShader extends AbstractShaderRenderer @Override protected void onRender() { - int depthTextureId = McLodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = McLodRenderer.INSTANCE.getActiveColorTextureId(); + int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); + int colorTextureId = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); if (depthTextureId == -1 || colorTextureId == -1) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java index f05d6f9f1..bc9bc7799 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.util; +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; @@ -64,7 +65,7 @@ public class RenderUtil * * @param mcProjMat Minecraft's current projection matrix */ - public static Mat4f createLodProjectionMatrix(Mat4f mcProjMat) + public static Mat4f createLodProjectionMatrix(DhApiMat4f mcProjMat) { // in James' testing a near clip plane distance of 2 blocks is enough to allow the fragment // culling to take effect instead of seeing the near clip plane. @@ -81,18 +82,18 @@ public class RenderUtil float farClipDist = (float) RenderUtil.getFarClipPlaneDistanceInBlocks(); // Create a copy of the current matrix, so it won't be modified. - Mat4f lodProj = mcProjMat.copy(); + Mat4f lodProj = new Mat4f(mcProjMat); // Set new far and near clip plane values. lodProj.setClipPlanes(nearClipDist, farClipDist); return lodProj; } /** create and return a new projection matrix based on MC's modelView and projection matrices */ - public static Mat4f createLodModelViewMatrix(Mat4f mcModelViewMat) + public static Mat4f createLodModelViewMatrix(DhApiMat4f mcModelViewMat) { // nothing beyond copying needs to be done to MC's MVM currently, // this method is just here in case that changes in the future - return mcModelViewMat.copy(); + return new Mat4f(mcModelViewMat); } //endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java index c7df69ff9..07d6e120a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; +import com.seibel.distanthorizons.core.render.renderer.RenderParams; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; @@ -26,6 +27,6 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab public interface IMcFarFadeRenderer extends IBindable { - void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix); + void render(RenderParams renderParams); } From 39dd1c8509c23facf77ef9cafc5364a0908dd71f Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 12:28:49 -0500 Subject: [PATCH 23/46] renderable box cleanup --- .../generic/GenericObjectRenderer.java | 4 +-- .../renderer/generic/RenderableBoxGroup.java | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java index 9e4c390e5..69fd166b0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java @@ -475,7 +475,7 @@ public class GenericObjectRenderer implements IMcGenericRenderer boxGroup.tryUpdateInstancedDataAsync(); // skip groups that haven't been uploaded yet - if (boxGroup.instancedVbos.getState() != NativeGlGenericObjectVertexContainer.EState.RENDER) + if (boxGroup.vertexBufferContainer.getState() != NativeGlGenericObjectVertexContainer.EState.RENDER) { continue; } @@ -557,7 +557,7 @@ public class GenericObjectRenderer implements IMcGenericRenderer // Bind instance data // profiler.popPush("binding"); - NativeGlGenericObjectVertexContainer container = (NativeGlGenericObjectVertexContainer)(boxGroup.instancedVbos); + NativeGlGenericObjectVertexContainer container = (NativeGlGenericObjectVertexContainer)(boxGroup.vertexBufferContainer); GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color); GL32.glEnableVertexAttribArray(1); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java index d96a776f4..54a4ea7ba 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java @@ -68,9 +68,9 @@ public class RenderableBoxGroup public Consumer afterRenderFunc; // instance data - public IGenericObjectVertexBufferContainer instancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); + public IGenericObjectVertexBufferContainer vertexBufferContainer = WRAPPER_FACTORY.createInstancedVboContainer(); /** double buffering for thread safety and to prevent locking the render thread during update */ - private IGenericObjectVertexBufferContainer altInstancedVbos = WRAPPER_FACTORY.createInstancedVboContainer(); + private IGenericObjectVertexBufferContainer altVertexBufferContainer = WRAPPER_FACTORY.createInstancedVboContainer(); @@ -196,14 +196,14 @@ public class RenderableBoxGroup public void tryUpdateInstancedDataAsync() { // if the alt container is done, swap it in - if (this.altInstancedVbos.getState() == NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD) + if (this.altVertexBufferContainer.getState() == NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD) { - this.altInstancedVbos.uploadDataToGpu(); + this.altVertexBufferContainer.uploadDataToGpu(); // swap VBO references for rendering - IGenericObjectVertexBufferContainer temp = this.instancedVbos; - this.instancedVbos = this.altInstancedVbos; - this.altInstancedVbos = temp; + IGenericObjectVertexBufferContainer temp = this.vertexBufferContainer; + this.vertexBufferContainer = this.altVertexBufferContainer; + this.altVertexBufferContainer = temp; this.vertexDataDirty = false; @@ -225,11 +225,11 @@ public class RenderableBoxGroup } // if the alternate container is already updating, don't double-queue it - if (this.altInstancedVbos.getState() == NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA) + if (this.altVertexBufferContainer.getState() == NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA) { return; } - this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA); + this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA); @@ -248,19 +248,19 @@ public class RenderableBoxGroup { try { - this.altInstancedVbos.updateVertexData(this.uploadBoxList); + this.altVertexBufferContainer.updateVertexData(this.uploadBoxList); } catch (Exception e) { LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e); - this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.ERROR); + this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.ERROR); } }); } catch (RejectedExecutionException ignore) { // the executor was shut down, it should be back up shortly and able to accept new jobs - this.altInstancedVbos.setState(NativeGlGenericObjectVertexContainer.EState.NEW); + this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.NEW); } } @@ -349,8 +349,8 @@ public class RenderableBoxGroup { GLProxy.queueRunningOnRenderThread(() -> { - this.instancedVbos.close(); - this.altInstancedVbos.close(); + this.vertexBufferContainer.close(); + this.altVertexBufferContainer.close(); }); } From e1a932cf38e5f8f016a20fe946f5a792884333a3 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 13:51:44 -0500 Subject: [PATCH 24/46] Only upload unique LOD uniforms once --- .../render/bufferBuilding/LodBufferContainer.java | 6 ++++-- .../render/ILodContainerUniformBufferWrapper.java | 7 +++++-- .../assets/distanthorizons/shaders/lod/blaze/vert.vsh | 3 ++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index 1d71b7812..95338fe68 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -66,7 +66,7 @@ public class LodBufferContainer implements AutoCloseable public IVertexBufferWrapper[] vbos; public IVertexBufferWrapper[] vbosTransparent; - public ILodContainerUniformBufferWrapper uniforms = WRAPPER_FACTORY.createLodContainerUniformWrapper(); + public ILodContainerUniformBufferWrapper uniformContainer = WRAPPER_FACTORY.createLodContainerUniformWrapper(); private final AtomicReference> uploadFutureRef = new AtomicReference<>(null); @@ -82,6 +82,8 @@ public class LodBufferContainer implements AutoCloseable this.minCornerBlockPos = minCornerBlockPos; this.vbos = new IVertexBufferWrapper[0]; this.vbosTransparent = new IVertexBufferWrapper[0]; + + this.uniformContainer.createUniformData(this); } @@ -311,7 +313,7 @@ public class LodBufferContainer implements AutoCloseable } } - this.uniforms.close(); + this.uniformContainer.close(); }); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java index 6eedda0e2..93c9183f5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java @@ -20,9 +20,12 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; public interface ILodContainerUniformBufferWrapper extends IUniformBufferWrapper { - void createBufferData(RenderParams renderEventParam, LodBufferContainer bufferContainer); + + void createUniformData(LodBufferContainer bufferContainer); + + void tryUpload(); + } diff --git a/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh b/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh index 3b5fdf531..e2eed781e 100644 --- a/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh +++ b/core/src/main/resources/assets/distanthorizons/shaders/lod/blaze/vert.vsh @@ -24,6 +24,7 @@ layout (std140) uniform vertSharedUniformBlock float uMircoOffset; float uEarthRadius; + vec3 uCameraPos; mat4 uCombinedMatrix; }; @@ -36,7 +37,7 @@ void main() { vPos = vPosition; // This is so it can be passed to the fragment shader - vertexWorldPos = vPosition.xyz + uModelOffset; + vertexWorldPos = vPosition.xyz + (uModelOffset - uCameraPos); vertexYPos = vPosition.y + uWorldYOffset; From 8240101a461472c8de1ba845deea28d69bfe3aeb Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 13:58:29 -0500 Subject: [PATCH 25/46] javadoc --- .../render/ILodContainerUniformBufferWrapper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java index 93c9183f5..cda04b44b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java @@ -21,6 +21,9 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; +/** + * @see LodBufferContainer + */ public interface ILodContainerUniformBufferWrapper extends IUniformBufferWrapper { From 27b66940bebb141e2280d71c0bfd41aa4a4c4bef Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 16:22:55 -0500 Subject: [PATCH 26/46] Start moving OpenGL rendering to common 1 --- .../core/render/DhFrustumBounds.java | 69 -- .../core/render/NeverCullFrustum.java | 42 - .../core/render/fog/FogSettings.java | 72 -- .../core/render/glObject/GLEnums.java | 261 ------ .../core/render/glObject/GLProxy.java | 453 ----------- .../core/render/glObject/GLState.java | 259 ------ .../core/render/glObject/buffer/GLBuffer.java | 344 -------- .../glObject/buffer/GLElementBuffer.java | 60 -- .../glObject/buffer/GLVertexBuffer.java | 88 -- .../glObject/buffer/QuadElementBuffer.java | 196 ----- .../core/render/glObject/shader/Shader.java | 185 ----- .../render/glObject/shader/ShaderProgram.java | 230 ------ .../glObject/texture/DHDepthTexture.java | 63 -- .../glObject/texture/DhColorTexture.java | 184 ----- .../glObject/texture/DhFramebuffer.java | 153 ---- .../texture/EDhDepthBufferFormat.java | 114 --- .../texture/EDhInternalTextureFormat.java | 130 --- .../glObject/texture/EDhPixelFormat.java | 60 -- .../render/glObject/texture/EDhPixelType.java | 64 -- .../render/glObject/texture/EGlVersion.java | 9 - .../AbstractVertexAttribute.java | 92 --- .../VertexAttributePostGL43.java | 156 ---- .../VertexAttributePreGL43.java | 254 ------ .../vertexAttribute/VertexPointer.java | 72 -- .../core/render/renderer/DebugRenderer.java | 513 ------------ .../core/render/renderer/DhFadeRenderer.java | 164 ---- .../renderer/DhTerrainShaderProgram.java | 226 ------ .../core/render/renderer/FogRenderer.java | 142 ---- .../core/render/renderer/LodRenderer.java | 767 ------------------ .../core/render/renderer/RenderParams.java | 223 ----- .../core/render/renderer/SSAORenderer.java | 142 ---- .../core/render/renderer/ScreenQuad.java | 98 --- .../core/render/renderer/TestRenderer.java | 142 ---- .../render/renderer/VanillaFadeRenderer.java | 187 ----- .../renderer/generic/BeaconRenderHandler.java | 331 -------- .../renderer/generic/CloudRenderHandler.java | 617 -------------- .../generic/GenericObjectRenderer.java | 735 ----------------- .../generic/GenericObjectShaderProgram.java | 231 ------ .../generic/GenericRenderObjectFactory.java | 78 -- .../IGenericObjectVertexBufferContainer.java | 40 - .../NativeGlGenericObjectVertexContainer.java | 180 ---- .../renderer/generic/RenderableBoxGroup.java | 362 --------- .../shaders/AbstractShaderRenderer.java | 77 -- .../renderer/shaders/DhApplyShader.java | 198 ----- .../render/renderer/shaders/DhFadeShader.java | 164 ---- .../renderer/shaders/FadeApplyShader.java | 118 --- .../renderer/shaders/FogApplyShader.java | 118 --- .../render/renderer/shaders/FogShader.java | 286 ------- .../renderer/shaders/SSAOApplyShader.java | 144 ---- .../render/renderer/shaders/SSAOShader.java | 140 ---- .../renderer/shaders/VanillaFadeShader.java | 197 ----- .../render/vertexFormat/LodVertexFormat.java | 181 ----- .../vertexFormat/LodVertexFormatElement.java | 168 ---- .../render/vertexFormat/VertexFormats.java | 50 -- .../minecraft/IMinecraftGLWrapper.java | 126 --- 55 files changed, 10755 deletions(-) delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/DhFrustumBounds.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/NeverCullFrustum.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/fog/FogSettings.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLEnums.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/Shader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DHDepthTexture.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhColorTexture.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhFramebuffer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhDepthBufferFormat.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhInternalTextureFormat.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelFormat.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelType.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EGlVersion.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/AbstractVertexAttribute.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePostGL43.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePreGL43.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexPointer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectShaderProgram.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericRenderObjectFactory.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormat.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/VertexFormats.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftGLWrapper.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/DhFrustumBounds.java b/core/src/main/java/com/seibel/distanthorizons/core/render/DhFrustumBounds.java deleted file mode 100644 index a4ca46ca2..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/DhFrustumBounds.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.seibel.distanthorizons.core.render; - -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum; -import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; -import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import org.joml.FrustumIntersection; -import org.joml.Matrix4f; -import org.joml.Matrix4fc; -import org.joml.Vector3f; - - -public class DhFrustumBounds implements IDhApiCullingFrustum -{ - private final FrustumIntersection frustum; - private final Vector3f boundsMin = new Vector3f(); - private final Vector3f boundsMax = new Vector3f(); - public float worldMinY; - public float worldMaxY; - - - - //=============// - // constructor // - //=============// - - public DhFrustumBounds() - { - this.frustum = new FrustumIntersection(); - } - - - - //=========// - // methods // - //=========// - - @Override - public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f dhWorldViewProjection) - { - this.worldMinY = worldMinBlockY; - this.worldMaxY = worldMaxBlockY; - - Matrix4f worldViewProjection = new Matrix4f(Mat4f.createJomlMatrix(dhWorldViewProjection)); - this.frustum.set(worldViewProjection); - - Matrix4fc matWorldViewProjectionInv = new Matrix4f(worldViewProjection).invert(); - matWorldViewProjectionInv.frustumAabb(this.boundsMin, this.boundsMax); - } - - @Override - public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) - { - Vector3f lodMin = new Vector3f(lodBlockPosMinX, this.worldMinY, lodBlockPosMinZ); - Vector3f lodMax = new Vector3f(lodBlockPosMinX + lodBlockWidth, this.worldMaxY, lodBlockPosMinZ + lodBlockWidth); - - return this.frustum.testAab(lodMin, lodMax); - } - - - - //=====================// - // overridable methods // - //=====================// - - @Override - public int getPriority() { return IOverrideInjector.CORE_PRIORITY; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/NeverCullFrustum.java b/core/src/main/java/com/seibel/distanthorizons/core/render/NeverCullFrustum.java deleted file mode 100644 index 611aa0ad6..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/NeverCullFrustum.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.seibel.distanthorizons.core.render; - -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum; -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum; -import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; -import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector; -import com.seibel.distanthorizons.core.util.math.Mat4f; - -/** - * Dummy {@link IDhApiCullingFrustum} that allows everything through.
- * Useful when a frustum is required, but culling shouldn't be done. - */ -public class NeverCullFrustum implements IDhApiCullingFrustum, IDhApiShadowCullingFrustum -{ - //=============// - // constructor // - //=============// - - public NeverCullFrustum() { } - - - - //=========// - // methods // - //=========// - - @Override - public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f dhWorldViewProjection) { /* update isn't needed */ } - - @Override - public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) { return true; } - - - - //=====================// - // overridable methods // - //=====================// - - @Override - public int getPriority() { return IOverrideInjector.CORE_PRIORITY; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/fog/FogSettings.java b/core/src/main/java/com/seibel/distanthorizons/core/render/fog/FogSettings.java deleted file mode 100644 index 041f0e9d2..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/fog/FogSettings.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.fog; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogFalloff; - -import java.util.Objects; - -/** - * Contains all configurable options related to fog. - * - * @version 2022-4-13 - */ -public class FogSettings -{ - /** a FogSetting object with 0 for every value */ - public static final FogSettings EMPTY = new FogSettings(0, 0, 0, 0, 0, EDhApiFogFalloff.LINEAR); - - - public final double start; - public final double end; - public final double min; - public final double max; - public final double density; - public final EDhApiFogFalloff fogType; - - public FogSettings(double start, double end, double min, double max, double density, EDhApiFogFalloff fogType) - { - this.start = start; - this.end = end; - this.min = min; - this.max = max; - this.density = density; - this.fogType = fogType; - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - FogSettings that = (FogSettings) o; - return Double.compare(that.start, start) == 0 && Double.compare(that.end, end) == 0 && Double.compare(that.min, min) == 0 && Double.compare(that.max, max) == 0 && Double.compare(that.density, density) == 0 && fogType == that.fogType; - } - - @Override - public int hashCode() - { - return Objects.hash(start, end, min, max, density, fogType); - } - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLEnums.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLEnums.java deleted file mode 100644 index d356c2b1a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLEnums.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject; - -import static org.lwjgl.opengl.GL46.*; - -// Turns GL int enums back to readable strings -public class GLEnums -{ - - public static String getString(int glEnum) - { - // blend stuff - switch (glEnum) - { - case GL_ZERO: - return "GL_ZERO"; - case GL_ONE: - return "GL_ONE"; - case GL_SRC_COLOR: - return "GL_SRC_COLOR"; - case GL_ONE_MINUS_SRC_COLOR: - return "GL_ONE_MINUS_SRC_COLOR"; - case GL_DST_COLOR: - return "GL_DST_COLOR"; - case GL_ONE_MINUS_DST_COLOR: - return "GL_ONE_MINUS_DST_COLOR"; - case GL_SRC_ALPHA: - return "GL_SRC_ALPHA"; - case GL_ONE_MINUS_SRC_ALPHA: - return "GL_ONE_MINUS_SRC_ALPHA"; - case GL_DST_ALPHA: - return "GL_DST_ALPHA"; - case GL_ONE_MINUS_DST_ALPHA: - return "GL_ONE_MINUS_DST_ALPHA"; - case GL_CONSTANT_COLOR: - return "GL_CONSTANT_COLOR"; - case GL_ONE_MINUS_CONSTANT_COLOR: - return "GL_ONE_MINUS_CONSTANT_COLOR"; - case GL_CONSTANT_ALPHA: - return "GL_CONSTANT_ALPHA"; - case GL_ONE_MINUS_CONSTANT_ALPHA: - return "GL_ONE_MINUS_CONSTANT_ALPHA"; - default: - } - - // shader stuff - switch (glEnum) - { - case GL_VERTEX_SHADER: - return "GL_VERTEX_SHADER"; - case GL_GEOMETRY_SHADER: - return "GL_GEOMETRY_SHADER"; - case GL_FRAGMENT_SHADER: - return "GL_FRAGMENT_SHADER"; - default: - } - - // stencil stuff - switch (glEnum) - { - case GL_KEEP: - return "GL_KEEP"; - case GL_ZERO: - return "GL_ZERO"; - case GL_REPLACE: - return "GL_REPLACE"; - case GL_INCR: - return "GL_INCR"; - case GL_DECR: - return "GL_DECR"; - case GL_INVERT: - return "GL_INVERT"; - case GL_INCR_WRAP: - return "GL_INCR_WRAP"; - case GL_DECR_WRAP: - return "GL_DECR_WRAP"; - default: - } - - // depth stuff - switch (glEnum) - { - case GL_NEVER: - return "GL_NEVER"; - case GL_LESS: - return "GL_LESS"; - case GL_EQUAL: - return "GL_EQUAL"; - case GL_LEQUAL: - return "GL_LEQUAL"; - case GL_GREATER: - return "GL_GREATER"; - case GL_NOTEQUAL: - return "GL_NOTEQUAL"; - case GL_GEQUAL: - return "GL_GEQUAL"; - case GL_ALWAYS: - return "GL_ALWAYS"; - default: - } - - // Texture binding points - switch (glEnum) - { - case GL_TEXTURE0: - return "GL_TEXTURE0"; - case GL_TEXTURE1: - return "GL_TEXTURE1"; - case GL_TEXTURE2: - return "GL_TEXTURE2"; - case GL_TEXTURE3: - return "GL_TEXTURE3"; - case GL_TEXTURE4: - return "GL_TEXTURE4"; - case GL_TEXTURE5: - return "GL_TEXTURE5"; - case GL_TEXTURE6: - return "GL_TEXTURE6"; - case GL_TEXTURE7: - return "GL_TEXTURE7"; - case GL_TEXTURE8: - return "GL_TEXTURE8"; - case GL_TEXTURE9: - return "GL_TEXTURE9"; - case GL_TEXTURE10: - return "GL_TEXTURE10"; - case GL_TEXTURE11: - return "GL_TEXTURE11"; - case GL_TEXTURE12: - return "GL_TEXTURE12"; - case GL_TEXTURE13: - return "GL_TEXTURE13"; - case GL_TEXTURE14: - return "GL_TEXTURE14"; - case GL_TEXTURE15: - return "GL_TEXTURE15"; - case GL_TEXTURE16: - return "GL_TEXTURE16"; - case GL_TEXTURE17: - return "GL_TEXTURE17"; - case GL_TEXTURE18: - return "GL_TEXTURE18"; - case GL_TEXTURE19: - return "GL_TEXTURE19"; - case GL_TEXTURE20: - return "GL_TEXTURE20"; - case GL_TEXTURE21: - return "GL_TEXTURE21"; - case GL_TEXTURE22: - return "GL_TEXTURE22"; - case GL_TEXTURE23: - return "GL_TEXTURE23"; - case GL_TEXTURE24: - return "GL_TEXTURE24"; - case GL_TEXTURE25: - return "GL_TEXTURE25"; - case GL_TEXTURE26: - return "GL_TEXTURE26"; - case GL_TEXTURE27: - return "GL_TEXTURE27"; - case GL_TEXTURE28: - return "GL_TEXTURE28"; - case GL_TEXTURE29: - return "GL_TEXTURE29"; - case GL_TEXTURE30: - return "GL_TEXTURE30"; - case GL_TEXTURE31: - return "GL_TEXTURE31"; - default: - } - - // Polygon modes - switch (glEnum) - { - case GL_POINT: - return "GL_POINT"; - case GL_LINE: - return "GL_LINE"; - case GL_FILL: - return "GL_FILL"; - default: - } - - // Culling modes - switch (glEnum) - { - case GL_FRONT: - return "GL_FRONT"; - case GL_BACK: - return "GL_BACK"; - case GL_FRONT_AND_BACK: - return "GL_FRONT_AND_BACK"; - default: - } - - // Types - switch (glEnum) - { - case GL_BYTE: - return "GL_BYTE"; - case GL_UNSIGNED_BYTE: - return "GL_UNSIGNED_BYTE"; - case GL_SHORT: - return "GL_SHORT"; - case GL_UNSIGNED_SHORT: - return "GL_UNSIGNED_SHORT"; - case GL_INT: - return "GL_INT"; - case GL_UNSIGNED_INT: - return "GL_UNSIGNED_INT"; - case GL_FLOAT: - return "GL_FLOAT"; - case GL_DOUBLE: - return "GL_DOUBLE"; - default: - } - - return "GL_UNKNOWN(" + glEnum + ")"; - } - - public static int getTypeSize(int glTypeEnum) - { - switch (glTypeEnum) - { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return 1; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - return 2; - case GL_INT: - case GL_UNSIGNED_INT: - return 4; - case GL_FLOAT: - return 4; - case GL_DOUBLE: - return 8; - default: - throw new IllegalArgumentException("Unknown type enum: " + getString(glTypeEnum)); - } - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java deleted file mode 100644 index eb4f6f1ab..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLProxy.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode; -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.jar.EPlatform; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.util.TimerUtil; -import com.seibel.distanthorizons.core.util.objects.GLMessages.*; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.coreapi.ModInfo; -import org.lwjgl.glfw.GLFW; -import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GLCapabilities; -import org.lwjgl.opengl.GLUtil; - -import java.io.PrintStream; -import java.util.Collections; -import java.util.Set; -import java.util.Timer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * A singleton that holds references to different openGL contexts - * and GPU capabilities. - */ -public class GLProxy -{ - //private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - //private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - public static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) - .build(); - - public static final Set LOGGED_GL_MESSAGES = Collections.newSetFromMap(new ConcurrentHashMap()); - - private static final ConcurrentLinkedQueue RENDER_THREAD_RUNNABLE_QUEUE = new ConcurrentLinkedQueue<>(); - - private static final Timer TIMER = TimerUtil.CreateTimer("Cleanup timer"); - private static final long MS_BETWEEN_CLEANUP_TICKS = 1_000L; - private static final long MS_BEFORE_RUN_CLEANUP_TIMER = 1_000L; - - - - private static GLProxy instance = null; - - - /** Minecraft's GL capabilities */ - public final GLCapabilities glCapabilities; - - public boolean namedObjectSupported = false; // ~OpenGL 4.5 (UNUSED CURRENTLY) - public boolean bufferStorageSupported = false; // ~OpenGL 4.4 - public boolean vertexAttributeBufferBindingSupported = false; // ~OpenGL 4.3 - public boolean instancedArraysSupported = false; - public boolean vertexAttribDivisorSupported = false; // OpenGL 3.3 or newer - - private final EDhApiGpuUploadMethod preferredUploadMethod; - - public final GLMessageBuilder vanillaDebugMessageBuilder = - new GLMessageBuilder( - (type) -> - { - if (type == EGLMessageType.POP_GROUP) - return false; - else if (type == EGLMessageType.PUSH_GROUP) - return false; - else if (type == EGLMessageType.MARKER) - return false; - else - return true; - }, - (severity) -> - { - // notifications can generally be ignored (if they are logged at all) - if (severity == EGLMessageSeverity.NOTIFICATION) - return false; - else - return true; - }, - null - ); - - private long msSinceGlTasksRun = System.currentTimeMillis(); - - - - //=============// - // constructor // - //=============// - //region - - private GLProxy() throws IllegalStateException - { - // this must be created on minecraft's render context to work correctly - if (GLFW.glfwGetCurrentContext() == 0L) - { - throw new IllegalStateException(GLProxy.class.getSimpleName() + " was created outside the render thread!"); - } - - LOGGER.info("Creating " + GLProxy.class.getSimpleName() + "... If this is the last message you see there must have been an OpenGL error."); - LOGGER.info("Lod Render OpenGL version [" + GL32.glGetString(GL32.GL_VERSION) + "]."); - - - - - //============================// - // get Minecraft's GL context // - //============================// - - // get Minecraft's capabilities - this.glCapabilities = GL.getCapabilities(); - - // crash the game if the GPU doesn't support OpenGL 3.2 - if (!this.glCapabilities.OpenGL32) - { - String supportedVersionInfo = this.getFailedVersionInfo(this.glCapabilities); - - // See full requirement at above. - String errorMessage = ModInfo.READABLE_NAME + " was initializing " + GLProxy.class.getSimpleName() - + " and discovered this GPU doesn't meet the OpenGL requirements. Sorry I couldn't tell you sooner :(\n" + - "Additional info:\n" + supportedVersionInfo; - IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - MC.crashMinecraft(errorMessage, new UnsupportedOperationException("Distant Horizon OpenGL requirements not met")); - } - LOGGER.info("minecraftGlCapabilities:\n" + this.versionInfoToString(this.glCapabilities)); - - if (Config.Client.Advanced.Debugging.OpenGl.overrideVanillaGLLogger.get()) - { - GLUtil.setupDebugMessageCallback(new PrintStream(new GLMessageOutputStream(GLProxy::logMessage, this.vanillaDebugMessageBuilder), true)); - } - - - - //======================// - // get GPU capabilities // - //======================// - - // UNUSED currently - // Check if we can use the named version of all calls, which is available in GL4.5 or after - this.namedObjectSupported = this.glCapabilities.glNamedBufferData != 0L; //Nullptr - - // Check if we can use the Buffer Storage, which is available in GL4.4 or after - this.bufferStorageSupported = this.glCapabilities.glBufferStorage != 0L; // Nullptr - if (!this.bufferStorageSupported) - { - LOGGER.info("This GPU doesn't support Buffer Storage (OpenGL 4.4), falling back to using other methods."); - } - - // Check if we can use the make-over version of Vertex Attribute, which is available in GL4.3 or after - this.vertexAttributeBufferBindingSupported = this.glCapabilities.glBindVertexBuffer != 0L; // Nullptr - - // used by instanced rendering - this.vertexAttribDivisorSupported = this.glCapabilities.OpenGL33; - // denotes if ARBInstancedArrays.glVertexAttribDivisorARB() is available or not - // can be used as a backup if MC didn't create a GL 3.3+ context - this.instancedArraysSupported = this.glCapabilities.GL_ARB_instanced_arrays; - - // get the best automatic upload method - String vendor = GL32.glGetString(GL32.GL_VENDOR).toUpperCase(); // example return: "NVIDIA CORPORATION" - if (EPlatform.get() != EPlatform.MACOS) - { - if (vendor.contains("NVIDIA") || vendor.contains("GEFORCE")) - { - // NVIDIA card - this.preferredUploadMethod = this.bufferStorageSupported ? EDhApiGpuUploadMethod.BUFFER_STORAGE : EDhApiGpuUploadMethod.SUB_DATA; - } - else - { - // AMD or Intel card - this.preferredUploadMethod = this.bufferStorageSupported ? EDhApiGpuUploadMethod.BUFFER_STORAGE : EDhApiGpuUploadMethod.DATA; - } - } - else - { - // Mac may have an issue with Buffer Storage, so default to the most basic - // form of uploading - this.preferredUploadMethod = EDhApiGpuUploadMethod.DATA; - } - LOGGER.info("GPU Vendor [" + vendor + "] with OS [" + EPlatform.get().getName() + "], Preferred upload method is [" + this.preferredUploadMethod + "]."); - - - TIMER.scheduleAtFixedRate(TimerUtil.createTimerTask(this::manualGlCleanupTick), MS_BETWEEN_CLEANUP_TICKS, MS_BETWEEN_CLEANUP_TICKS); - - - //==========// - // clean up // - //==========// - - // GLProxy creation success - LOGGER.info(GLProxy.class.getSimpleName() + " creation successful. OpenGL smiles upon you this day."); - } - - //endregion - - - - //=========// - // getters // - //=========// - //region - - public static boolean hasInstance() { return instance != null; } - /** @throws IllegalStateException if the Proxy hasn't been created yet and this is called outside the render thread */ - public static GLProxy getInstance() throws IllegalStateException - { - if (instance == null) - { - instance = new GLProxy(); - } - - return instance; - } - - public EDhApiGpuUploadMethod getGpuUploadMethod() - { - EDhApiGpuUploadMethod uploadOverride = Config.Client.Advanced.Debugging.OpenGl.glUploadMode.get(); - if (uploadOverride == EDhApiGpuUploadMethod.AUTO) - { - return this.preferredUploadMethod; - } - - return uploadOverride; - } - - public static boolean runningOnRenderThread() - { - long currentContext = GLFW.glfwGetCurrentContext(); - return currentContext != 0L; // if the context isn't null, it's the MC context - } - - //endregion - - - - //=========================// - // Worker Thread Runnables // - //=========================// - //region - - public static void queueRunningOnRenderThread(Runnable renderCall) - { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - RENDER_THREAD_RUNNABLE_QUEUE.add(() -> runOpenGlCall(renderCall, stackTrace)); - } - private static void runOpenGlCall(Runnable renderCall, StackTraceElement[] stackTrace) - { - try - { - renderCall.run(); - } - catch (Exception e) - { - RuntimeException error = new RuntimeException("Uncaught Exception during GL call execution:", e); - error.setStackTrace(stackTrace); - LOGGER.error("[" + Thread.currentThread().getName() + "] ran into an unexpected error running a GL call, Error: ["+ e.getMessage() +"].", error); - } - } - - /** - * Doesn't do any thread/GL Context validation. - * Running this outside of the render thread may cause crashes or other issues. - */ - public void runRenderThreadTasks() - { - IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - int frameLimit = MC_RENDER.getFrameLimit(); - if (frameLimit <= 1) - { - frameLimit = 4; // 240 FPS - } - - // https://fpstoms.com/ - int msPerFrame = 1000 / frameLimit; - this.runRenderThreadTasks(msPerFrame); - } - private void runRenderThreadTasks(long msMaxRunTime) - { - long startTimeMs = System.currentTimeMillis(); - this.msSinceGlTasksRun = startTimeMs; - - Runnable runnable = RENDER_THREAD_RUNNABLE_QUEUE.poll(); - while(runnable != null) - { - runnable.run(); - - // only try running for 4ms (240 FPS) at a time to prevent random lag spikes - long currentTimeMs = System.currentTimeMillis(); - long runDuration = currentTimeMs - startTimeMs; - if (runDuration > msMaxRunTime) - { - break; - } - - runnable = RENDER_THREAD_RUNNABLE_QUEUE.poll(); - } - } - - /** - * Should only be called if our render code isn't being hit for some reason. - * Normally this only happens if there's a mod that limits MC's framerate to 0. - */ - private void manualGlCleanupTick() - { - long nowMs = System.currentTimeMillis(); - long msSinceLast = nowMs - this.msSinceGlTasksRun; - if (msSinceLast > MS_BEFORE_RUN_CLEANUP_TIMER) - { - return; - } - - // We haven't gotten a frame for a while, - // this means we could have GL jobs building up. - // Run the queued tasks on MC's executor (hopefully this should always run, - // even if DH's render code isn't being hit). - IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - MC.executeOnRenderThread(() -> this.runRenderThreadTasks(1_000)); - } - - //endregion - - - - //=========// - // logging // - //=========// - //region - - /** this method is called on the render thread at the point of the GL Error */ - private static void logMessage(GLMessage msg) - { - EDhApiGLErrorHandlingMode errorHandlingMode = Config.Client.Advanced.Debugging.OpenGl.glErrorHandlingMode.get(); - if (errorHandlingMode == EDhApiGLErrorHandlingMode.IGNORE) - { - return; - } - - - - boolean onlyLogOnce = Config.Client.Advanced.Debugging.OpenGl.onlyLogGlErrorsOnce.get(); - String errorMessage = "GL ERROR [" + msg.id + "] from [" + msg.source + "]: [" + msg.message + "]"+(onlyLogOnce ? " this message will only be logged once" : "")+"."; - if (onlyLogOnce - && !LOGGED_GL_MESSAGES.add(errorMessage)) - { - // this message has already been logged - return; - } - - - // create an exception so we get a stacktrace of where the message was triggered from - RuntimeException exception = new RuntimeException(errorMessage); - - if (msg.type == EGLMessageType.ERROR || msg.type == EGLMessageType.UNDEFINED_BEHAVIOR) - { - // critical error - - LOGGER.error(exception.getMessage(), exception); - - if (errorHandlingMode == EDhApiGLErrorHandlingMode.LOG_THROW) - { - // will probably crash the game, - // good for quickly checking if there's a problem while preventing log spam - throw exception; - } - } - else - { - // non-critical log - - EGLMessageSeverity severity = msg.severity; - if (severity == null) - { - // just in case the message was malformed - severity = EGLMessageSeverity.LOW; - } - - switch (severity) - { - case HIGH: - LOGGER.error(exception.getMessage(), exception); - break; - case MEDIUM: - LOGGER.warn(exception.getMessage(), exception); - break; - case LOW: - LOGGER.info(exception.getMessage(), exception); - break; - case NOTIFICATION: - LOGGER.debug(exception.getMessage(), exception); - break; - } - } - } - - //endregion - - - - //================// - // helper methods // - //================// - //region - - private String getFailedVersionInfo(GLCapabilities c) - { - return "Your OpenGL support:\n" + - "openGL version 3.2+: [" + c.OpenGL32 + "] <- REQUIRED\n" + - "Vertex Attribute Buffer Binding: [" + (c.glVertexAttribBinding != 0) + "] <- optional improvement\n" + - "Buffer Storage: [" + (c.glBufferStorage != 0) + "] <- optional improvement\n" + - "If you noticed that your computer supports higher OpenGL versions" - + " but not the required version, try running the game in compatibility mode." - + " (How you turn that on, I have no clue~)"; - } - - private String versionInfoToString(GLCapabilities c) - { - return "Your OpenGL support:\n" + - "openGL version 3.2+: [" + c.OpenGL32 + "] <- REQUIRED\n" + - "Vertex Attribute Buffer Binding: [" + (c.glVertexAttribBinding != 0) + "] <- optional improvement\n" + - "Buffer Storage: [" + (c.glBufferStorage != 0) + "] <- optional improvement\n"; - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java deleted file mode 100644 index 7029b007e..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/GLState.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL32; - -public class GLState implements AutoCloseable -{ - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int program; - public int vao; - public int vbo; - public int ebo; - public int fbo; - public int texture2D; - /** IE: GL_TEXTURE0, GL_TEXTURE1, etc. */ - public int activeTextureNumber; - public int texture0; - public int texture1; - public int texture2; - public int texture3; - public int frameBufferTexture0; - public int frameBufferTexture1; - public int frameBufferDepthTexture; - public boolean blend; - public boolean scissor; - public int blendEqRGB; - public int blendEqAlpha; - public int blendSrcColor; - public int blendSrcAlpha; - public int blendDstColor; - public int blendDstAlpha; - public boolean depth; - public boolean writeToDepthBuffer; - public int depthFunc; - public boolean stencil; - public int stencilFunc; - public int stencilRef; - public int stencilMask; - public int[] view; - public boolean cull; - public int cullMode; - public int polyMode; - - - - public GLState() { this.saveState(); } - - public void saveState() - { - this.program = GL32.glGetInteger(GL32.GL_CURRENT_PROGRAM); - this.vao = GL32.glGetInteger(GL32.GL_VERTEX_ARRAY_BINDING); - this.vbo = GL32.glGetInteger(GL32.GL_ARRAY_BUFFER_BINDING); - this.ebo = GL32.glGetInteger(GL32.GL_ELEMENT_ARRAY_BUFFER_BINDING); - - this.fbo = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING); - - this.texture2D = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); - this.activeTextureNumber = GL32.glGetInteger(GL32.GL_ACTIVE_TEXTURE); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - this.texture0 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - this.texture1 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); - - GLMC.glActiveTexture(GL32.GL_TEXTURE2); // problem with Iris - this.texture2 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); - - GLMC.glActiveTexture(GL32.GL_TEXTURE3); - this.texture3 = GL32.glGetInteger(GL32.GL_TEXTURE_BINDING_2D); - - GLMC.glActiveTexture(this.activeTextureNumber); - - if (this.fbo != 0) - { - this.frameBufferTexture0 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - this.frameBufferTexture1 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - this.frameBufferDepthTexture = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - } - else - { - // attempting to get values from the default framebuffer can throw errors on Linux - this.frameBufferTexture0 = 0; - this.frameBufferTexture1 = 0; - this.frameBufferDepthTexture = 0; - } - - this.blend = GL32.glIsEnabled(GL32.GL_BLEND); - this.scissor = GL32.glIsEnabled(GL32.GL_SCISSOR_TEST); - this.blendEqRGB = GL32.glGetInteger(GL32.GL_BLEND_EQUATION_RGB); - this.blendEqAlpha = GL32.glGetInteger(GL32.GL_BLEND_EQUATION_ALPHA); - this.blendSrcColor = GL32.glGetInteger(GL32.GL_BLEND_SRC_RGB); - this.blendSrcAlpha = GL32.glGetInteger(GL32.GL_BLEND_SRC_ALPHA); - this.blendDstColor = GL32.glGetInteger(GL32.GL_BLEND_DST_RGB); - this.blendDstAlpha = GL32.glGetInteger(GL32.GL_BLEND_DST_ALPHA); - this.depth = GL32.glIsEnabled(GL32.GL_DEPTH_TEST); - this.writeToDepthBuffer = GL32.glGetInteger(GL32.GL_DEPTH_WRITEMASK) == GL32.GL_TRUE; - this.depthFunc = GL32.glGetInteger(GL32.GL_DEPTH_FUNC); - this.stencil = GL32.glIsEnabled(GL32.GL_STENCIL_TEST); - this.stencilFunc = GL32.glGetInteger(GL32.GL_STENCIL_FUNC); - this.stencilRef = GL32.glGetInteger(GL32.GL_STENCIL_REF); - this.stencilMask = GL32.glGetInteger(GL32.GL_STENCIL_VALUE_MASK); - this.view = new int[4]; - GL32.glGetIntegerv(GL32.GL_VIEWPORT, this.view); - this.cull = GL32.glIsEnabled(GL32.GL_CULL_FACE); - this.cullMode = GL32.glGetInteger(GL32.GL_CULL_FACE_MODE); - this.polyMode = GL32.glGetInteger(GL32.GL_POLYGON_MODE); - } - - @Override - public void close() - { - // explicitly unbinding the frame buffer is necessary to prevent GL_CLEAR calls from hitting the wrong buffer - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, 0); - boolean frameBufferSet = false; - - if (this.fbo != 0 && GL32.glIsFramebuffer(this.fbo)) - { - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fbo); - frameBufferSet = true; - } - - - if (this.blend) - { - GLMC.enableBlend(); - } - else - { - GLMC.disableBlend(); - } - - if (this.scissor) - { - GLMC.enableScissorTest(); - } - else - { - GLMC.disableScissorTest(); - } - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(GL32.glIsTexture(this.texture0) ? this.texture0 : 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(GL32.glIsTexture(this.texture1) ? this.texture1 : 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE2); - GLMC.glBindTexture(GL32.glIsTexture(this.texture2) ? this.texture2 : 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE3); - GLMC.glBindTexture(GL32.glIsTexture(this.texture3) ? this.texture3 : 0); - - GLMC.glActiveTexture(this.activeTextureNumber); - GLMC.glBindTexture(GL32.glIsTexture(this.texture2D) ? this.texture2D : 0); - - // attempting to set textures on the default frame buffer (ID 0) will throw errors - if (frameBufferSet) - { - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.frameBufferTexture0, 0); - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_TEXTURE_2D, this.frameBufferTexture1, 0); - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_TEXTURE_2D, this.frameBufferDepthTexture, 0); - } - - GL32.glBindVertexArray(GL32.glIsVertexArray(this.vao) ? this.vao : 0); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, GL32.glIsBuffer(this.vbo) ? this.vbo : 0); - GL32.glBindBuffer(GL32.GL_ELEMENT_ARRAY_BUFFER, GL32.glIsBuffer(this.ebo) ? this.ebo: 0); - GL32.glUseProgram(GL32.glIsProgram(this.program) ? this.program : 0); - - if (this.writeToDepthBuffer) - { - GLMC.enableDepthMask(); - } - else - { - GLMC.disableDepthMask(); - } - - GLMC.glBlendFunc(this.blendSrcColor, this.blendDstColor); - GL32.glBlendEquationSeparate(this.blendEqRGB, this.blendEqAlpha); - GLMC.glBlendFuncSeparate(this.blendSrcColor, this.blendDstColor, this.blendSrcAlpha, this.blendDstAlpha); - - if (this.depth) - { - GLMC.enableDepthTest(); - } - else - { - GLMC.disableDepthTest(); - } - GLMC.glDepthFunc(this.depthFunc); - - if (this.stencil) - { - GL32.glEnable(GL32.GL_STENCIL_TEST); - } - else - { - GL32.glDisable(GL32.GL_STENCIL_TEST); - } - GL32.glStencilFunc(this.stencilFunc, this.stencilRef, this.stencilMask); - - GL32.glViewport(this.view[0], this.view[1], this.view[2], this.view[3]); - if (this.cull) - { - GLMC.enableFaceCulling(); - } - else - { - GLMC.disableFaceCulling(); - } - GL32.glCullFace(this.cullMode); - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, this.polyMode); - } - - @Override - public String toString() - { - return "GLState{" + - "program=" + this.program + ", vao=" + this.vao + ", vbo=" + this.vbo + ", ebo=" + this.ebo + ", fbo=" + this.fbo + - ", text=" + GLEnums.getString(this.texture2D) + "@" + this.activeTextureNumber + ", text0=" + GLEnums.getString(this.texture0) + - ", FB text0=" + this.frameBufferTexture0 + - ", FB text1=" + this.frameBufferTexture1 + - ", FB depth=" + this.frameBufferDepthTexture + - ", blend=" + this.blend + ", scissor=" + this.scissor + ", blendMode=" + GLEnums.getString(this.blendSrcColor) + "," + GLEnums.getString(this.blendDstColor) + - ", depth=" + this.depth + - ", depthFunc=" + GLEnums.getString(this.depthFunc) + ", stencil=" + this.stencil + - ", stencilFunc=" + GLEnums.getString(this.stencilFunc) + ", stencilRef=" + this.stencilRef + ", stencilMask=" + this.stencilMask + - ", view={x:" + this.view[0] + ", y:" + this.view[1] + - ", w:" + this.view[2] + ", h:" + this.view[3] + "}" + ", cull=" + this.cull + - ", cullMode=" + GLEnums.getString(this.cullMode) + ", polyMode=" + GLEnums.getString(this.polyMode) + - '}'; - } - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java deleted file mode 100644 index 0cf89c3a3..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLBuffer.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.buffer; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.ThreadUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL44; - -import java.lang.ref.PhantomReference; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.nio.ByteBuffer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicInteger; - -public class GLBuffer implements AutoCloseable -{ - private static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) - .build(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public static final double BUFFER_EXPANSION_MULTIPLIER = 1.3; - public static final double BUFFER_SHRINK_TRIGGER = BUFFER_EXPANSION_MULTIPLIER * BUFFER_EXPANSION_MULTIPLIER; - /** the number of active buffers, can be used for debugging */ - public static AtomicInteger bufferCount = new AtomicInteger(0); - - private static final int PHANTOM_REF_CHECK_TIME_IN_MS = 5 * 1000; - private static final ConcurrentHashMap, Integer> PHANTOM_TO_BUFFER_ID = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap> BUFFER_ID_TO_PHANTOM = new ConcurrentHashMap<>(); - private static final ReferenceQueue PHANTOM_REFERENCE_QUEUE = new ReferenceQueue<>(); - private static final ThreadPoolExecutor CLEANUP_THREAD = ThreadUtil.makeSingleDaemonThreadPool("GLBuffer Cleanup"); - - - protected int id; - public final int getId() { return this.id; } - protected int size = 0; - public int getSize() { return this.size; } - protected boolean bufferStorage; - public final boolean isBufferStorage() { return this.bufferStorage; } - protected boolean isMapped = false; - - - - //==============// - // constructors // - //==============// - - static { CLEANUP_THREAD.execute(() -> runPhantomReferenceCleanupLoop()); } - - public GLBuffer(boolean isBufferStorage) { this.create(isBufferStorage); } - - - - //=========// - // methods // - //=========// - - // Should be override by subclasses - public int getBufferBindingTarget() { return GL32.GL_COPY_READ_BUFFER; } - - public void bind() { GL32.glBindBuffer(this.getBufferBindingTarget(), this.id); } - public void unbind() { GL32.glBindBuffer(this.getBufferBindingTarget(), 0); } - - - - //====================// - // create and destroy // - //====================// - - protected void create(boolean asBufferStorage) - { - if (!GLProxy.runningOnRenderThread()) - { - LodUtil.assertNotReach("Thread ["+Thread.currentThread()+"] tried to create a GLBuffer outside the MC render thread."); - } - - // destroy the old buffer if one is present - // (as of 2024-12-31 James didn't see this happen, but just in case) - if (this.id != 0) - { - destroyBufferIdAsync(this.id); - } - - this.id = GLMC.glGenBuffers(); - this.bufferStorage = asBufferStorage; - bufferCount.getAndIncrement(); - - PhantomReference phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE); - PHANTOM_TO_BUFFER_ID.put(phantom, this.id); - BUFFER_ID_TO_PHANTOM.put(this.id, phantom); - - } - - protected void destroyAsync() - { - if (this.id == 0) - { - // the buffer has already been closed - return; - } - - destroyBufferIdAsync(this.id); - - this.id = 0; - this.size = 0; - } - private static void destroyBufferIdAsync(int id) - { - // remove and clear the phantom reference if present - if (BUFFER_ID_TO_PHANTOM.containsKey(id)) - { - Reference phantom = BUFFER_ID_TO_PHANTOM.get(id); - - // if we are manually closing this buffer, we don't want the phantom reference to accidentally close it again - // this can cause a race condition were we accidentally delete an in-use buffer and cause NVIDIA - // to throw an EXCEPTION_ACCESS_VIOLATION when we attempt to render it - phantom.clear(); - - PHANTOM_TO_BUFFER_ID.remove(phantom); - BUFFER_ID_TO_PHANTOM.remove(id); - } - - GLProxy.queueRunningOnRenderThread(() -> - { - // destroy the buffer if it exists, - // the buffer may not exist if the destroy method is called twice - if (GL32.glIsBuffer(id)) - { - GLMC.glDeleteBuffers(id); - bufferCount.decrementAndGet(); - - if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get()) - { - LOGGER.info("destroyed buffer [" + id + "], remaining: [" + BUFFER_ID_TO_PHANTOM.size() + "]"); - } - } - }); - } - - - - //==================// - // buffer uploading // - //==================// - - /** - * Assumes the GL Context is already bound.
- * Will create the VBO if one exist. - */ - public void uploadBuffer(ByteBuffer bb, EDhApiGpuUploadMethod uploadMethod, int maxExpansionSize, int bufferHint) - { - LodUtil.assertTrue(!uploadMethod.useEarlyMapping, "UploadMethod signal that this should use Mapping instead of uploadBuffer!"); - int bbSize = bb.limit() - bb.position(); - if (bbSize > maxExpansionSize) - { - LodUtil.assertNotReach("maxExpansionSize is [" + maxExpansionSize + "] but buffer size is [" + bbSize + "]!"); - } - - // Don't upload an empty buffer - if (bbSize == 0) - { - return; - } - - // make sure the buffer is ready for uploading - this.createOrChangeBufferTypeForUpload(uploadMethod); - - switch (uploadMethod) - { - //case NONE: - // return; - case AUTO: - LodUtil.assertNotReach("GpuUploadMethod AUTO must be resolved before call to uploadBuffer()!"); - case BUFFER_STORAGE: - this.uploadBufferStorage(bb, bufferHint); - break; - case DATA: - this.uploadBufferData(bb, bufferHint); - break; - case SUB_DATA: - this.uploadSubData(bb, maxExpansionSize, bufferHint); - break; - default: - LodUtil.assertNotReach("Unknown GpuUploadMethod!"); - } - } - /** Requires the buffer to be bound */ - protected void uploadBufferStorage(ByteBuffer bb, int bufferStorageHint) - { - LodUtil.assertTrue(this.bufferStorage, "Buffer is not bufferStorage but its trying to use bufferStorage upload method!"); - - int bbSize = bb.limit() - bb.position(); - this.destroyAsync(); - this.create(true); - this.bind(); - GL44.glBufferStorage(this.getBufferBindingTarget(), bb, 0); - this.size = bbSize; - } - /** Requires the buffer to be bound */ - protected void uploadBufferData(ByteBuffer bb, int bufferDataHint) - { - LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use bufferData upload method!"); - - int bbSize = bb.limit() - bb.position(); - GL32.glBufferData(this.getBufferBindingTarget(), bb, bufferDataHint); - this.size = bbSize; - } - /** Requires the buffer to be bound */ - protected void uploadSubData(ByteBuffer bb, int maxExpansionSize, int bufferDataHint) - { - LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use subData upload method!"); - - int bbSize = bb.limit() - bb.position(); - if (this.size < bbSize || this.size > bbSize * BUFFER_SHRINK_TRIGGER) - { - int newSize = (int) (bbSize * BUFFER_EXPANSION_MULTIPLIER); - if (newSize > maxExpansionSize) newSize = maxExpansionSize; - GL32.glBufferData(this.getBufferBindingTarget(), newSize, bufferDataHint); - this.size = newSize; - } - GL32.glBufferSubData(this.getBufferBindingTarget(), 0, bb); - } - - - - //===========// - // overrides // - //===========// - - @Override - public void close() { this.destroyAsync(); } - - @Override - public String toString() - { - return (this.bufferStorage ? "" : "Static-") + this.getClass().getSimpleName() + - "[id:" + this.id + ",size:" + this.size + (this.isMapped ? ",MAPPED" : "") + "]"; - } - - - - //================// - // helper methods // - //================// - - /** - * Makes sure the buffer exists and is of the correct format - * before uploading. - */ - private void createOrChangeBufferTypeForUpload(EDhApiGpuUploadMethod uploadMethod) - { - // create/change the buffer type if necessary - if (uploadMethod.useBufferStorage != this.bufferStorage) - { - // recreate if the buffer storage type changed - this.bind(); - this.destroyAsync(); - this.create(uploadMethod.useBufferStorage); - this.bind(); - } - else - { - // Prevent uploading to the null buffer (ID 0). - // This can happen if the buffer was deleted previously. - if (this.id == 0) - { - this.create(this.bufferStorage); - } - - this.bind(); - } - } - - - - //================// - // static cleanup // - //================// - - private static void runPhantomReferenceCleanupLoop() - { - while (true) - { - try - { - try - { - Thread.sleep(PHANTOM_REF_CHECK_TIME_IN_MS); - } - catch (InterruptedException ignore) { } - - - Reference phantomRef = PHANTOM_REFERENCE_QUEUE.poll(); - while (phantomRef != null) - { - // destroy the buffer if it hasn't been cleared yet - if (PHANTOM_TO_BUFFER_ID.containsKey(phantomRef)) - { - int id = PHANTOM_TO_BUFFER_ID.get(phantomRef); - destroyBufferIdAsync(id); - //LOGGER.warn("Buffer Phantom collected, ID: ["+id+"]"); - } - - phantomRef = PHANTOM_REFERENCE_QUEUE.poll(); - } - } - catch (Exception e) - { - LOGGER.error("Unexpected error in buffer cleanup thread: [" + e.getMessage() + "].", e); - } - } - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java deleted file mode 100644 index 9ccd96baa..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLElementBuffer.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.buffer; - -import org.lwjgl.opengl.GL32; - -/** - * This is a container for a OpenGL - * VBO (Vertex Buffer Object). - * - * @author James Seibel - * @version 11-20-2021 - */ -public class GLElementBuffer extends GLBuffer -{ - /** - * When uploading to a buffer that is too small, recreate it this many times - * bigger than the upload payload - */ - protected int indicesCount = 0; - public int getIndicesCount() { return this.indicesCount; } - protected int type = GL32.GL_UNSIGNED_INT; - public int getType() { return type; } - - public GLElementBuffer(boolean isBufferStorage) - { - super(isBufferStorage); - } - - @Override - public void destroyAsync() - { - super.destroyAsync(); - this.indicesCount = 0; - } - - @Override - public int getBufferBindingTarget() - { - return GL32.GL_ELEMENT_ARRAY_BUFFER; - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java deleted file mode 100644 index aedb0fb4a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/GLVertexBuffer.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.buffer; - -import java.nio.ByteBuffer; - -import org.lwjgl.opengl.GL32; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; - -/** - * This is a container for a OpenGL - * VBO (Vertex Buffer Object). - * - * @author James Seibel - * @version 11-20-2021 - */ -public class GLVertexBuffer extends GLBuffer -{ - /** - * When uploading to a buffer that is too small, recreate it this many times - * bigger than the upload payload - */ - protected int vertexCount = 0; - public int getVertexCount() { return this.vertexCount; } - // FIXME: This setter is needed for premapping buffer to manually set the vertexCount. Fix this. - public void setVertexCount(int vertexCount) { this.vertexCount = vertexCount; } - - - public GLVertexBuffer(boolean isBufferStorage) - { - super(isBufferStorage); - } - - - - @Override - public void destroyAsync() - { - super.destroyAsync(); - this.vertexCount = 0; - } - - @Override - public int getBufferBindingTarget() { return GL32.GL_ARRAY_BUFFER; } - - /** - * bufferSize is the number of shared verticies.
- * This number will be higher when actually rendered since each box's face needs 2 triangles - * with 2 shared verticies. - */ - public void uploadBuffer(ByteBuffer byteBuffer, int bufferSize, EDhApiGpuUploadMethod uploadMethod, int maxExpensionSize) - { - if (bufferSize < 0) - { - throw new IllegalArgumentException("VertCount is negative!"); - } - - // If size is zero, just ignore it. - if (byteBuffer.limit() - byteBuffer.position() != 0) - { - boolean useBuffStorage = uploadMethod.useBufferStorage; - super.uploadBuffer(byteBuffer, uploadMethod, maxExpensionSize, useBuffStorage ? 0 : GL32.GL_STATIC_DRAW); - } - - // /4 to get the number of cubes - // *6 to get the number of verticies (2 triangles, 3 verticies each) - this.vertexCount = (bufferSize / 4) * 6; - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java deleted file mode 100644 index 3176c01ea..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/buffer/QuadElementBuffer.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.buffer; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLEnums; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.logging.DhLogger; -import org.lwjgl.opengl.GL32; -import org.lwjgl.system.MemoryUtil; - -import java.lang.invoke.MethodHandles; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** AKA Index Buffer TODO RENAME */ -public class QuadElementBuffer extends GLElementBuffer -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - - - //=============// - // constructor // - //=============// - //region - - public QuadElementBuffer() { super(false); } - - public void reserve(int quadCount) - { - if (quadCount < 0) - { - throw new IllegalArgumentException("quadCount must be greater than 0"); - } - if (quadCount == 0) - { - // shouldn't happen, but just in case - return; - } - - this.indicesCount = quadCount * 6; // 2 triangles per quad - if (this.indicesCount >= this.getCapacity() - && this.indicesCount < this.getCapacity() * BUFFER_SHRINK_TRIGGER) - { - return; - } - int vertexCount = quadCount * 4; // 4 vertices per quad - - if (vertexCount < 255) - { - // Reserve 1 for the reset index - this.type = GL32.GL_UNSIGNED_BYTE; - } - else if (vertexCount < 65535) - { - // Reserve 1 for the reset index - this.type = GL32.GL_UNSIGNED_SHORT; - } - else - { - this.type = GL32.GL_UNSIGNED_INT; - } - - ByteBuffer buffer = MemoryUtil.memAlloc(this.indicesCount * GLEnums.getTypeSize(this.type)); - buildBuffer(quadCount, buffer, this.type); - this.bind(); - super.uploadBuffer(buffer, EDhApiGpuUploadMethod.DATA, - this.indicesCount * GLEnums.getTypeSize(this.type), GL32.GL_STATIC_DRAW); - - MemoryUtil.memFree(buffer); - } - - //endregion - - - - //=========// - // getters // - //=========// - //region - - public int getCapacity() { return super.getSize() / GLEnums.getTypeSize(this.getType()); } - - //endregion - - - - //==========// - // building // - //==========// - //region - - public static void buildBuffer(int quadCount, ByteBuffer buffer, int type) - { - switch (type) - { - case GL32.GL_UNSIGNED_BYTE: - buildBufferByte(quadCount, buffer); - break; - case GL32.GL_UNSIGNED_SHORT: - buildBufferShort(quadCount, buffer); - break; - case GL32.GL_UNSIGNED_INT: - buildBufferInt(quadCount, buffer); - break; - default: - throw new IllegalStateException("Unknown buffer type: [" + type + "]."); - } - } - - private static void buildBufferByte(int quadCount, ByteBuffer buffer) - { - for (int i = 0; i < quadCount; i++) - { - int vIndex = i * 4; - // First triangle - buffer.put((byte) (vIndex)); - buffer.put((byte) (vIndex + 1)); - buffer.put((byte) (vIndex + 2)); - // Second triangle - buffer.put((byte) (vIndex + 2)); - buffer.put((byte) (vIndex + 3)); - buffer.put((byte) (vIndex)); - } - if (buffer.hasRemaining()) - { - throw new IllegalStateException("QuadElementBuffer is not full somehow after building"); - } - buffer.rewind(); - } - private static void buildBufferShort(int quadCount, ByteBuffer buffer) - { - for (int i = 0; i < quadCount; i++) - { - int vIndex = i * 4; - // First triangle - buffer.putShort((short) (vIndex)); - buffer.putShort((short) (vIndex + 1)); - buffer.putShort((short) (vIndex + 2)); - // Second triangle - buffer.putShort((short) (vIndex + 2)); - buffer.putShort((short) (vIndex + 3)); - buffer.putShort((short) (vIndex)); - } - if (buffer.hasRemaining()) - { - throw new IllegalStateException("QuadElementBuffer is not full somehow after building"); - } - buffer.rewind(); - } - private static void buildBufferInt(int quadCount, ByteBuffer buffer) - { - for (int i = 0; i < quadCount; i++) - { - int vIndex = i * 4; - // First triangle - buffer.putInt(vIndex); - buffer.putInt(vIndex + 1); - buffer.putInt(vIndex + 2); - // Second triangle - buffer.putInt(vIndex + 2); - buffer.putInt(vIndex + 3); - buffer.putInt(vIndex); - } - if (buffer.hasRemaining()) - { - throw new IllegalStateException("QuadElementBuffer is not full somehow after building"); - } - buffer.rewind(); - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/Shader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/Shader.java deleted file mode 100644 index 7258cf4ee..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/Shader.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.shader; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.ByteBuffer; - -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import org.lwjgl.PointerBuffer; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL32C; -import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; -import org.lwjgl.system.NativeType; - -/** - * This object holds a OpenGL reference to a shader - * and allows for reading in and compiling a shader file. - */ -public class Shader -{ - private static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) - .build(); - - - /** OpenGL shader ID */ - public final int id; - - - - //==============// - // constructors // - //==============// - //region - - /** - * Creates a shader with specified type. - * - * @param type Either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. - * @param sourceString File path of the shader - * @throws RuntimeException if the shader fails to compile - */ - public Shader(int type, String sourceString) - { - LOGGER.info("Loading shader with type: ["+type+"]"); - LOGGER.debug("Source: \n["+sourceString+"]"); - if (sourceString == null || sourceString.isEmpty()) - { - throw new IllegalArgumentException("No shader source given."); - } - - // Create an empty shader object - this.id = GL32.glCreateShader(type); - if (this.id == 0) - { - throw new IllegalArgumentException("Failed to create shader with type ["+type+"] and Source: \n["+sourceString+"]."); - } - - safeShaderSource(this.id, sourceString); - GL32.glCompileShader(this.id); - // check if the shader compiled - int status = GL32.glGetShaderi(this.id, GL32.GL_COMPILE_STATUS); - if (status != GL32.GL_TRUE) - { - - String message = "Shader compiler error. Details: [" + GL32.glGetShaderInfoLog(this.id) + "]\n"; - message += "Source: \n[" + sourceString + "]"; - this.free(); // important! - throw new RuntimeException(message); - } - LOGGER.info("Shader loaded sucessfully."); - } - - //endregion - - - - //=========// - // helpers // - //=========// - //region - - /** - * Identical in function to {@link GL32C#glShaderSource(int, CharSequence)} but - * passes a null pointer for string length to force the driver to rely on the null - * terminator for string length. This is a workaround for an apparent flaw with some - * AMD drivers that don't receive or interpret the length correctly, resulting in - * an access violation when the driver tries to read past the string memory. - * - *

Hat tip to fewizz for the find and the fix. - * - *

Source: https://github.com/vram-guild/canvas/commit/820bf754092ccaf8d0c169620c2ff575722d7d96 - */ - private static void safeShaderSource(@NativeType("GLuint") int glId, @NativeType("GLchar const **") CharSequence source) - { - final MemoryStack stack = MemoryStack.stackGet(); - final int stackPointer = stack.getPointer(); - - try - { - final ByteBuffer sourceBuffer = MemoryUtil.memUTF8(source, true); - final PointerBuffer pointers = stack.mallocPointer(1); - pointers.put(sourceBuffer); - - GL32.nglShaderSource(glId, 1, pointers.address0(), 0); - org.lwjgl.system.APIUtil.apiArrayFree(pointers.address0(), 1); - } - finally - { - stack.setPointer(stackPointer); - } - } - - public void free() { GL32.glDeleteShader(this.id); } - - public static String loadFile(String path, boolean absoluteFilePath) - { - StringBuilder stringBuilder = new StringBuilder(); - - try - { - // open the file - InputStream in; - if (absoluteFilePath) - { - // Throws FileNotFoundException - in = new FileInputStream(path); // Note: this should use OS path seperator - } - else - { - in = Shader.class.getClassLoader().getResourceAsStream(path); // Note: path seperator should be '/' - if (in == null) - { - throw new FileNotFoundException("Shader file not found in resource: " + path); - } - } - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - - // read in the file - String line; - while ((line = reader.readLine()) != null) - { - stringBuilder.append(line).append("\n"); - } - } - catch (IOException e) - { - throw new RuntimeException("Unable to load shader from file [" + path + "]. Error: " + e.getMessage()); - } - - return stringBuilder.toString(); - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java deleted file mode 100644 index 08ea181dc..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/shader/ShaderProgram.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.shader; - -import java.awt.Color; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; - -import com.seibel.distanthorizons.api.objects.math.DhApiVec3i; -import org.lwjgl.opengl.GL32; -import org.lwjgl.system.MemoryStack; - -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.math.Vec3f; - - -/** - * This object holds the reference to a OpenGL shader program - * and contains a few methods that can be used with OpenGL shader programs. - * The reason for many of these simple wrapper methods is as reminders of what - * can (and needs to be) done with a shader program. - */ -public class ShaderProgram -{ - /** Stores the handle of the program. */ - public final int id; - - - - //=============// - // constructor // - //=============// - //region - - public ShaderProgram(String vertResourcePath, String fragResourcePath, String attribute) { this(vertResourcePath, fragResourcePath, new String[]{ attribute }); } - /** - * @param vertResourcePath the relative path the vertex shader should be found - * @param fragResourcePath the relative path the fragment shader should be found - */ - public ShaderProgram(String vertResourcePath, String fragResourcePath, String[] attributes) - { - this.id = GL32.glCreateProgram(); - - { - String shaderString = Shader.loadFile(vertResourcePath, false); - Shader vertShader = new Shader(GL32.GL_VERTEX_SHADER, shaderString); - GL32.glAttachShader(this.id, vertShader.id); - vertShader.free(); - } - - { - String shaderString = Shader.loadFile(fragResourcePath, false); - Shader fragShader = new Shader(GL32.GL_FRAGMENT_SHADER, shaderString); - GL32.glAttachShader(this.id, fragShader.id); - fragShader.free(); - } - - for (int i = 0; i < attributes.length; i++) - { - GL32.glBindAttribLocation(this.id, i, attributes[i]); - } - GL32.glLinkProgram(this.id); - - int status = GL32.glGetProgrami(this.id, GL32.GL_LINK_STATUS); - if (status != GL32.GL_TRUE) - { - String message = "Shader Link Error. Details: " + GL32.glGetProgramInfoLog(this.id); - this.free(); // important! - throw new RuntimeException(message); - } - GL32.glUseProgram(this.id); // This HAVE to be a direct call to prevent calling the overloaded version - } - - //endregion - - - - //=========// - // binding // - //=========// - //region - - public void bind() { GL32.glUseProgram(this.id); } - public void unbind() { GL32.glUseProgram(0); } - - public void free() { GL32.glDeleteProgram(this.id); } - - //endregion - - - - //============// - // attributes // - //============// - //region - - /** - * WARNING: Slow native call! Cache it if possible! - * Gets the location of an attribute variable with specified name. - * Calls GL20.glGetAttribLocation(id, name) - * - * @param name Attribute name - * @return Location of the attribute - * @throws RuntimeException if attribute not found - */ - public int getAttributeLocation(CharSequence name) - { - int i = GL32.glGetAttribLocation(id, name); - if (i == -1) throw new RuntimeException("Attribute name not found: " + name); - return i; - } - /** - * Same as above but without throwing errors.
- * Returns -1 if the attribute doesn't exist or has been optimized out. - */ - public int tryGetAttributeLocation(CharSequence name) - { return GL32.glGetAttribLocation(this.id, name); } - - //endregion - - - - //==========// - // uniforms // - //==========// - //region - - /** - * WARNING: Slow native call! Cache it if possible! - * Gets the location of a uniform variable with specified name. - * Calls GL20.glGetUniformLocation(id, name) - * - * @param name Uniform name - * @return Location of the Uniform - * @throws RuntimeException if uniform not found - */ - public int getUniformLocation(CharSequence name) throws RuntimeException - { - int i = GL32.glGetUniformLocation(id, name); - if (i == -1) - { - throw new RuntimeException("Uniform name not found: " + name); - } - return i; - } - - // Same as above but without throwing errors. - // Return -1 if uniform doesn't exist or has been optimized out - public int tryGetUniformLocation(CharSequence name) - { return GL32.glGetUniformLocation(this.id, name); } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, boolean value) { GL32.glUniform1i(location, value ? 1 : 0); } - /** @see ShaderProgram#setUniform(int, boolean) */ - public void trySetUniform(int location, boolean value) { if (location != -1) { this.setUniform(location, value); } } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, int value) { GL32.glUniform1i(location, value); } - /** @see ShaderProgram#setUniform(int, int) */ - public void trySetUniform(int location, int value) { if (location != -1) { this.setUniform(location, value); } } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, float value) { GL32.glUniform1f(location, value); } - /** @see ShaderProgram#setUniform(int, float) */ - public void trySetUniform(int location, float value) { if (location != -1) { this.setUniform(location, value); } } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, Vec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); } - /** @see ShaderProgram#setUniform(int, Vec3f) */ - public void trySetUniform(int location, Vec3f value) { if (location != -1) { this.setUniform(location, value); } } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, DhApiVec3i value) { GL32.glUniform3i(location, value.x, value.y, value.z); } - /** @see ShaderProgram#setUniform(int, Mat4f) */ - public void trySetUniform(int location, DhApiVec3i value) { if (location != -1) { this.setUniform(location, value); } } - - /** Requires a bound ShaderProgram. */ - public void setUniform(int location, Mat4f value) - { - try (MemoryStack stack = MemoryStack.stackPush()) - { - FloatBuffer buffer = stack.mallocFloat(4 * 4); - value.store(buffer); - GL32.glUniformMatrix4fv(location, false, buffer); - } - } - /** @see ShaderProgram#setUniform(int, Mat4f) */ - public void trySetUniform(int location, Mat4f value) { if (location != -1) { this.setUniform(location, value); } } - - /** - * Converts the color's RGBA values into values between 0 and 1.
- * Requires a bound ShaderProgram. - */ - public void setUniform(int location, Color value) - { - GL32.glUniform4f(location, - value.getRed() / 256.0f, - value.getGreen() / 256.0f, - value.getBlue() / 256.0f, - value.getAlpha() / 256.0f); - } - /** @see ShaderProgram#setUniform(int, Color) */ - public void trySetUniform(int location, Color value) { if (location != -1) { this.setUniform(location, value); } } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DHDepthTexture.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DHDepthTexture.java deleted file mode 100644 index 865b95821..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DHDepthTexture.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL11C; -import org.lwjgl.opengl.GL13C; -import org.lwjgl.opengl.GL43C; - -import java.nio.ByteBuffer; - -public class DHDepthTexture -{ - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private int id; - public DHDepthTexture(int width, int height, EDhDepthBufferFormat format) - { - this.id = GL43C.glGenTextures(); - - this.resize(width, height, format); - - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MIN_FILTER, GL11C.GL_NEAREST); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MAG_FILTER, GL11C.GL_NEAREST); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_WRAP_S, GL13C.GL_CLAMP_TO_EDGE); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_WRAP_T, GL13C.GL_CLAMP_TO_EDGE); - - // disable mip-mapping since DH is just going to draw straight to the screen - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_BASE_LEVEL, 0); - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_MAX_LEVEL, 0); - - GL43C.glBindTexture(GL43C.GL_TEXTURE_2D, 0); - } - - // For internal use by Iris for copying data. Do not use this in DH. - public DHDepthTexture(int id) { this.id = id; } - - public void resize(int width, int height, EDhDepthBufferFormat format) - { - GL43C.glBindTexture(GL43C.GL_TEXTURE_2D, this.getTextureId()); - GL43C.glTexImage2D(GL11C.GL_TEXTURE_2D, 0, format.getGlInternalFormat(), width, height, 0, - format.getGlType(), format.getGlFormat(), (ByteBuffer) null); - } - - public int getTextureId() - { - if (this.id == -1) - { - throw new IllegalStateException("Depth texture does not exist!"); - } - - return this.id; - } - - public void destroy() - { - GLMC.glDeleteTextures(this.getTextureId()); - this.id = -1; - } - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhColorTexture.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhColorTexture.java deleted file mode 100644 index cbce810c1..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhColorTexture.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.joml.Vector2i; -import org.lwjgl.opengl.GL11C; -import org.lwjgl.opengl.GL13C; -import org.lwjgl.opengl.GL43C; - -import java.nio.ByteBuffer; - -public class DhColorTexture -{ - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private final EDhInternalTextureFormat internalFormat; - private final EDhPixelFormat format; - private final EDhPixelType type; - private int width; - private int height; - - private boolean isValid; - /** AKA, the OpenGL name of this texture */ - private final int id; - - private static final ByteBuffer NULL_BUFFER = null; - - - - //=============// - // constructor // - //=============// - - public DhColorTexture(Builder builder) - { - this.isValid = true; - - this.internalFormat = builder.internalFormat; - this.format = builder.format; - this.type = builder.type; - - this.width = builder.width; - this.height = builder.height; - - this.id = GL43C.glGenTextures(); - - boolean isPixelFormatInteger = builder.internalFormat.getPixelFormat().isInteger(); - this.setupTexture(this.id, builder.width, builder.height, !isPixelFormatInteger); // this binds the texture - - // Clean up after ourselves - // This is strictly defensive to ensure that other buggy code doesn't tamper with our textures - GL43C.glBindTexture(GL43C.GL_TEXTURE_2D, 0); - } - - - - //=========// - // methods // - //=========// - - private void setupTexture(int id, int width, int height, boolean allowsLinear) - { - this.resizeTexture(id, width, height); - - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MIN_FILTER, allowsLinear ? GL11C.GL_LINEAR : GL11C.GL_NEAREST); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_MAG_FILTER, allowsLinear ? GL11C.GL_LINEAR : GL11C.GL_NEAREST); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_WRAP_S, GL13C.GL_CLAMP_TO_EDGE); - GL43C.glTexParameteri(GL11C.GL_TEXTURE_2D, GL11C.GL_TEXTURE_WRAP_T, GL13C.GL_CLAMP_TO_EDGE); - - // disable mip-mapping since DH is just going to draw straight to the screen - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_BASE_LEVEL, 0); - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_MAX_LEVEL, 0); - } - - private void resizeTexture(int texture, int width, int height) - { - GL43C.glBindTexture(GL43C.GL_TEXTURE_2D, texture); - GL43C.glTexImage2D(GL11C.GL_TEXTURE_2D, 0, this.internalFormat.getGlFormat(), width, height, 0, this.format.getGlFormat(), this.type.getGlFormat(), NULL_BUFFER); - } - - void resize(Vector2i textureScaleOverride) { this.resize(textureScaleOverride.x, textureScaleOverride.y); } - - // Package private, call CompositeRenderTargets#resizeIfNeeded instead. - public void resize(int width, int height) - { - this.throwIfInvalid(); - - this.width = width; - this.height = height; - - this.resizeTexture(this.id, width, height); - } - - public EDhInternalTextureFormat getInternalFormat() { return this.internalFormat; } - - public int getTextureId() - { - this.throwIfInvalid(); - return this.id; - } - - public int getWidth() { return this.width; } - - public int getHeight() { return this.height; } - - public void destroy() - { - this.throwIfInvalid(); - this.isValid = false; - - GLMC.glDeleteTextures(this.id); - } - - /** @throws IllegalStateException if the texture isn't valid */ - private void throwIfInvalid() - { - if (!this.isValid) - { - throw new IllegalStateException("Attempted to use a deleted composite render target"); - } - } - - public static Builder builder() { return new Builder(); } - - - - //================// - // helper classes // - //================// - - public static class Builder - { - private EDhInternalTextureFormat internalFormat = EDhInternalTextureFormat.RGBA8; - private int width = 0; - private int height = 0; - private EDhPixelFormat format = EDhPixelFormat.RGBA; - private EDhPixelType type = EDhPixelType.UNSIGNED_BYTE; - - private Builder() - { - // No-op - } - - public Builder setInternalFormat(EDhInternalTextureFormat format) - { - this.internalFormat = format; - return this; - } - - public Builder setDimensions(int width, int height) - { - if (width <= 0) - { - throw new IllegalArgumentException("Width must be greater than zero"); - } - - if (height <= 0) - { - throw new IllegalArgumentException("Height must be greater than zero"); - } - - this.width = width; - this.height = height; - - return this; - } - - public Builder setPixelFormat(EDhPixelFormat pixelFormat) - { - this.format = pixelFormat; - return this; - } - - public Builder setPixelType(EDhPixelType pixelType) - { - this.type = pixelType; - return this; - } - - public DhColorTexture build() { return new DhColorTexture(this); } - - } -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhFramebuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhFramebuffer.java deleted file mode 100644 index 2f40d9530..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/DhFramebuffer.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import it.unimi.dsi.fastutil.ints.Int2IntArrayMap; -import it.unimi.dsi.fastutil.ints.Int2IntMap; -import org.lwjgl.opengl.GL32; - -public class DhFramebuffer implements IDhApiFramebuffer -{ - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - private final Int2IntMap attachments; - private final int maxDrawBuffers; - private final int maxColorAttachments; - private boolean hasDepthAttachment; - private int id; - - - - //=============// - // constructor // - //=============// - - public DhFramebuffer() - { - this.id = GL32.glGenFramebuffers(); - - this.attachments = new Int2IntArrayMap(); - this.maxDrawBuffers = GL32.glGetInteger(GL32.GL_MAX_DRAW_BUFFERS); - this.maxColorAttachments = GL32.glGetInteger(GL32.GL_MAX_COLOR_ATTACHMENTS); - this.hasDepthAttachment = false; - } - - /** For internal use by Iris, do not remove. */ - public DhFramebuffer(int id) - { - this.id = id; - - this.attachments = new Int2IntArrayMap(); - this.maxDrawBuffers = GL32.glGetInteger(GL32.GL_MAX_DRAW_BUFFERS); - this.maxColorAttachments = GL32.glGetInteger(GL32.GL_MAX_COLOR_ATTACHMENTS); - this.hasDepthAttachment = false; - } - - - - //=========// - // methods // - //=========// - - @Override - public void addDepthAttachment(int textureId, boolean isCombinedStencil) - { - this.bind(); - - int depthAttachment = isCombinedStencil ? GL32.GL_DEPTH_STENCIL_ATTACHMENT : GL32.GL_DEPTH_ATTACHMENT; - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, depthAttachment, GL32.GL_TEXTURE_2D, textureId, 0); - - this.hasDepthAttachment = true; - } - - @Override - public void addColorAttachment(int textureIndex, int textureId) - { - this.bind(); - - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0 + textureIndex, GL32.GL_TEXTURE_2D, textureId, 0); - this.attachments.put(textureIndex, textureId); - } - - public void noDrawBuffers() - { - this.bind(); - GL32.glDrawBuffers(new int[]{GL32.GL_NONE}); - } - - public void drawBuffers(int[] buffers) - { - int[] glBuffers = new int[buffers.length]; - int index = 0; - - if (buffers.length > this.maxDrawBuffers) - { - throw new IllegalArgumentException("Cannot write to more than " + this.maxDrawBuffers + " draw buffers on this GPU"); - } - - for (int buffer : buffers) - { - if (buffer >= this.maxColorAttachments) - { - throw new IllegalArgumentException("Only " + this.maxColorAttachments + " color attachments are supported on this GPU, but an attempt was made to write to a color attachment with index " + buffer); - } - - glBuffers[index++] = GL32.GL_COLOR_ATTACHMENT0 + buffer; - } - - this.bind(); - GL32.glDrawBuffers(new int[]{GL32.GL_NONE}); - } - - public void readBuffer(int buffer) - { - this.bind(); - GL32.glReadBuffer(GL32.GL_COLOR_ATTACHMENT0 + buffer); - } - - public int getColorAttachment(int index) { return this.attachments.get(index); } - - public boolean hasDepthAttachment() { return this.hasDepthAttachment; } - - @Override - public void bind() - { - if (this.id == -1) - { - throw new IllegalStateException("Framebuffer does not exist!"); - } - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.id); - } - - public void bindAsReadBuffer() { GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.id); } - - public void bindAsDrawBuffer() { GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, this.id); } - - @Override - public void destroy() - { - GL32.glDeleteFramebuffers(this.id); - this.id = -1; - } - - @Override - public int getStatus() - { - this.bind(); - int status = GL32.glCheckFramebufferStatus(GL32.GL_FRAMEBUFFER); - return status; - } - - @Override - public int getId() { return this.id; } - - - - //=============// - // API methods // - //=============// - - public boolean overrideThisFrame() { return true; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhDepthBufferFormat.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhDepthBufferFormat.java deleted file mode 100644 index 537ea939a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhDepthBufferFormat.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL30C; -import org.lwjgl.opengl.GL43C; - -public enum EDhDepthBufferFormat -{ - DEPTH(false), - DEPTH16(false), - DEPTH24(false), - DEPTH32(false), - DEPTH32F(false), - DEPTH_STENCIL(true), - DEPTH24_STENCIL8(true), - DEPTH32F_STENCIL8(true); - - - - private final boolean combinedStencil; - - EDhDepthBufferFormat(boolean combinedStencil) { this.combinedStencil = combinedStencil; } - - - - @Nullable - public static EDhDepthBufferFormat fromGlEnum(int glenum) - { - switch (glenum) - { - case GL30C.GL_DEPTH_COMPONENT: - return EDhDepthBufferFormat.DEPTH; - case GL30C.GL_DEPTH_COMPONENT16: - return EDhDepthBufferFormat.DEPTH16; - case GL30C.GL_DEPTH_COMPONENT24: - return EDhDepthBufferFormat.DEPTH24; - case GL30C.GL_DEPTH_COMPONENT32: - return EDhDepthBufferFormat.DEPTH32; - case GL30C.GL_DEPTH_COMPONENT32F: - return EDhDepthBufferFormat.DEPTH32F; - case GL30C.GL_DEPTH_STENCIL: - return EDhDepthBufferFormat.DEPTH_STENCIL; - case GL30C.GL_DEPTH24_STENCIL8: - return EDhDepthBufferFormat.DEPTH24_STENCIL8; - case GL30C.GL_DEPTH32F_STENCIL8: - return EDhDepthBufferFormat.DEPTH32F_STENCIL8; - default: - return null; - } - } - - public static EDhDepthBufferFormat fromGlEnumOrDefault(int glenum) - { - EDhDepthBufferFormat format = fromGlEnum(glenum); - if (format == null) - { - // yolo, just assume it's GL_DEPTH_COMPONENT - return EDhDepthBufferFormat.DEPTH; - } - return format; - } - - public int getGlInternalFormat() - { - switch (this) - { - case DEPTH: - return GL30C.GL_DEPTH_COMPONENT; - case DEPTH16: - return GL30C.GL_DEPTH_COMPONENT16; - case DEPTH24: - return GL30C.GL_DEPTH_COMPONENT24; - case DEPTH32: - return GL30C.GL_DEPTH_COMPONENT32; - case DEPTH32F: - return GL30C.GL_DEPTH_COMPONENT32F; - case DEPTH_STENCIL: - return GL30C.GL_DEPTH_STENCIL; - case DEPTH24_STENCIL8: - return GL30C.GL_DEPTH24_STENCIL8; - case DEPTH32F_STENCIL8: - return GL30C.GL_DEPTH32F_STENCIL8; - } - - throw new AssertionError("unreachable"); - } - - public int getGlType() { return isCombinedStencil() ? GL30C.GL_DEPTH_STENCIL : GL30C.GL_DEPTH_COMPONENT; } - - public int getGlFormat() - { - switch (this) - { - case DEPTH: - case DEPTH16: - return GL43C.GL_UNSIGNED_SHORT; - case DEPTH24: - case DEPTH32: - return GL43C.GL_UNSIGNED_INT; - case DEPTH32F: - return GL30C.GL_FLOAT; - case DEPTH_STENCIL: - case DEPTH24_STENCIL8: - return GL30C.GL_UNSIGNED_INT_24_8; - case DEPTH32F_STENCIL8: - return GL30C.GL_FLOAT_32_UNSIGNED_INT_24_8_REV; - } - - throw new AssertionError("unreachable"); - } - - public boolean isCombinedStencil() { return combinedStencil; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhInternalTextureFormat.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhInternalTextureFormat.java deleted file mode 100644 index b307aafa6..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhInternalTextureFormat.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import org.lwjgl.opengl.GL11C; -import org.lwjgl.opengl.GL30C; -import org.lwjgl.opengl.GL31C; - -import java.util.Locale; -import java.util.Optional; - -public enum EDhInternalTextureFormat -{ - RGBA(GL11C.GL_RGBA, EGlVersion.GL_11, EDhPixelFormat.RGBA), - - // 8-bit normalized - R8(GL30C.GL_R8, EGlVersion.GL_30, EDhPixelFormat.RED), - RG8(GL30C.GL_RG8, EGlVersion.GL_30, EDhPixelFormat.RG), - RGB8(GL11C.GL_RGB8, EGlVersion.GL_11, EDhPixelFormat.RGB), - RGBA8(GL11C.GL_RGBA8, EGlVersion.GL_11, EDhPixelFormat.RGBA), - - // 8-bit signed normalized - R8_SNORM(GL31C.GL_R8_SNORM, EGlVersion.GL_31, EDhPixelFormat.RED), - RG8_SNORM(GL31C.GL_RG8_SNORM, EGlVersion.GL_31, EDhPixelFormat.RG), - RGB8_SNORM(GL31C.GL_RGB8_SNORM, EGlVersion.GL_31, EDhPixelFormat.RGB), - RGBA8_SNORM(GL31C.GL_RGBA8_SNORM, EGlVersion.GL_31, EDhPixelFormat.RGBA), - - // 16-bit normalized - R16(GL30C.GL_R16, EGlVersion.GL_30, EDhPixelFormat.RED), - RG16(GL30C.GL_RG16, EGlVersion.GL_30, EDhPixelFormat.RG), - RGB16(GL11C.GL_RGB16, EGlVersion.GL_11, EDhPixelFormat.RGB), - RGBA16(GL11C.GL_RGBA16, EGlVersion.GL_11, EDhPixelFormat.RGBA), - - // 16-bit signed normalized - R16_SNORM(GL31C.GL_R16_SNORM, EGlVersion.GL_31, EDhPixelFormat.RED), - RG16_SNORM(GL31C.GL_RG16_SNORM, EGlVersion.GL_31, EDhPixelFormat.RG), - RGB16_SNORM(GL31C.GL_RGB16_SNORM, EGlVersion.GL_31, EDhPixelFormat.RGB), - RGBA16_SNORM(GL31C.GL_RGBA16_SNORM, EGlVersion.GL_31, EDhPixelFormat.RGBA), - - // 16-bit float - R16F(GL30C.GL_R16F, EGlVersion.GL_30, EDhPixelFormat.RED), - RG16F(GL30C.GL_RG16F, EGlVersion.GL_30, EDhPixelFormat.RG), - RGB16F(GL30C.GL_RGB16F, EGlVersion.GL_30, EDhPixelFormat.RGB), - RGBA16F(GL30C.GL_RGBA16F, EGlVersion.GL_30, EDhPixelFormat.RGBA), - - // 32-bit float - R32F(GL30C.GL_R32F, EGlVersion.GL_30, EDhPixelFormat.RED), - RG32F(GL30C.GL_RG32F, EGlVersion.GL_30, EDhPixelFormat.RG), - RGB32F(GL30C.GL_RGB32F, EGlVersion.GL_30, EDhPixelFormat.RGB), - RGBA32F(GL30C.GL_RGBA32F, EGlVersion.GL_30, EDhPixelFormat.RGBA), - - // 8-bit integer - R8I(GL30C.GL_R8I, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG8I(GL30C.GL_RG8I, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB8I(GL30C.GL_RGB8I, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA8I(GL30C.GL_RGBA8I, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // 8-bit unsigned integer - R8UI(GL30C.GL_R8UI, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG8UI(GL30C.GL_RG8UI, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB8UI(GL30C.GL_RGB8UI, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA8UI(GL30C.GL_RGBA8UI, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // 16-bit integer - R16I(GL30C.GL_R16I, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG16I(GL30C.GL_RG16I, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB16I(GL30C.GL_RGB16I, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA16I(GL30C.GL_RGBA16I, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // 16-bit unsigned integer - R16UI(GL30C.GL_R16UI, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG16UI(GL30C.GL_RG16UI, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB16UI(GL30C.GL_RGB16UI, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA16UI(GL30C.GL_RGBA16UI, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // 32-bit integer - R32I(GL30C.GL_R32I, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG32I(GL30C.GL_RG32I, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB32I(GL30C.GL_RGB32I, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA32I(GL30C.GL_RGBA32I, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // 32-bit unsigned integer - R32UI(GL30C.GL_R32UI, EGlVersion.GL_30, EDhPixelFormat.RED_INTEGER), - RG32UI(GL30C.GL_RG32UI, EGlVersion.GL_30, EDhPixelFormat.RG_INTEGER), - RGB32UI(GL30C.GL_RGB32UI, EGlVersion.GL_30, EDhPixelFormat.RGB_INTEGER), - RGBA32UI(GL30C.GL_RGBA32UI, EGlVersion.GL_30, EDhPixelFormat.RGBA_INTEGER), - - // Mixed - R3_G3_B2(GL11C.GL_R3_G3_B2, EGlVersion.GL_11, EDhPixelFormat.RGB), - RGB5_A1(GL11C.GL_RGB5_A1, EGlVersion.GL_11, EDhPixelFormat.RGBA), - RGB10_A2(GL11C.GL_RGB10_A2, EGlVersion.GL_11, EDhPixelFormat.RGBA), - R11F_G11F_B10F(GL30C.GL_R11F_G11F_B10F, EGlVersion.GL_30, EDhPixelFormat.RGB), - RGB9_E5(GL30C.GL_RGB9_E5, EGlVersion.GL_30, EDhPixelFormat.RGB); - - - - private final int glFormat; - private final EGlVersion minimumGlVersion; - private final EDhPixelFormat expectedPixelFormat; - - - - EDhInternalTextureFormat(int glFormat, EGlVersion minimumGlVersion, EDhPixelFormat expectedPixelFormat) - { - this.glFormat = glFormat; - this.minimumGlVersion = minimumGlVersion; - this.expectedPixelFormat = expectedPixelFormat; - } - - - - public static Optional fromString(String name) - { - try - { - return Optional.of(EDhInternalTextureFormat.valueOf(name.toUpperCase(Locale.US))); - } - catch (IllegalArgumentException e) - { - return Optional.empty(); - } - } - - public int getGlFormat() { return this.glFormat; } - - public EDhPixelFormat getPixelFormat() { return this.expectedPixelFormat; } - - public EGlVersion getMinimumGlVersion() { return this.minimumGlVersion; } - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelFormat.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelFormat.java deleted file mode 100644 index a9bac119f..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelFormat.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import org.lwjgl.opengl.GL11C; -import org.lwjgl.opengl.GL12C; -import org.lwjgl.opengl.GL30C; - -import java.util.Locale; -import java.util.Optional; - -public enum EDhPixelFormat -{ - RED(GL11C.GL_RED, EGlVersion.GL_11, false), - RG(GL30C.GL_RG, EGlVersion.GL_30, false), - RGB(GL11C.GL_RGB, EGlVersion.GL_11, false), - BGR(GL12C.GL_BGR, EGlVersion.GL_12, false), - RGBA(GL11C.GL_RGBA, EGlVersion.GL_11, false), - BGRA(GL12C.GL_BGRA, EGlVersion.GL_12, false), - RED_INTEGER(GL30C.GL_RED_INTEGER, EGlVersion.GL_30, true), - RG_INTEGER(GL30C.GL_RG_INTEGER, EGlVersion.GL_30, true), - RGB_INTEGER(GL30C.GL_RGB_INTEGER, EGlVersion.GL_30, true), - BGR_INTEGER(GL30C.GL_BGR_INTEGER, EGlVersion.GL_30, true), - RGBA_INTEGER(GL30C.GL_RGBA_INTEGER, EGlVersion.GL_30, true), - BGRA_INTEGER(GL30C.GL_BGRA_INTEGER, EGlVersion.GL_30, true); - - - - private final int glFormat; - private final EGlVersion minimumGlVersion; - private final boolean isInteger; - - - - EDhPixelFormat(int glFormat, EGlVersion minimumGlVersion, boolean isInteger) - { - this.glFormat = glFormat; - this.minimumGlVersion = minimumGlVersion; - this.isInteger = isInteger; - } - - - - public static Optional fromString(String name) - { - try - { - return Optional.of(EDhPixelFormat.valueOf(name.toUpperCase(Locale.US))); - } - catch (IllegalArgumentException e) - { - return Optional.empty(); - } - } - - public int getGlFormat() { return this.glFormat; } - - public EGlVersion getMinimumGlVersion() { return this.minimumGlVersion; } - - public boolean isInteger() { return this.isInteger; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelType.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelType.java deleted file mode 100644 index b2c00d748..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EDhPixelType.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -import org.lwjgl.opengl.GL11C; -import org.lwjgl.opengl.GL12C; -import org.lwjgl.opengl.GL30C; - -import java.util.Locale; -import java.util.Optional; - -public enum EDhPixelType -{ - BYTE(GL11C.GL_BYTE, EGlVersion.GL_11), - SHORT(GL11C.GL_SHORT, EGlVersion.GL_11), - INT(GL11C.GL_INT, EGlVersion.GL_11), - HALF_FLOAT(GL30C.GL_HALF_FLOAT, EGlVersion.GL_30), - FLOAT(GL11C.GL_FLOAT, EGlVersion.GL_11), - UNSIGNED_BYTE(GL11C.GL_UNSIGNED_BYTE, EGlVersion.GL_11), - UNSIGNED_BYTE_3_3_2(GL12C.GL_UNSIGNED_BYTE_3_3_2, EGlVersion.GL_12), - UNSIGNED_BYTE_2_3_3_REV(GL12C.GL_UNSIGNED_BYTE_2_3_3_REV, EGlVersion.GL_12), - UNSIGNED_SHORT(GL11C.GL_UNSIGNED_SHORT, EGlVersion.GL_11), - UNSIGNED_SHORT_5_6_5(GL12C.GL_UNSIGNED_SHORT_5_6_5, EGlVersion.GL_12), - UNSIGNED_SHORT_5_6_5_REV(GL12C.GL_UNSIGNED_SHORT_5_6_5_REV, EGlVersion.GL_12), - UNSIGNED_SHORT_4_4_4_4(GL12C.GL_UNSIGNED_SHORT_4_4_4_4, EGlVersion.GL_12), - UNSIGNED_SHORT_4_4_4_4_REV(GL12C.GL_UNSIGNED_SHORT_4_4_4_4_REV, EGlVersion.GL_12), - UNSIGNED_SHORT_5_5_5_1(GL12C.GL_UNSIGNED_SHORT_5_5_5_1, EGlVersion.GL_12), - UNSIGNED_SHORT_1_5_5_5_REV(GL12C.GL_UNSIGNED_SHORT_1_5_5_5_REV, EGlVersion.GL_12), - UNSIGNED_INT(GL11C.GL_UNSIGNED_INT, EGlVersion.GL_11), - UNSIGNED_INT_8_8_8_8(GL12C.GL_UNSIGNED_INT_8_8_8_8, EGlVersion.GL_12), - UNSIGNED_INT_8_8_8_8_REV(GL12C.GL_UNSIGNED_INT_8_8_8_8_REV, EGlVersion.GL_12), - UNSIGNED_INT_10_10_10_2(GL12C.GL_UNSIGNED_INT_10_10_10_2, EGlVersion.GL_12), - UNSIGNED_INT_2_10_10_10_REV(GL12C.GL_UNSIGNED_INT_2_10_10_10_REV, EGlVersion.GL_12); - - - - private final int glFormat; - private final EGlVersion minimumGlVersion; - - - - EDhPixelType(int glFormat, EGlVersion minimumGlVersion) - { - this.glFormat = glFormat; - this.minimumGlVersion = minimumGlVersion; - } - - - - public static Optional fromString(String name) - { - try - { - return Optional.of(EDhPixelType.valueOf(name.toUpperCase(Locale.US))); - } - catch (IllegalArgumentException e) - { - return Optional.empty(); - } - } - - public int getGlFormat() { return glFormat; } - - public EGlVersion getMinimumGlVersion() { return minimumGlVersion; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EGlVersion.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EGlVersion.java deleted file mode 100644 index e705a1f86..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/texture/EGlVersion.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.seibel.distanthorizons.core.render.glObject.texture; - -public enum EGlVersion -{ - GL_11, - GL_12, - GL_30, - GL_31 -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/AbstractVertexAttribute.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/AbstractVertexAttribute.java deleted file mode 100644 index e4b90c99d..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/AbstractVertexAttribute.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.vertexAttribute; - -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import org.lwjgl.opengl.GL32; - -/** - * Base for binding/unbinding Vertex Attribute objects (VAO's). - * - * @see VertexAttributePostGL43 - * @see VertexAttributePreGL43 - */ -public abstract class AbstractVertexAttribute -{ - /** Stores the handle of the AbstractVertexAttribute. */ - public final int id; - - - - //==============// - // constructors // - //==============// - - // This will bind AbstractVertexAttribute - protected AbstractVertexAttribute() - { - this.id = GL32.glGenVertexArrays(); - GL32.glBindVertexArray(this.id); - } - - public static AbstractVertexAttribute create() - { - if (GLProxy.getInstance().vertexAttributeBufferBindingSupported) - { - return new VertexAttributePostGL43(); - } - else - { - return new VertexAttributePreGL43(); - } - } - - - - //=========// - // binding // - //=========// - - public void bind() { GL32.glBindVertexArray(this.id); } - public void unbind() { GL32.glBindVertexArray(0); } - - /** Always remember to always free your resources! */ - public void free() { GL32.glDeleteVertexArrays(this.id); } - - - - //==================// - // abstract methods // - //==================// - - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - public abstract void bindBufferToAllBindingPoints(int buffer); - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - public abstract void bindBufferToBindingPoint(int buffer, int bindingPoint); - /** Requires both AbstractVertexAttribute to be bound */ - public abstract void unbindBuffersFromAllBindingPoint(); - /** Requires both AbstractVertexAttribute to be bound */ - public abstract void unbindBuffersFromBindingPoint(int bindingPoint); - /** Requires both AbstractVertexAttribute to be bound */ - public abstract void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute); - /** Requires both AbstractVertexAttribute to be bound */ - public abstract void completeAndCheck(int expectedStrideSize); - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePostGL43.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePostGL43.java deleted file mode 100644 index 658227d6b..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePostGL43.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.vertexAttribute; - -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import org.lwjgl.opengl.GL43; - -/** - * In OpenGL 4.3 and later, Vertex Attribute got a make-over. - * Now it provides support for buffer binding points natively. - * This means that setting up the VAO is just use ONE native call when - * binding to a buffer.

- * - * Since I no longer need to implement binding points, I also no - * longer needs to keep track of Pointers. - */ -public final class VertexAttributePostGL43 extends AbstractVertexAttribute -{ - private static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) - .build(); - - - int numberOfBindingPoints = 0; - int strideSize = 0; - - - - //=============// - // constructor // - //=============// - - /** This will bind the {@link AbstractVertexAttribute} */ - public VertexAttributePostGL43() - { - super(); // also bind AbstractVertexAttribute - } - - - - //=========// - // binding // - //=========// - - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - @Override - public void bindBufferToAllBindingPoints(int buffer) - { - for (int i = 0; i < this.numberOfBindingPoints; i++) - { - GL43.glBindVertexBuffer(i, buffer, 0, this.strideSize); - } - } - - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - @Override - public void bindBufferToBindingPoint(int buffer, int bindingPoint) - { - GL43.glBindVertexBuffer(bindingPoint, buffer, 0, this.strideSize); - } - - - - //===========// - // unbinding // - //===========// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void unbindBuffersFromAllBindingPoint() - { - for (int i = 0; i < this.numberOfBindingPoints; i++) - { - GL43.glBindVertexBuffer(i, 0, 0, 0); - } - } - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void unbindBuffersFromBindingPoint(int bindingPoint) - { - GL43.glBindVertexBuffer(bindingPoint, 0, 0, 0); - } - - - - //==========================// - // manual attribute setting // - //==========================// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute) - { - if (attribute.useInteger) - { - GL43.glVertexAttribIFormat(attributeIndex, attribute.elementCount, attribute.glType, this.strideSize); - } - else - { - GL43.glVertexAttribFormat(attributeIndex, attribute.elementCount, attribute.glType, - attribute.normalized, this.strideSize); // Here strideSize is new attrib offset - } - - this.strideSize += attribute.byteSize; - if (this.numberOfBindingPoints <= bindingPoint) - { - this.numberOfBindingPoints = bindingPoint + 1; - } - GL43.glVertexAttribBinding(attributeIndex, bindingPoint); - GL43.glEnableVertexAttribArray(attributeIndex); - } - - - - //============// - // validation // - //============// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void completeAndCheck(int expectedStrideSize) - { - if (this.strideSize != expectedStrideSize) - { - LOGGER.error("Vertex Attribute calculated stride size " + this.strideSize + - " does not match the provided expected stride size " + expectedStrideSize + "!"); - throw new IllegalArgumentException("Vertex Attribute Incorrect Format"); - } - - LOGGER.info("Vertex Attribute (GL43+) completed. It contains " + this.numberOfBindingPoints - + " binding points and a stride size of " + this.strideSize); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePreGL43.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePreGL43.java deleted file mode 100644 index ac0bec5c5..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexAttributePreGL43.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.vertexAttribute; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.TreeMap; -import java.util.TreeSet; - -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import org.lwjgl.opengl.GL32; - - -public final class VertexAttributePreGL43 extends AbstractVertexAttribute -{ - private static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) - .build(); - - - // I tried to use raw arrays as much as possible since those lookups - // happen every frame, and the speed directly affects fps - int strideSize = 0; - int[][] bindingPointsToIndex; - VertexPointer[] pointers; - int[] pointersOffset; - - TreeMap> bindingPointsToIndexBuilder; - ArrayList pointersBuilder; - - - - //=============// - // constructor // - //=============// - - /** This will bind the {@link AbstractVertexAttribute} */ - public VertexAttributePreGL43() - { - super(); // also bind AbstractVertexAttribute - this.bindingPointsToIndexBuilder = new TreeMap<>(); - this.pointersBuilder = new ArrayList<>(); - } - - - - //=========// - // binding // - //=========// - - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - @Override - public void bindBufferToAllBindingPoints(int buffer) - { - for (int i = 0; i < this.pointers.length; i++) - { - GL32.glEnableVertexAttribArray(i); - } - - for (int i = 0; i < this.pointers.length; i++) - { - VertexPointer pointer = this.pointers[i]; - if (pointer == null) - { - continue; - } - - if (pointer.useInteger) - { - GL32.glVertexAttribIPointer(i, pointer.elementCount, pointer.glType, - this.strideSize, this.pointersOffset[i]); - } - else - { - GL32.glVertexAttribPointer(i, pointer.elementCount, pointer.glType, - pointer.normalized, this.strideSize, this.pointersOffset[i]); - } - } - } - - /** Requires both AbstractVertexAttribute and VertexBuffer to be bound */ - @Override - public void bindBufferToBindingPoint(int buffer, int bindingPoint) - { - int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint]; - - for (int bindingPointIndex : bindingPointIndexes) - { - GL32.glEnableVertexAttribArray(bindingPointIndex); - } - - for (int bindingPointIndex : bindingPointIndexes) - { - VertexPointer pointer = this.pointers[bindingPointIndex]; - if (pointer == null) - { - continue; - } - - if (pointer.useInteger) - { - GL32.glVertexAttribIPointer(bindingPointIndex, pointer.elementCount, pointer.glType, - this.strideSize, this.pointersOffset[bindingPointIndex]); - } - else - { - GL32.glVertexAttribPointer(bindingPointIndex, pointer.elementCount, pointer.glType, - pointer.normalized, this.strideSize, this.pointersOffset[bindingPointIndex]); - } - } - - } - - - - //===========// - // unbinding // - //===========// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void unbindBuffersFromAllBindingPoint() - { - for (int i = 0; i < this.pointers.length; i++) - { - GL32.glDisableVertexAttribArray(i); - } - } - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void unbindBuffersFromBindingPoint(int bindingPoint) - { - int[] bindingPointIndexes = this.bindingPointsToIndex[bindingPoint]; - for (int bindingPointIndex : bindingPointIndexes) - { - GL32.glDisableVertexAttribArray(bindingPointIndex); - } - } - - - - //==========================// - // manual attribute setting // - //==========================// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void setVertexAttribute(int bindingPoint, int attributeIndex, VertexPointer attribute) - { - TreeSet intArray = this.bindingPointsToIndexBuilder.computeIfAbsent(bindingPoint, k -> new TreeSet<>()); - intArray.add(attributeIndex); - - while (this.pointersBuilder.size() <= attributeIndex) - { - // This is dumb, but ArrayList doesn't have a resize, And this code - // should only be run when it's building the Vertex Attribute anyway. - this.pointersBuilder.add(null); - } - this.pointersBuilder.set(attributeIndex, attribute); - } - - - - //============// - // validation // - //============// - - /** Requires AbstractVertexAttribute to be bound */ - @Override - public void completeAndCheck(int expectedStrideSize) - { - int maxBindPointNumber = this.bindingPointsToIndexBuilder.lastKey(); - this.bindingPointsToIndex = new int[maxBindPointNumber + 1][]; - - this.bindingPointsToIndexBuilder.forEach((Integer i, TreeSet set) -> - { - this.bindingPointsToIndex[i] = new int[set.size()]; - Iterator iter = set.iterator(); - for (int j = 0; j < set.size(); j++) - { - this.bindingPointsToIndex[i][j] = iter.next(); - } - }); - - this.pointers = this.pointersBuilder.toArray(new VertexPointer[this.pointersBuilder.size()]); - this.pointersOffset = new int[this.pointers.length]; - this.pointersBuilder = null; // Release the builder - this.bindingPointsToIndexBuilder = null; // Release the builder - - // Check if all pointers are valid - int currentOffset = 0; - for (int i = 0; i < this.pointers.length; i++) - { - VertexPointer pointer = this.pointers[i]; - if (pointer == null) - { - LOGGER.warn("Vertex Attribute index " + i + " is not set! No index should be skipped normally!"); - continue; - } - this.pointersOffset[i] = currentOffset; - currentOffset += pointer.byteSize; - } - - if (currentOffset != expectedStrideSize) - { - LOGGER.error("Vertex Attribute calculated stride size " + currentOffset + - " does not match the provided expected stride size " + expectedStrideSize + "!"); - throw new IllegalArgumentException("Vertex Attribute Incorrect Format"); - } - this.strideSize = currentOffset; - LOGGER.info("Vertex Attribute (pre GL43) completed."); - - // Debug logging - LOGGER.debug("AttributeIndex: ElementCount, glType, normalized, strideSize, offset"); - - for (int i = 0; i < this.pointers.length; i++) - { - VertexPointer pointer = this.pointers[i]; - if (pointer == null) - { - LOGGER.debug(i + ": Null!!!!"); - } - else - { - LOGGER.debug(i + ": " + pointer.elementCount + ", " + - pointer.glType + ", " + pointer.normalized + ", " + this.strideSize + ", " + this.pointersOffset[i]); - } - } - - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexPointer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexPointer.java deleted file mode 100644 index 061827aa3..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/glObject/vertexAttribute/VertexPointer.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.glObject.vertexAttribute; - -import com.seibel.distanthorizons.coreapi.util.MathUtil; -import org.lwjgl.opengl.GL32; - -public final class VertexPointer -{ - public final int elementCount; - public final int glType; - public final boolean normalized; - public final int byteSize; - public final boolean useInteger; - - - - // basic constructors // - - public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize, boolean useInteger) - { - this.elementCount = elementCount; - this.glType = glType; - this.normalized = normalized; - this.byteSize = byteSize; - this.useInteger = useInteger; - } - public VertexPointer(int elementCount, int glType, boolean normalized, int byteSize) - { - this(elementCount, glType, normalized, byteSize, false); - } - private static int _align(int bytes) { return MathUtil.ceilDiv(bytes, 4) * 4; } - - - - // named constructors // - - public static VertexPointer addFloatPointer(boolean normalized) { return new VertexPointer(1, GL32.GL_FLOAT, normalized, Float.BYTES); } - public static VertexPointer addVec2Pointer(boolean normalized) { return new VertexPointer(2, GL32.GL_FLOAT, normalized, Float.BYTES * 2); } - public static VertexPointer addVec3Pointer(boolean normalized) { return new VertexPointer(3, GL32.GL_FLOAT, normalized, Float.BYTES * 3); } - public static VertexPointer addVec4Pointer(boolean normalized) { return new VertexPointer(4, GL32.GL_FLOAT, normalized, Float.BYTES * 4); } - /** Always aligned to 4 bytes */ - public static VertexPointer addUnsignedBytePointer(boolean normalized, boolean useInteger) { return new VertexPointer(1, GL32.GL_UNSIGNED_BYTE, normalized, 4, useInteger); } - /** aligned to 4 bytes */ - public static VertexPointer addUnsignedBytesPointer(int elementCount, boolean normalized, boolean useInteger) - { return new VertexPointer(elementCount, GL32.GL_UNSIGNED_BYTE, normalized, _align(elementCount), useInteger); } - public static VertexPointer addUnsignedShortsPointer(int elementCount, boolean normalized, boolean useInteger) - { return new VertexPointer(elementCount, GL32.GL_UNSIGNED_SHORT, normalized, _align(elementCount * 2), useInteger); } - public static VertexPointer addShortsPointer(int elementCount, boolean normalized, boolean useInteger) { return new VertexPointer(elementCount, GL32.GL_SHORT, normalized, _align(elementCount * 2), useInteger); } - public static VertexPointer addIntPointer(boolean normalized, boolean useInteger) { return new VertexPointer(1, GL32.GL_INT, normalized, 4, useInteger); } - public static VertexPointer addIVec2Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(2, GL32.GL_INT, normalized, 8, useInteger); } - public static VertexPointer addIVec3Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(3, GL32.GL_INT, normalized, 12, useInteger); } - public static VertexPointer addIVec4Pointer(boolean normalized, boolean useInteger) { return new VertexPointer(4, GL32.GL_INT, normalized, 16, useInteger); } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java deleted file mode 100644 index 69d64ce3c..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java +++ /dev/null @@ -1,513 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.config.types.ConfigEntry; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.concurrent.PriorityBlockingQueue; - -/** - * Handles rendering the wireframe particles - * that are used for seeing what the system's doing. - */ -public class DebugRenderer -{ - public static DebugRenderer INSTANCE = new DebugRenderer(); - - public static final DhLogger LOGGER = new DhLoggerBuilder().build(); - public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder() - .maxCountPerSecond(1) - .build(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - - // rendering setup - private ShaderProgram basicShader; - private GLElementBuffer outlineIndexBuffer; - private AbstractVertexAttribute va; - private boolean init = false; - - // used when rendering - private Mat4f dhMvmProjMatrixThisFrame; - private Vec3f camPosFloatThisFrame; - - - private final RendererLists rendererLists = new RendererLists(); - private final PriorityBlockingQueue particles = new PriorityBlockingQueue<>(); - - - - ///** A box from 0,0,0 to 1,1,1 */ - //private static final float[] BOX_VERTICES = { - // //region - // // Pos x y z - // 0, 0, 0, - // 1, 0, 0, - // 1, 1, 0, - // 0, 1, 0, - // 0, 0, 1, - // 1, 0, 1, - // 1, 1, 1, - // 0, 1, 1, - // //endregion - //}; - // - //private static final int[] BOX_OUTLINE_INDICES = { - // //region - // 0, 1, - // 1, 2, - // 2, 3, - // 3, 0, - // - // 4, 5, - // 5, 6, - // 6, 7, - // 7, 4, - // - // 0, 4, - // 1, 5, - // 2, 6, - // 3, 7, - // //endregion - //}; - - - - //=============// - // constructor // - //=============// - //region - - private DebugRenderer() { } - - //public void init() - //{ - // if (this.init) - // { - // return; - // } - // this.init = true; - // - // this.va = AbstractVertexAttribute.create(); - // this.va.bind(); - // // Pos - // this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false)); - // this.va.completeAndCheck(Float.BYTES * 3); - // this.basicShader = new ShaderProgram( - // "shaders/debug/vert.vert", - // "shaders/debug/frag.frag", - // "vPosition" - // ); - // this.createBuffer(); - //} - // - //private void createBuffer() - //{ - // // box vertices - // ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES); - // boxVerticesBuffer.order(ByteOrder.nativeOrder()); - // boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); - // boxVerticesBuffer.rewind(); - // - // - // // outline vertex indexes - // ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES); - // boxOutlineBuffer.order(ByteOrder.nativeOrder()); - // boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES); - // boxOutlineBuffer.rewind(); - // this.outlineIndexBuffer = new GLElementBuffer(false); - // this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW); - // - //} - - //endregion - - - - //==============// - // registration // - //==============// - //region - - public static void makeParticle(BoxParticle particle) - { - if (INSTANCE != null && Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get()) - { - INSTANCE.particles.add(particle); - } - } - - public static void register(IDebugRenderable renderable, ConfigEntry config) { if (INSTANCE != null) { INSTANCE.addRenderer(renderable, config); } } - public void addRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.addRenderable(renderable, config); } - - public static void unregister(IDebugRenderable renderable, ConfigEntry config) { if (INSTANCE != null) { INSTANCE.removeRenderer(renderable, config); } } - private void removeRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.removeRenderable(renderable, config); } - - public static void clearRenderables() { INSTANCE.rendererLists.clearRenderables(); } - - //endregion - - - - //===========// - // rendering // - //===========// - //region - - public void render(RenderParams renderEventParam) - { - //this.dhMvmProjMatrixThisFrame = dhMvmProjMatrix; - //Vec3d camPos = MC_RENDER.getCameraExactPosition(); - //this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); - - //this.init(); - - //GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); - //GLMC.enableDepthTest(); - // - //this.basicShader.bind(); - //this.va.bind(); - // - // - //this.outlineIndexBuffer.bind(); - this.rendererLists.render(this); - - - // particle rendering - BoxParticle head = null; - while ((head = this.particles.poll()) != null && head.isDead()) - { /* remove dead particles */ } - if (head != null) - { - // re-add the popped off head - this.particles.add(head); - } - - IMcDebugRenderer renderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); - renderer.render(renderEventParam, this.particles); - - } - - @Deprecated // TODO this should add all the boxes to a list so we can render them as a batch instead of individual draw calls - public void renderBox(Box box) - { - IMcDebugRenderer renderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); - renderer.render(box); - } - - //public void render(Mat4f dhMvmProjMatrix) - //{ - // this.dhMvmProjMatrixThisFrame = dhMvmProjMatrix; - // Vec3d camPos = MC_RENDER.getCameraExactPosition(); - // this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); - // - // this.init(); - // - // GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); - // GLMC.enableDepthTest(); - // - // this.basicShader.bind(); - // this.va.bind(); - // - // - // this.outlineIndexBuffer.bind(); - // this.rendererLists.render(this); - // - // - // // particle rendering - // BoxParticle head = null; - // while ((head = this.particles.poll()) != null && head.isDead()) - // { /* remove dead particles */ } - // if (head != null) - // { - // // re-add the popped off head - // this.particles.add(head); - // } - // - // - // // box rendering - // GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - // for (BoxParticle particle : this.particles) - // { - // // a new box is created each time since the height will be different based on the time it's lived - // this.renderBox(particle.createNewRenderBox()); - // } - //} - // - //public void renderBox(Box box) - //{ - // Mat4f boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z); - // boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z)); - // - // Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy(); - // transformMatrix.multiply(boxTransform); - // this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix); - // - // this.basicShader.setUniform(this.basicShader.getUniformLocation("uColor"), box.color); - // - // GL32.glDrawElements(GL32.GL_LINES, BOX_OUTLINE_INDICES.length, GL32.GL_UNSIGNED_INT, 0); - //} - - //endregion - - - - //================// - // helper classes // - //================// - //region - - public static final class Box - { - public Vec3f minPos; - public Vec3f maxPos; - public Color color; - - - - public Box(long pos, float minY, float maxY, float marginPercent, Color color) - { - float edgeOffset = DhSectionPos.getBlockWidth(pos) * marginPercent; - - int minBlockPosX = DhSectionPos.getMinCornerBlockX(pos); - int minBlockPosZ = DhSectionPos.getMinCornerBlockZ(pos); - int maxBlockPosX = minBlockPosX + DhSectionPos.getBlockWidth(pos); - int maxBlockPosZ = minBlockPosZ + DhSectionPos.getBlockWidth(pos); - - this.minPos = new Vec3f(minBlockPosX + edgeOffset, minY, minBlockPosZ + edgeOffset); - this.maxPos = new Vec3f(maxBlockPosX - edgeOffset, maxY, maxBlockPosZ - edgeOffset); - this.color = color; - } - - /** only used for */ - public Box(Vec3f minPos, Vec3f maxPos, Color color) - { - this.minPos = minPos; - this.maxPos = maxPos; - this.color = color; - } - - } - - public static final class BoxParticle implements Comparable - { - public Box box; - public long startMsTime; - public long durationInMs; - public float yChange; - - - private BoxParticle(Box box, long startMsTime, long durationInMs, float yChange) - { - this.box = box; - this.startMsTime = startMsTime; - this.durationInMs = durationInMs; - this.yChange = yChange; - } - - public BoxParticle(Box box, double secondDuration, float yChange) - { this(box, System.currentTimeMillis(), (long) (secondDuration * 1_000), yChange); } - - - @Override - public int compareTo(@NotNull DebugRenderer.BoxParticle particle) - { return Long.compare(this.startMsTime + this.durationInMs, particle.startMsTime + particle.durationInMs); } - - /** will change each time it's called based on the yChange value and time */ - public Box createNewRenderBox() - { - long nowMs = System.currentTimeMillis(); - - float percent = (nowMs - this.startMsTime) / (float) this.durationInMs; - percent = (float) Math.pow(percent, 4); - float yDiff = this.yChange * percent; - - return new Box( - new Vec3f(this.box.minPos.x, this.box.minPos.y + yDiff, this.box.minPos.z), - new Vec3f(this.box.maxPos.x, this.box.maxPos.y + yDiff, this.box.maxPos.z), - this.box.color); - } - - public boolean isDead() { return (System.currentTimeMillis() - this.startMsTime) > this.durationInMs; } - - } - - private static class RendererLists - { - public final LinkedList> generalRenderableList = new LinkedList<>(); - - private final HashMap, LinkedList>> renderableListByConfig = new HashMap<>(); - - - - //==============// - // registration // - //==============// - //region - - public void addRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config) - { - synchronized (this) - { - if (config != null) - { - if (!this.renderableListByConfig.containsKey(config)) - { - this.renderableListByConfig.put(config, new LinkedList<>()); - } - - LinkedList> renderableList = this.renderableListByConfig.get(config); - renderableList.add(new WeakReference<>(renderable)); - } - else - { - this.generalRenderableList.add(new WeakReference<>(renderable)); - } - } - } - - public void removeRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config) - { - synchronized (this) - { - if (config != null) - { - if (this.renderableListByConfig.containsKey(config)) - { - LinkedList> renderableList = this.renderableListByConfig.get(config); - this.removeRenderableFromInternalList(renderableList, renderable); - } - } - else - { - this.removeRenderableFromInternalList(this.generalRenderableList, renderable); - } - } - } - private void removeRenderableFromInternalList(LinkedList> rendererList, IDebugRenderable renderable) - { - Iterator> iterator = rendererList.iterator(); - while (iterator.hasNext()) - { - WeakReference renderableRef = iterator.next(); - if (renderableRef.get() == null) - { - iterator.remove(); - continue; - } - - if (renderableRef.get() == renderable) - { - iterator.remove(); - return; - } - } - } - - public void clearRenderables() - { - for (ConfigEntry config : this.renderableListByConfig.keySet()) - { - LinkedList> renderableList = this.renderableListByConfig.get(config); - if (config.get() && renderableList != null) - { - renderableList.clear(); - } - } - } - - //endregion - - - - //===========// - // rendering // - //===========// - //region - - public void render(DebugRenderer debugRenderer) - { - this.renderList(debugRenderer, this.generalRenderableList); - - for (ConfigEntry config : this.renderableListByConfig.keySet()) - { - LinkedList> renderableList = this.renderableListByConfig.get(config); - if (config.get() && renderableList != null && renderableList.size() != 0) - { - this.renderList(debugRenderer, renderableList); - } - } - } - private void renderList(DebugRenderer debugRenderer, LinkedList> rendererList) - { - synchronized (this) - { - try - { - Iterator> iterator = rendererList.iterator(); - while (iterator.hasNext()) - { - WeakReference ref = iterator.next(); - IDebugRenderable renderable = ref.get(); - if (renderable == null) - { - iterator.remove(); - continue; - } - - renderable.debugRender(debugRenderer); - } - } - catch (Exception e) - { - RATE_LIMITED_LOGGER.error("Unexpected Debug renderer error, Error: "+e.getMessage(), e); - } - } - } - - //endregion - } - - //endregion - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java deleted file mode 100644 index d73a55693..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhFadeRenderer.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.renderer.shaders.DhFadeShader; -import com.seibel.distanthorizons.core.render.renderer.shaders.FadeApplyShader; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL43C; - -import java.nio.ByteBuffer; - -/** - * Handles fading MC and DH together via {@link DhFadeShader} and {@link FadeApplyShader}.

- * - * {@link DhFadeShader} - draws the Fade to a texture.
- * {@link FadeApplyShader} - draws the Fade texture to DH's framebuffer.
- */ -public class DhFadeRenderer -{ - - public static DhFadeRenderer INSTANCE = new DhFadeRenderer(); - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private boolean init = false; - - private int width = -1; - private int height = -1; - private int fadeFramebuffer = -1; - - private int fadeTexture = -1; - - - - //=============// - // constructor // - //=============// - - private DhFadeRenderer() { } - - public void init() - { - if (this.init) return; - this.init = true; - - DhFadeShader.INSTANCE.init(); - FadeApplyShader.INSTANCE.init(); - } - - private void createFramebuffer(int width, int height) - { - if (this.fadeFramebuffer != -1) - { - GL32.glDeleteFramebuffers(this.fadeFramebuffer); - this.fadeFramebuffer = -1; - } - - this.fadeFramebuffer = GL32.glGenFramebuffers(); - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fadeFramebuffer); - - - if (this.fadeTexture != -1) - { - GLMC.glDeleteTextures(this.fadeTexture); - this.fadeTexture = -1; - } - - this.fadeTexture = GL32.glGenTextures(); - { - GLMC.glBindTexture(this.fadeTexture); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16, width, height, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_SHORT_4_4_4_4, (ByteBuffer) null); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); - - // disable mip-mapping since DH is just going to draw straight to the screen - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_BASE_LEVEL, 0); - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_MAX_LEVEL, 0); - } - - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.fadeTexture, 0); - - } - - - - //========// - // render // - //========// - - public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler) - { - try - { - profiler.push("Fade Generate"); - - this.init(); - - // resize the framebuffer if necessary - int width = MC_RENDER.getTargetFramebufferViewportWidth(); - int height = MC_RENDER.getTargetFramebufferViewportHeight(); - if (this.width != width || this.height != height) - { - this.width = width; - this.height = height; - this.createFramebuffer(width, height); - } - - - DhFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; - DhFadeShader.INSTANCE.setProjectionMatrix(mcModelViewMatrix, mcProjectionMatrix); - DhFadeShader.INSTANCE.render(partialTicks); - - // restored so we can write the fade texture to the main frame buffer - //mcState.restore(); - - profiler.popPush("Fade Apply"); - - FadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; - FadeApplyShader.INSTANCE.readFramebuffer = DhFadeShader.INSTANCE.frameBuffer; - FadeApplyShader.INSTANCE.drawFramebuffer = BlazeLodRenderer.INSTANCE.getActiveFramebufferId(); - FadeApplyShader.INSTANCE.render(partialTicks); - } - catch (Exception e) - { - LOGGER.error("Unexpected error during fade render, error: ["+e.getMessage()+"].", e); - } - finally - { - profiler.pop(); - } - } - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java deleted file mode 100644 index 35298e10d..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DhTerrainShaderProgram.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.render.glObject.shader.Shader; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttributePostGL43; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttributePreGL43; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; - -/** - * Handles rendering the normal LOD terrain. - * @see LodQuadBuilder - */ -public class DhTerrainShaderProgram extends ShaderProgram implements IDhApiShaderProgram -{ - public final AbstractVertexAttribute vao; - - // Uniforms - public int uCombinedMatrix = -1; - public int uModelOffset = -1; - public int uWorldYOffset = -1; - - public int uMircoOffset = -1; - public int uEarthRadius = -1; - public int uLightMap = -1; - - // fragment shader uniforms - public int uClipDistance = -1; - public int uDitherDhRendering = -1; - - // Noise Uniforms - public int uNoiseEnabled = -1; - public int uNoiseSteps = -1; - public int uNoiseIntensity = -1; - public int uNoiseDropoff = -1; - - // Debug Uniform - public int uIsWhiteWorld = -1; - - - - //=============// - // constructor // - //=============// - - // This will bind AbstractVertexAttribute - public DhTerrainShaderProgram() - { - super( - "shaders/standard.vert", - "shaders/flat_shaded.frag", - new String[]{"vPosition", "color"} - ); - - this.uCombinedMatrix = this.getUniformLocation("uCombinedMatrix"); - this.uModelOffset = this.getUniformLocation("uModelOffset"); - this.uWorldYOffset = this.getUniformLocation("uWorldYOffset"); - this.uDitherDhRendering = this.getUniformLocation("uDitherDhRendering"); - this.uMircoOffset = this.getUniformLocation("uMircoOffset"); - this.uEarthRadius = this.getUniformLocation("uEarthRadius"); - - this.uLightMap = this.getUniformLocation("uLightMap"); - - // Fog/Clip Uniforms - this.uClipDistance = this.getUniformLocation("uClipDistance"); - - // Noise Uniforms - this.uNoiseEnabled = this.getUniformLocation("uNoiseEnabled"); - this.uNoiseSteps = this.getUniformLocation("uNoiseSteps"); - this.uNoiseIntensity = this.getUniformLocation("uNoiseIntensity"); - this.uNoiseDropoff = this.getUniformLocation("uNoiseDropoff"); - - // Debug Uniform - this.uIsWhiteWorld = this.getUniformLocation("uIsWhiteWorld"); - - - if (GLProxy.getInstance().vertexAttributeBufferBindingSupported) - { - this.vao = new VertexAttributePostGL43(); // also binds AbstractVertexAttribute - } - else - { - this.vao = new VertexAttributePreGL43(); // also binds AbstractVertexAttribute - } - this.vao.bind(); - - // short: x, y, z, meta - // meta: byte skylight, byte blocklight, byte microOffset - this.vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); - // byte: r, g, b, a - this.vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); - // byte: iris material ID, normal index, 2 spacers - this.vao.setVertexAttribute(0, 2, VertexPointer.addUnsignedBytesPointer(4, true, true)); - - try - { - int vertexByteCount = LodUtil.DH_VERTEX_FORMAT.getByteSize(); - this.vao.completeAndCheck(vertexByteCount); - } - catch (RuntimeException e) - { - System.out.println(LodUtil.DH_VERTEX_FORMAT); - throw e; - } - - } - - - - //=========// - // methods // - //=========// - - @Override - public void bind() - { - super.bind(); - this.vao.bind(); - } - @Override - public void unbind() - { - super.unbind(); - this.vao.unbind(); - } - - @Override - public void free() - { - this.vao.free(); - super.free(); - } - - @Override - public void bindVertexBuffer(int vbo) { this.vao.bindBufferToAllBindingPoints(vbo); } - - @Override - public void fillUniformData(DhApiRenderParam renderParameters) - { - Mat4f combinedMatrix = new Mat4f(renderParameters.dhProjectionMatrix); - combinedMatrix.multiply(renderParameters.dhModelViewMatrix); - - super.bind(); - - // uniforms - this.setUniform(this.uCombinedMatrix, combinedMatrix); - this.setUniform(this.uMircoOffset, 0.01f); // 0.01 block offset - - this.setUniform(this.uLightMap, ILightMapWrapper.BOUND_INDEX); - - this.setUniform(this.uWorldYOffset, (float) renderParameters.worldYOffset); - - this.setUniform(this.uDitherDhRendering, Config.Client.Advanced.Graphics.Quality.ditherDhFade.get()); - - float curveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get(); - if (curveRatio < -1.0f || curveRatio > 1.0f) - { - curveRatio = /*6371KM*/ 6371000.0f / curveRatio; - } - else - { - // disable curvature if the config value is between -1 and 1 - curveRatio = 0.0f; - } - this.setUniform(this.uEarthRadius, curveRatio); - - // Noise Uniforms - this.setUniform(this.uNoiseEnabled, Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get()); - this.setUniform(this.uNoiseSteps, Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get()); - this.setUniform(this.uNoiseIntensity, Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get()); - this.setUniform(this.uNoiseDropoff, Config.Client.Advanced.Graphics.NoiseTexture.noiseDropoff.get()); - - // Debug - this.setUniform(this.uIsWhiteWorld, Config.Client.Advanced.Debugging.enableWhiteWorld.get()); - - // Clip Uniform - float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks(); - if (!Config.Client.Advanced.Debugging.lodOnlyMode.get()) - { - // this added value prevents the near clip plane and discard circle from touching, which looks bad - dhNearClipDistance += 16f; - } - this.setUniform(this.uClipDistance, dhNearClipDistance); - } - - @Override - public void setModelOffsetPos(DhApiVec3f modelOffsetPos) { this.setUniform(this.uModelOffset, new Vec3f(modelOffsetPos)); } - - @Override - public int getId() { return this.id; } - - /** The base DH render program should always render */ - @Override - public boolean overrideThisFrame() { return true; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderer.java deleted file mode 100644 index f649b7a05..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderer.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.renderer.shaders.FogApplyShader; -import com.seibel.distanthorizons.core.render.renderer.shaders.FogShader; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL43C; - -import java.nio.ByteBuffer; - -/** - * Handles adding SSAO via {@link FogShader} and {@link FogApplyShader}.

- * - * {@link FogShader} - draws the Fog to a texture.
- * {@link FogApplyShader} - draws the Fog texture to DH's FrameBuffer.
- */ -public class FogRenderer -{ - public static FogRenderer INSTANCE = new FogRenderer(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private boolean init = false; - - private int width = -1; - private int height = -1; - private int fogFramebuffer = -1; - - private int fogTexture = -1; - - - - //=============// - // constructor // - //=============// - - private FogRenderer() { } - - public void init() - { - if (this.init) return; - this.init = true; - - FogShader.INSTANCE.init(); - FogApplyShader.INSTANCE.init(); - } - - private void createFramebuffer(int width, int height) - { - if (this.fogFramebuffer != -1) - { - GL32.glDeleteFramebuffers(this.fogFramebuffer); - this.fogFramebuffer = -1; - } - - if (this.fogTexture != -1) - { - GLMC.glDeleteTextures(this.fogTexture); - this.fogTexture = -1; - } - - this.fogFramebuffer = GL32.glGenFramebuffers(); - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fogFramebuffer); - - this.fogTexture = GLMC.glGenTextures(); - { - GLMC.glBindTexture(this.fogTexture); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16, width, height, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_SHORT_4_4_4_4, (ByteBuffer) null); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.fogTexture, 0); - - // disable mip-mapping since DH is just going to draw straight to the screen - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_BASE_LEVEL, 0); - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_MAX_LEVEL, 0); - } - } - - - - //========// - // render // - //========// - - public void render(Mat4f modelViewProjectionMatrix, float partialTicks) - { - // GLState needed in MC 1.16.5 probably due to MC not manually setting each GL state they need before the next rendering step - try (GLState state = new GLState()) - { - this.init(); - - // resize the framebuffer if necessary - int width = MC_RENDER.getTargetFramebufferViewportWidth(); - int height = MC_RENDER.getTargetFramebufferViewportHeight(); - if (this.width != width || this.height != height) - { - this.width = width; - this.height = height; - this.createFramebuffer(width, height); - } - - FogShader.INSTANCE.frameBuffer = this.fogFramebuffer; - FogShader.INSTANCE.setProjectionMatrix(modelViewProjectionMatrix); - FogShader.INSTANCE.render(partialTicks); - - FogApplyShader.INSTANCE.fogTexture = this.fogTexture; - FogApplyShader.INSTANCE.render(partialTicks); - } - } - - public void free() - { - FogShader.INSTANCE.free(); - FogApplyShader.INSTANCE.free(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java deleted file mode 100644 index ce6212a80..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ /dev/null @@ -1,767 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode; -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer; -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram; -import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiTextureCreatedParam; -import com.seibel.distanthorizons.core.api.internal.ClientApi; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; -import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; -import com.seibel.distanthorizons.core.render.DhApiRenderProxy; -import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; -import com.seibel.distanthorizons.core.render.glObject.buffer.QuadElementBuffer; -import com.seibel.distanthorizons.core.render.glObject.texture.*; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; -import com.seibel.distanthorizons.core.render.renderer.shaders.*; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.objects.SortedArraySet; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; -import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; -import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; -import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL32; - -/** - * This is where all the magic happens.
- * This is where LODs are draw to the world. - */ -public class LodRenderer -{ - public static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) - .build(); - - public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) - .maxCountPerSecond(4) - .build(); - - private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); - - public static final LodRenderer INSTANCE = new LodRenderer(); - - - - // these ID's either what any render is currently using (since only one renderer can be active at a time), or just used previously - private int activeFramebufferId = -1; - private int activeColorTextureId = -1; - private int activeDepthTextureId = -1; - private int textureWidth; - private int textureHeight; - - - private IDhApiShaderProgram lodRenderProgram = null; - public QuadElementBuffer quadIBO = null; - private boolean renderObjectsCreated = false; - - // framebuffer and texture ID's for this renderer - private IDhApiFramebuffer framebuffer; - /** will be null if MC's framebuffer is being used since MC already has a color texture */ - @Nullable - private DhColorTexture nullableColorTexture; - private DHDepthTexture depthTexture; - /** - * If true the {@link LodRenderer#framebuffer} is the same as MC's. - * This should only be true in the case of Optifine so LODs won't be overwritten when shaders are enabled. - */ - private boolean usingMcFramebuffer = false; - - - - //=============// - // constructor // - //=============// - - private LodRenderer() { } - - - - //===========// - // rendering // - //===========// - //region - - /** - * This will draw both opaque and transparent LODs if - * {@link DhApiRenderProxy#getDeferTransparentRendering()} is false, - * otherwise it will only render opaque LODs. - */ - public void render(RenderParams renderParams, IProfilerWrapper profiler) - { this.renderLodPass(renderParams, profiler, false); } - - /** - * This method is designed for Iris to be able - * to draw water in a deferred rendering context. - * It needs to be updated with any major changes, - * but shouldn't be activated as per deferWaterRendering. - */ - public void renderDeferred(RenderParams renderParams, IProfilerWrapper profiler) - { this.renderLodPass(renderParams, profiler, true); } - - private void renderLodPass(RenderParams renderParams, IProfilerWrapper profiler, boolean runningDeferredPass) - { - //====================// - // validate rendering // - //====================// - - boolean deferTransparentRendering = DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); - if (runningDeferredPass - && !deferTransparentRendering) - { - return; - } - boolean firstPass = !runningDeferredPass; - - // RenderParams parameter validation should be done before this - if (!renderParams.validationRun) - { - throw new IllegalArgumentException("Render parameters validation"); - } - - RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; - IMcGenericRenderer genericRenderer = renderParams.genericRenderer; - ILightMapWrapper lightmap = renderParams.lightmap; - - - - //=================// - // rendering setup // - //=================// - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams); - profiler.push("LOD GL setup"); - - if (!this.renderObjectsCreated) - { - boolean setupSuccess = this.createRenderObjects(); - if (!setupSuccess) - { - // shouldn't normally happen, but just in case - return; - } - - // only do this once, that way they can still be reverted if desired - if (Config.Client.Advanced.Graphics.overrideVanillaGraphicsSettings.get()) - { - LOGGER.info("Overriding vanilla MC settings to better fit Distant Horizons... This behavior can be disabled in the Distant Horizons config."); - - MC.disableVanillaClouds(); - MC.disableVanillaChunkFadeIn(); - MC.disableFabulousTransparency(); - } - - this.renderObjectsCreated = true; - } - - this.setGLState(renderParams, firstPass); - - lightmap.bind(); - this.quadIBO.bind(); - - if (firstPass) - { - // we only need to sort/cull the LODs during the first frame - profiler.popPush("LOD build render list"); - renderBufferHandler.buildRenderList(renderParams); - } - - IDhApiShaderProgram lodShaderProgram = this.lodRenderProgram; - IDhApiShaderProgram lodShaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class); - if (lodShaderProgramOverride != null && lodShaderProgram.overrideThisFrame()) - { - lodShaderProgram = lodShaderProgramOverride; - } - - - - //===========// - // rendering // - //===========// - - if (!runningDeferredPass) - { - //=========================// - // opaque and non-deferred // - // transparent rendering // - //=========================// - - // opaque LODs - profiler.popPush("LOD Opaque"); - this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ true); - - // custom objects with SSAO - if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) - { - profiler.popPush("Custom Objects"); - genericRenderer.render(renderParams, profiler, true); - } - - // SSAO - if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get()) - { - profiler.popPush("LOD SSAO"); - SSAORenderer.INSTANCE.render(new Mat4f(renderParams.dhProjectionMatrix), renderParams.partialTicks); - } - - // custom objects without SSAO - if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) - { - profiler.popPush("Custom Objects"); - genericRenderer.render(renderParams, profiler, false); - } - - // combined pass transparent rendering - if (!deferTransparentRendering - && Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) - { - profiler.popPush("LOD Transparent"); - this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ false); - } - - // far plane clip fading - if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get() - // the fade shader messes with the GL state in a way Iris doesn't like, - // so skip it if a shader is active - && (IRIS_ACCESSOR == null || !IRIS_ACCESSOR.isShaderPackInUse())) - { - profiler.popPush("Fade Far Clip Fade"); - DhFadeRenderer.INSTANCE.render( - new Mat4f(renderParams.mcModelViewMatrix), new Mat4f(renderParams.mcProjectionMatrix), - renderParams.partialTicks, profiler); - } - - // fog - if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() - // this is done to fix issues with: underwater fog, blindness effect, etc. - || renderParams.vanillaFogEnabled) - { - profiler.popPush("LOD Fog"); - - Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); - } - - - - //=================// - // debug rendering // - //=================// - - if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get()) - { - profiler.popPush("Debug wireframes"); - - Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - // Note: this can be very slow if a lot of boxes are being rendered - //DebugRenderer.INSTANCE.render(combinedMatrix); // TODO - } - - - - //===================// - // optifine clean up // - //===================// - - if (this.usingMcFramebuffer) - { - // If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC. - // This should only happen when Optifine shaders are being used. - GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT); - } - - - - //=============================// - // Apply to the MC Framebuffer // - //=============================// - - boolean cancelApplyShader = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeApplyShaderRenderEvent.class, renderParams); - if (!cancelApplyShader) - { - profiler.popPush("LOD Apply"); - - // Copy the LOD framebuffer to Minecraft's framebuffer - DhApplyShader.INSTANCE.render(renderParams.partialTicks); - } - } - else - { - //====================// - // deferred rendering // - //====================// - - if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) - { - profiler.popPush("LOD Transparent"); - this.renderLodPass(lodShaderProgram, renderBufferHandler, renderParams, /*opaquePass*/ false); - - - if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() - // this is done to fix issues with: underwater fog, blindness effect, etc. - || renderParams.vanillaFogEnabled) - { - profiler.popPush("LOD Fog"); - - Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); - } - } - } - - - - //================// - // render cleanup // - //================// - - profiler.popPush("LOD cleanup"); - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams); - - lightmap.unbind(); - this.quadIBO.unbind(); - lodShaderProgram.unbind(); - - - // end of internal LOD profiling - profiler.pop(); - } - - //endregion - - - - //=================// - // Setup Functions // - //=================// - //region - - private void setGLState( - DhApiRenderParam renderEventParam, - boolean firstPass) - { - //===================// - // framebuffer setup // - //===================// - - // get the active framebuffer - IDhApiFramebuffer framebuffer = this.framebuffer; - IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class); - if (framebufferOverride != null && framebufferOverride.overrideThisFrame()) - { - framebuffer = framebufferOverride; - } - this.activeFramebufferId = framebuffer.getId(); - framebuffer.bind(); - - - - //==========// - // bindings // - //==========// - - // by default draw everything as triangles - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - GLMC.enableFaceCulling(); - - GLMC.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA); - GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ZERO); - - GL32.glDisable(GL32.GL_SCISSOR_TEST); - - // Enable depth test and depth mask - GLMC.enableDepthTest(); - GLMC.glDepthFunc(GL32.GL_LESS); - GLMC.enableDepthMask(); - - // This is required for MC versions 1.21.5+ - // due to MC updating the lightmap by changing the viewport size - GL32.glViewport(0, 0, this.textureWidth, this.textureHeight); - - this.lodRenderProgram.bind(); - - - - //==========// - // uniforms // - //==========// - - IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class); - if (shaderProgramOverride != null) - { - shaderProgramOverride.fillUniformData(renderEventParam); - } - - this.lodRenderProgram.fillUniformData(renderEventParam); - - - - - //===============// - // texture setup // - //===============// - - // resize the textures if needed - if (MC_RENDER.getTargetFramebufferViewportWidth() != this.textureWidth - || MC_RENDER.getTargetFramebufferViewportHeight() != this.textureHeight) - { - // just resizing the textures doesn't work when Optifine is present, - // so recreate the textures with the new size instead - this.createAndBindTextures(); - } - - - // set the active textures - this.activeDepthTextureId = this.depthTexture.getTextureId(); - - if (this.nullableColorTexture != null) - { - this.activeColorTextureId = this.nullableColorTexture.getTextureId(); - } - else - { - // get MC's color texture - this.activeColorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); - } - - - // needs to be fired after all the textures have been created/bound - boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderEventParam); - if (clearTextures) - { - GL32.glClearDepth(1.0); - - float[] clearColorValues = new float[4]; - GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues); - GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 1.0f); - - if (this.usingMcFramebuffer && framebufferOverride == null) - { - // Due to using MC/Optifine's framebuffer we need to re-bind the depth texture, - // otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues - framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil()); - - - // don't clear the color texture, that removes the sky - GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT); - } - else if (firstPass) - { - GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT); - } - } - - - } - - private boolean createRenderObjects() - { - if (this.renderObjectsCreated) - { - LOGGER.warn("Renderer setup called but it has already completed setup!"); - return false; - } - - // GLProxy should have already been created by this point, but just in case create it now - GLProxy.getInstance(); - - - - LOGGER.info("Setting up renderer"); - this.lodRenderProgram = new DhTerrainShaderProgram(); - - this.quadIBO = new QuadElementBuffer(); - this.quadIBO.reserve(LodBufferContainer.MAX_QUADS_PER_BUFFER); - - - // create or get the frame buffer - if (AbstractOptifineAccessor.optifinePresent()) - { - // use MC/Optifine's default Framebuffer so shaders won't remove the LODs - int currentFramebufferId = MC_RENDER.getTargetFramebuffer(); - this.framebuffer = new DhFramebuffer(currentFramebufferId); - this.usingMcFramebuffer = true; - } - else - { - // normal use case - this.framebuffer = new DhFramebuffer(); - this.usingMcFramebuffer = false; - } - - // create and bind the necessary textures - this.createAndBindTextures(); - - if(this.framebuffer.getStatus() != GL32.GL_FRAMEBUFFER_COMPLETE) - { - // This generally means something wasn't bound, IE missing either the color or depth texture - LOGGER.warn("Framebuffer ["+this.framebuffer.getId()+"] isn't complete."); - return false; - } - - - - LOGGER.info("Renderer setup complete"); - return true; - } - - @SuppressWarnings( "deprecation" ) // done to ignore DhApiColorDepthTextureCreatedEvent - private void createAndBindTextures() - { - int oldWidth = this.textureWidth; - int oldHeight = this.textureHeight; - this.textureWidth = MC_RENDER.getTargetFramebufferViewportWidth(); - this.textureHeight = MC_RENDER.getTargetFramebufferViewportHeight(); - - DhApiTextureCreatedParam textureCreatedParam = new DhApiTextureCreatedParam( - oldWidth, oldHeight, - this.textureWidth, this.textureHeight - ); - - - // DhApiColorDepthTextureCreatedEvent needs to be kept around since old versions of Iris need it - ApiEventInjector.INSTANCE.fireAllEvents(DhApiColorDepthTextureCreatedEvent.class, new DhApiColorDepthTextureCreatedEvent.EventParam(textureCreatedParam)); - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeColorDepthTextureCreatedEvent.class, textureCreatedParam); - - - // also update the framebuffer override if present - IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class); - - - this.depthTexture = new DHDepthTexture(this.textureWidth, this.textureHeight, EDhDepthBufferFormat.DEPTH32F); - this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil()); - if (framebufferOverride != null) - { - framebufferOverride.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil()); - } - - // if we are using MC's frame buffer, a color texture is already present and shouldn't need to be bound - if (!this.usingMcFramebuffer) - { - this.nullableColorTexture = DhColorTexture.builder().setDimensions(this.textureWidth, this.textureHeight) - .setInternalFormat(EDhInternalTextureFormat.RGBA8) - .setPixelType(EDhPixelType.UNSIGNED_BYTE) - .setPixelFormat(EDhPixelFormat.RGBA) - .build(); - - this.framebuffer.addColorAttachment(0, this.nullableColorTexture.getTextureId()); - if (framebufferOverride != null) - { - framebufferOverride.addColorAttachment(0, this.nullableColorTexture.getTextureId()); - } - } - else - { - this.nullableColorTexture = null; - } - - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterColorDepthTextureCreatedEvent.class, textureCreatedParam); - } - - //endregion - - - - //===============// - // LOD rendering // - //===============// - //region - - private void renderLodPass(IDhApiShaderProgram shaderProgram, RenderBufferHandler lodBufferHandler, RenderParams renderEventParam, boolean opaquePass) - { - //=======================// - // debug wireframe setup // - //=======================// - - boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get(); - if (renderWireframe) - { - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); - GLMC.disableFaceCulling(); - } - else - { - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - GLMC.enableFaceCulling(); - } - - if (!opaquePass) - { - GLMC.enableBlend(); - GLMC.enableDepthTest(); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); - } - else - { - GLMC.disableBlend(); - } - - - - - //===========// - // rendering // - //===========// - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam); - - if (IRIS_ACCESSOR != null) - { - // done to fix a bug with Iris where face culling isn't properly set or reverted in the MC state manager - // which causes Sodium to render some water chunks with their normal inverted - // https://github.com/IrisShaders/Iris/issues/2582 - // https://github.com/IrisShaders/Iris/blob/1.21.9/common/src/main/java/net/irisshaders/iris/compat/dh/LodRendererEvents.java#L346 - GLMC.enableFaceCulling(); - } - - //if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) - //{ - // // Normal LOD rendering - // - // SortedArraySet lodBufferContainer = lodBufferHandler.getColumnRenderBuffers(); - // if (lodBufferContainer != null) - // { - // for (int lodIndex = 0; lodIndex < lodBufferContainer.size(); lodIndex++) - // { - // LodBufferContainer bufferContainer = lodBufferContainer.get(lodIndex); - // this.setShaderProgramMvmOffset(bufferContainer.minCornerBlockPos, shaderProgram, renderEventParam); - // - // GLVertexBuffer[] vbos = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent; - // for (int vboIndex = 0; vboIndex < vbos.length; vboIndex++) - // { - // GLVertexBuffer vbo = vbos[vboIndex]; - // if (vbo == null) - // { - // continue; - // } - // - // if (vbo.getVertexCount() == 0) - // { - // continue; - // } - // - // vbo.bind(); - // shaderProgram.bindVertexBuffer(vbo.getId()); - // GL32.glDrawElements( - // GL32.GL_TRIANGLES, - // vbo.getVertexCount(), - // this.quadIBO.getType(), 0); - // vbo.unbind(); - // } - // } - // } - //} - //else - { - // basic quad rendering - - IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); - testRenderer.render(); - - //TestRenderer.INSTANCE.render(); - //McTestRenderer.INSTANCE.render(); - } - - - //=========================// - // debug wireframe cleanup // - //=========================// - - if (renderWireframe) - { - // default back to GL_FILL since all other rendering uses it - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - GLMC.enableFaceCulling(); - } - - } - - /** - * the MVM offset is needed so LODs can be rendered anywhere in the MC world - * without running into floating point percision loss. - */ - private void setShaderProgramMvmOffset(DhBlockPos pos, IDhApiShaderProgram shaderProgram, RenderParams renderEventParam) throws IllegalStateException - { - Vec3d camPos = renderEventParam.exactCameraPosition; - Vec3f modelPos = new Vec3f( - (float) (pos.getX() - camPos.x), - (float) (pos.getY() - camPos.y), - (float) (pos.getZ() - camPos.z)); - - shaderProgram.bind(); - shaderProgram.setModelOffsetPos(modelPos); - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos)); - } - - //endregion - - - - //===============// - // API functions // - //===============// - //region - - /** @return -1 if no frame buffer has been bound yet */ - public int getActiveFramebufferId() { return this.activeFramebufferId; } - - /** @return -1 if no texture has been bound yet */ - public int getActiveColorTextureId() { return this.activeColorTextureId; } - - /** @return -1 if no texture has been bound yet */ - public int getActiveDepthTextureId() { return this.activeDepthTextureId; } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java deleted file mode 100644 index d3a8d9857..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderParams.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.seibel.distanthorizons.core.render.renderer; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.core.api.internal.SharedApi; -import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.jar.EPlatform; -import com.seibel.distanthorizons.core.level.IDhClientLevel; -import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; -import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.world.IDhClientWorld; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; - -/** - * An extension of {@link DhApiRenderParam} - * that allows additional validation and putting all - * rendering variables in a single place. - */ -public class RenderParams extends DhApiRenderParam -{ - private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - private static final long TIME_FOR_MAC_TO_FINISH_COMPILING_IN_MS = 10_000; - private static boolean initialLoadingComplete = false; - - - public IDhClientWorld dhClientWorld; - public IDhClientLevel dhClientLevel; - /** more specific override of the API value {@link DhApiRenderParam#clientLevelWrapper} */ - public IClientLevelWrapper clientLevelWrapper; - public ILightMapWrapper lightmap; - public RenderBufferHandler renderBufferHandler; - public IMcGenericRenderer genericRenderer; - public Vec3d exactCameraPosition; - /** @see DhRenderState#vanillaFogEnabled */ - public boolean vanillaFogEnabled; - - public boolean validationRun = false; - - - - //=============// - // constructor // - //=============// - //region - - public RenderParams(EDhApiRenderPass renderPass, DhRenderState renderState) - { - this(renderPass, - renderState.partialTickTime, - renderState.mcProjectionMatrix, renderState.mcModelViewMatrix, - renderState.clientLevelWrapper, - renderState.vanillaFogEnabled - ); - } - private RenderParams( - EDhApiRenderPass renderPass, - float newPartialTicks, - Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix, - IClientLevelWrapper clientLevelWrapper, - boolean vanillaFogEnabled - ) - { - super(renderPass, - newPartialTicks, - RenderUtil.getNearClipPlaneInBlocks(), RenderUtil.getFarClipPlaneDistanceInBlocks(), - newMcProjectionMatrix, newMcModelViewMatrix, - RenderUtil.createLodProjectionMatrix(newMcProjectionMatrix), RenderUtil.createLodModelViewMatrix(newMcModelViewMatrix), - clientLevelWrapper.getMinHeight(), - clientLevelWrapper); - - - this.dhClientWorld = SharedApi.tryGetDhClientWorld(); - if (this.dhClientWorld != null) - { - this.dhClientLevel = (IDhClientLevel) this.dhClientWorld.getLevel(clientLevelWrapper); - if (this.dhClientLevel != null) - { - this.renderBufferHandler = this.dhClientLevel.getRenderBufferHandler(); - this.genericRenderer = this.dhClientLevel.getGenericRenderer(); - } - } - - this.clientLevelWrapper = clientLevelWrapper; - this.lightmap = MC_RENDER.getLightmapWrapper(this.clientLevelWrapper); - - if (MC_CLIENT.playerExists()) - { - this.exactCameraPosition = MC_RENDER.getCameraExactPosition(); - } - - this.vanillaFogEnabled = vanillaFogEnabled; - - } - - //endregion - - - - //======================// - // parameter validation // - //======================// - //region - - /** - * Should be called before rendering is done. - * @return a message if LODs shouldn't be rendered, null if the LODs can render - */ - public String getValidationErrorMessage(long firstRenderTimeMs) - { - // Note: all strings here should be constants to prevent String allocations - - this.validationRun = true; - - - if (!MC_CLIENT.playerExists()) - { - return "No Player Exists"; - } - - if (this.dhClientWorld == null) - { - return "No DH Client World Loaded"; - } - - if (this.dhClientLevel == null) - { - return "No DH Client Level Loaded"; - } - - if (this.clientLevelWrapper == null) - { - return "No Client Level Wrapper Loaded"; - } - - if (this.lightmap == null) - { - return "No Lightmap Loaded"; - } - - if (this.renderBufferHandler == null) - { - return "No RenderBufferHandler Present"; - } - - if (this.genericRenderer == null) - { - return "No Generic Renderer Present"; - } - - if (this.dhModelViewMatrix == null - || this.mcModelViewMatrix == null) - { - return "No MVM or Proj Matrix Given"; - } - - if (AbstractOptifineAccessor.optifinePresent() - && MC_RENDER.getTargetFramebuffer() == -1) - { - // wait for MC to finish setting up their renderer - return "Optifine Target Frame Buffer not set"; - } - - - // potential fix for a segfault when - // Sodium and DH are running together - if (EPlatform.get() == EPlatform.MACOS - && !initialLoadingComplete) - { - // Once MC starts rendering, wait a few seconds so - // MC/Sodium can finish their shader compiling before DH does its own. - // This will allow DH to compile its own shaders after Sodium finishes - // compiling its own. - long nowMs = System.currentTimeMillis(); - long firstAllowedRenderTimeMs = firstRenderTimeMs + TIME_FOR_MAC_TO_FINISH_COMPILING_IN_MS; - if (nowMs < firstAllowedRenderTimeMs) - { - return "Waiting for initial MC compile..."; - } - - - // null shouldn't happen, but just in case - PriorityTaskPicker.Executor renderLoadExecutor = ThreadPoolUtil.getRenderLoadingExecutor(); - if (renderLoadExecutor == null) - { - return "Waiting for DH Threadpool..."; - } - - // wait for DH to finish loading, by the time that's done - // java should have finished all of DH's JIT compiling, - // which will hopefully mean less concurrency and thus a lower - // chance of breaking - // (plus this gives Sodium/vanill a bit longer to finish their setup) - int taskCount = renderLoadExecutor.getQueueSize(); - if (taskCount > 0) - { - return "Waiting for DH JIT compiling..."; - } - - initialLoadingComplete = true; - } - - - return null; - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java deleted file mode 100644 index a74dabde3..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/SSAORenderer.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOApplyShader; -import com.seibel.distanthorizons.core.render.renderer.shaders.SSAOShader; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL43C; - -import java.nio.ByteBuffer; - -/** - * Handles adding SSAO via {@link SSAOShader} and {@link SSAOApplyShader}.

- * - * {@link SSAOShader} - draws the SSAO to a texture.
- * {@link SSAOApplyShader} - draws the SSAO texture to DH's FrameBuffer.
- */ -public class SSAORenderer -{ - public static SSAORenderer INSTANCE = new SSAORenderer(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private boolean init = false; - - private int width = -1; - private int height = -1; - private int ssaoFramebuffer = -1; - - private int ssaoTexture = -1; - - - - //=============// - // constructor // - //=============// - - private SSAORenderer() { } - - public void init() - { - if (this.init) return; - this.init = true; - - SSAOShader.INSTANCE.init(); - SSAOApplyShader.INSTANCE.init(); - } - - private void createFramebuffer(int width, int height) - { - if (this.ssaoFramebuffer != -1) - { - GL32.glDeleteFramebuffers(this.ssaoFramebuffer); - this.ssaoFramebuffer = -1; - } - - if (this.ssaoTexture != -1) - { - GLMC.glDeleteTextures(this.ssaoTexture); - this.ssaoTexture = -1; - } - - this.ssaoFramebuffer = GL32.glGenFramebuffers(); - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.ssaoFramebuffer); - - this.ssaoTexture = GLMC.glGenTextures(); - { - GLMC.glBindTexture(this.ssaoTexture); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_R16F, width, height, 0, GL32.GL_RED, GL32.GL_HALF_FLOAT, (ByteBuffer) null); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); - - // disable mip-mapping since DH is just going to draw straight to the screen - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_BASE_LEVEL, 0); - GL43C.glTexParameteri(GL43C.GL_TEXTURE_2D, GL43C.GL_TEXTURE_MAX_LEVEL, 0); - } - - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.ssaoTexture, 0); - } - - - - //========// - // render // - //========// - - public void render(Mat4f projectionMatrix, float partialTicks) - { - try(GLState state = new GLState()) - { - this.init(); - - // resize the framebuffer if necessary - int width = MC_RENDER.getTargetFramebufferViewportWidth(); - int height = MC_RENDER.getTargetFramebufferViewportHeight(); - if (this.width != width || this.height != height) - { - this.width = width; - this.height = height; - this.createFramebuffer(width, height); - } - - SSAOShader.INSTANCE.frameBuffer = this.ssaoFramebuffer; - SSAOShader.INSTANCE.setProjectionMatrix(projectionMatrix); - SSAOShader.INSTANCE.render(partialTicks); - - SSAOApplyShader.INSTANCE.ssaoTexture = this.ssaoTexture; - SSAOApplyShader.INSTANCE.render(partialTicks); - } - } - - public void free() - { - SSAOShader.INSTANCE.free(); - SSAOApplyShader.INSTANCE.free(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java deleted file mode 100644 index b1d429cb5..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/ScreenQuad.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; -import org.lwjgl.opengl.GL32; -import org.lwjgl.system.MemoryUtil; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * Renders a full-screen textured quad to the screen. - * Used in composite / deferred rendering (IE fog). - */ -public class ScreenQuad -{ - public static ScreenQuad INSTANCE = new ScreenQuad(); - - private static final float[] box_vertices = { - -1, -1, - 1, -1, - 1, 1, - -1, -1, - 1, 1, - -1, 1, - }; - - //private GLVertexBuffer boxBuffer; - private AbstractVertexAttribute va; - private boolean init = false; - - - //=============// - // constructor // - //=============// - - private ScreenQuad() { } - - public void init() - { - if (this.init) return; - this.init = true; - - this.va = AbstractVertexAttribute.create(); - this.va.bind(); - - // Pos - this.va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false)); - this.va.completeAndCheck(Float.BYTES * 2); - - // Framebuffer - this.createBuffer(); - } - - public void render() - { - this.init(); - - //this.boxBuffer.bind(); - - this.va.bind(); - //this.va.bindBufferToAllBindingPoints(this.boxBuffer.getId()); - - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 6); - } - - private void createBuffer() - { - ByteBuffer buffer = MemoryUtil.memAlloc(box_vertices.length * Float.BYTES); - buffer.asFloatBuffer().put(box_vertices); - buffer.rewind(); - - //this.boxBuffer = new GLVertexBuffer(false); - //this.boxBuffer.bind(); - //this.boxBuffer.uploadBuffer(buffer, box_vertices.length, EDhApiGpuUploadMethod.DATA, box_vertices.length * Float.BYTES); - MemoryUtil.memFree(buffer); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java deleted file mode 100644 index eadf83958..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/TestRenderer.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; - -import org.lwjgl.opengl.GL32; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * Renders a UV colored quad - * to the center of the screen to confirm DH's - * apply shader is running correctly - */ -@Deprecated -public class TestRenderer -{ - public static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - public static final TestRenderer INSTANCE = new TestRenderer(); - - // Render a square with uv color - private static final float[] VERTICES = { - // PosX,Y, ColorR,G,B,A - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.4f, -0.4f, 1.0f, 0.0f, 0.0f, 1.0f, - 0.3f, 0.3f, 1.0f, 1.0f, 0.0f, 0.0f, - -0.2f, 0.2f, 0.0f, 1.0f, 1.0f, 1.0f - }; - - - - ShaderProgram basicShader; - GLVertexBuffer vbo; - AbstractVertexAttribute va; - boolean init = false; - - - - //=============// - // constructor // - //=============// - //region - - private TestRenderer() { } - - public void init() - { - if (this.init) - { - return; - } - - LOGGER.info("init"); - this.init = true; - this.va = AbstractVertexAttribute.create(); - this.va.bind(); - // Pos - this.va.setVertexAttribute(0, 0, VertexPointer.addVec2Pointer(false)); - // Color - this.va.setVertexAttribute(0, 1, VertexPointer.addVec4Pointer(false)); - this.va.completeAndCheck(Float.BYTES * 6); - this.basicShader = new ShaderProgram( - "shaders/test/vert.vert", - "shaders/test/frag.frag", - new String[]{"vPosition", "color"}); - - this.createBuffer(); - } - - private void createBuffer() - { - ByteBuffer buffer = ByteBuffer.allocateDirect(VERTICES.length * Float.BYTES); - // Fill buffer with vertices. - buffer.order(ByteOrder.nativeOrder()); - buffer.asFloatBuffer().put(VERTICES); - buffer.rewind(); - - this.vbo = new GLVertexBuffer(false); - this.vbo.bind(); - this.vbo.uploadBuffer(buffer, 4, EDhApiGpuUploadMethod.DATA, VERTICES.length * Float.BYTES); - } - - //endregion - - - - //========// - // render // - //========// - //region - - public void render() - { - this.init(); - - this.basicShader.bind(); - this.va.bind(); - - this.vbo.bind(); - this.va.bindBufferToAllBindingPoints(this.vbo.getId()); - - // Render the square - GL32.glDrawArrays(GL32.GL_TRIANGLE_FAN, 0, 4); - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java deleted file mode 100644 index f3b2af3f5..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/VanillaFadeRenderer.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.renderer.shaders.DhFadeShader; -import com.seibel.distanthorizons.core.render.renderer.shaders.FadeApplyShader; -import com.seibel.distanthorizons.core.render.renderer.shaders.VanillaFadeShader; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; -import com.seibel.distanthorizons.core.logging.DhLogger; -import org.lwjgl.opengl.GL32; - -import java.nio.ByteBuffer; - -/** - * Handles fading MC and DH together via {@link VanillaFadeShader} and {@link FadeApplyShader}.

- * - * {@link VanillaFadeShader} - draws the Fade to a texture.
- * {@link FadeApplyShader} - draws the Fade texture to MC's FrameBuffer.
- */ -public class VanillaFadeRenderer -{ - public static VanillaFadeRenderer INSTANCE = new VanillaFadeRenderer(); - - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - private boolean init = false; - - private int width = -1; - private int height = -1; - private int fadeFramebuffer = -1; - - private int fadeTexture = -1; - - - - //=============// - // constructor // - //=============// - - private VanillaFadeRenderer() { } - - public void init() - { - if (this.init) return; - this.init = true; - - VanillaFadeShader.INSTANCE.init(); - FadeApplyShader.INSTANCE.init(); - } - - private void createFramebuffer(int width, int height) - { - if (this.fadeFramebuffer != -1) - { - GL32.glDeleteFramebuffers(this.fadeFramebuffer); - this.fadeFramebuffer = -1; - } - - this.fadeFramebuffer = GL32.glGenFramebuffers(); - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.fadeFramebuffer); - - - // Applying the fade texture is only needed if MC is drawing to their own frame buffer, - // otherwise we can directly render to their texture - if (MC_RENDER.mcRendersToFrameBuffer()) - { - if (this.fadeTexture != -1) - { - GLMC.glDeleteTextures(this.fadeTexture); - this.fadeTexture = -1; - } - - this.fadeTexture = GL32.glGenTextures(); - GLMC.glBindTexture(this.fadeTexture); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16, width, height, 0, GL32.GL_RGBA, GL32.GL_UNSIGNED_SHORT_4_4_4_4, (ByteBuffer) null); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_LINEAR); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_LINEAR); - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.fadeTexture, 0); - } - else - { - GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, MC_RENDER.getColorTextureId(), 0); - } - } - - - - //========// - // render // - //========// - - public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level) - { - int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); - if (depthTextureId == -1) - { - // the renderer hasn't been set up yet - // trying to render fading may cause GL errors - return; - } - - - - IProfilerWrapper profiler = MC_CLIENT.getProfiler(); - profiler.pop(); // get out of "terrain" - profiler.push("DH-Vanilla Fade"); - - - try(GLState mcState = new GLState()) - { - profiler.push("Vanilla Fade Generate"); - - this.init(); - - // resize the framebuffer if necessary - int width = MC_RENDER.getTargetFramebufferViewportWidth(); - int height = MC_RENDER.getTargetFramebufferViewportHeight(); - if (this.width != width || this.height != height) - { - this.width = width; - this.height = height; - this.createFramebuffer(width, height); - } - - - VanillaFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; - VanillaFadeShader.INSTANCE.setProjectionMatrix(mcModelViewMatrix, mcProjectionMatrix); - VanillaFadeShader.INSTANCE.setLevelMaxHeight(level.getMaxHeight()); - VanillaFadeShader.INSTANCE.render(0); - - // Applying the fade texture is only needed if MC is drawing to their own frame buffer, - // otherwise we can directly render to their texture - if (MC_RENDER.mcRendersToFrameBuffer()) - { - profiler.popPush("Vanilla Fade Apply"); - - FadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; - FadeApplyShader.INSTANCE.readFramebuffer = DhFadeShader.INSTANCE.frameBuffer; - FadeApplyShader.INSTANCE.drawFramebuffer = MC_RENDER.getTargetFramebuffer(); - FadeApplyShader.INSTANCE.render(0); - } - - profiler.pop(); - } - catch (Exception e) - { - LOGGER.error("Unexpected error during fade render, error: ["+e.getMessage()+"].", e); - } - } - - public void free() - { - VanillaFadeShader.INSTANCE.free(); - FadeApplyShader.INSTANCE.free(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java deleted file mode 100644 index 00d4a8b5e..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/BeaconRenderHandler.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; -import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.coreapi.ModInfo; -import com.seibel.distanthorizons.core.logging.DhLogger; -import org.jetbrains.annotations.NotNull; - -import java.util.*; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Predicate; - -public class BeaconRenderHandler -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - /** how often should we check if a beacon should be culled? */ - private static final int MAX_CULLING_FREQUENCY_IN_MS = 1_000; - - private static final Comparator NEGATIVE_BLOCKPOS_COMPARATOR = new NegativeInfiniteBlockPosComparator(); - - - - private final ReentrantLock updateLock = new ReentrantLock(); - - /** only contains the beacons currently being rendered (culled beacons will be missing) */ - private final IDhApiRenderableBoxGroup activeBeaconBoxRenderGroup; - /** contains all beacons that could be rendered (including those that are being culled) */ - private final ArrayList fullBeaconBoxList = new ArrayList<>(); - /** contains all beacons that could be rendered */ - private final HashSet fullBeaconBlockPosSet = new HashSet<>(); - - private boolean cullingThreadRunning = false; - private boolean updateRenderDataNextFrame = false; - - - - //=============// - // constructor // - //=============// - //region - - public BeaconRenderHandler(@NotNull IMcGenericRenderer renderer) - { - this.activeBeaconBoxRenderGroup = GenericRenderObjectFactory.INSTANCE.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0)); - this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); - this.activeBeaconBoxRenderGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); - this.activeBeaconBoxRenderGroup.setSsaoEnabled(false); - this.activeBeaconBoxRenderGroup.setShading(DhApiRenderableBoxGroupShading.getUnshaded()); - this.activeBeaconBoxRenderGroup.setPreRenderFunc(this::beforeRender); - - renderer.add(this.activeBeaconBoxRenderGroup); - } - - //endregion - - - - //=================// - // render handling // - //=================// - //region - - public void startRenderingBeacons(ArrayList beaconList, byte detailLevel) - { - try - { - this.updateLock.lock(); - - - // how wide should each beacon be? - int beaconBlockWidth = 1; - if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get()) - { - beaconBlockWidth = DhSectionPos.getBlockWidth(detailLevel); - } - - - ArrayList sortedBeaconList = new ArrayList<>(beaconList); - - // merge distant beams if requested - if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get()) - { - // sort beacons from neg inf -> pos inf - // so we can consistently merge adjacent beacons - sortedBeaconList.sort(NEGATIVE_BLOCKPOS_COMPARATOR); - - // go through each beacon... - for (int outerIndex = 0; outerIndex < sortedBeaconList.size(); outerIndex++) - { - BeaconBeamDTO outerBeacon = sortedBeaconList.get(outerIndex); - DhBlockPos outerBlockPos = outerBeacon.blockPos; - - // ...and remove any beacons that are within the block width to prevent overlaps - for (int mergeIndex = outerIndex + 1; mergeIndex < sortedBeaconList.size(); mergeIndex++) - { - BeaconBeamDTO beaconToMerge = sortedBeaconList.get(mergeIndex); - DhBlockPos mergeBlockPos = beaconToMerge.blockPos; - - int xDiff = mergeBlockPos.getX() - outerBlockPos.getX(); - int zDiff = mergeBlockPos.getZ() - outerBlockPos.getZ(); - - // merge (remove) this beacon if - // it's close to the outer beacon - if (xDiff < beaconBlockWidth - && zDiff < beaconBlockWidth) - { - sortedBeaconList.remove(mergeIndex); - mergeIndex--; // minus 1 so we don't go past the end of the array when incrementing in the for loop up top - } - } - } - } - - - //LOGGER.info("startRenderingBeacons ["+sortedBeaconList+"]"); - - // add each beacon to the renderer - for (int i = 0; i < sortedBeaconList.size(); i++) - { - BeaconBeamDTO beacon = sortedBeaconList.get(i); - if (!this.fullBeaconBlockPosSet.add(beacon.blockPos)) - { - // skip already present beacons - continue; - } - - - int maxBeaconBeamHeight = Config.Client.Advanced.Graphics.GenericRendering.beaconRenderHeight.get(); - DhApiRenderableBox beaconBox = new DhApiRenderableBox( - new DhApiVec3d(beacon.blockPos.getX(), beacon.blockPos.getY() + 1, beacon.blockPos.getZ()), - new DhApiVec3d(beacon.blockPos.getX() + beaconBlockWidth, maxBeaconBeamHeight, beacon.blockPos.getZ() + beaconBlockWidth), - beacon.color, - EDhApiBlockMaterial.ILLUMINATED - ); - - this.activeBeaconBoxRenderGroup.add(beaconBox); - this.fullBeaconBoxList.add(beaconBox); - this.activeBeaconBoxRenderGroup.triggerBoxChange(); - } - } - finally - { - this.updateLock.unlock(); - } - } - - public void stopRenderingBeaconsInRange(long pos) - { - try - { - this.updateLock.lock(); - - Predicate removeBoxPredicate = (DhApiRenderableBox box) -> - { - DhBlockPos blockPos = new DhBlockPos((int)box.minPos.x, (int)box.minPos.y, (int)box.minPos.z); - boolean contains = DhSectionPos.contains(pos, blockPos); - //if (contains) - //{ - // LOGGER.info("stopRenderingBeaconsInRange ["+DhSectionPos.toString(pos)+"] ["+blockPos+"]"); - //} - return contains; - }; - this.activeBeaconBoxRenderGroup.removeIf(removeBoxPredicate); - this.fullBeaconBoxList.removeIf(removeBoxPredicate); - - this.fullBeaconBlockPosSet.removeIf((DhBlockPos blockPos) -> DhSectionPos.contains(pos, blockPos)); - - this.activeBeaconBoxRenderGroup.triggerBoxChange(); - } - finally - { - this.updateLock.unlock(); - } - } - - - private void beforeRender(DhApiRenderParam renderEventParam) - { - if (Config.Client.Advanced.Graphics.Culling.disableBeaconDistanceCulling.get()) - { - // this could be called only when the player moves, but it's an extremely cheap check, - // so there isn't much of a reason to bother - this.tryUpdateBeaconCullingAsync(); - } - - - // this must be called on the render thread to prevent concurrency issues - if (this.updateRenderDataNextFrame) - { - this.activeBeaconBoxRenderGroup.triggerBoxChange(); - this.updateRenderDataNextFrame = false; - } - this.activeBeaconBoxRenderGroup.setActive(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering.get()); - } - /** does nothing if the culling thread is already running */ - private void tryUpdateBeaconCullingAsync() - { - ThreadPoolExecutor executor = ThreadPoolUtil.getBeaconCullingExecutor(); - if (executor != null - && !this.cullingThreadRunning) - { - this.cullingThreadRunning = true; - - try - { - executor.execute(() -> - { - try - { - Thread.sleep(MAX_CULLING_FREQUENCY_IN_MS); - } - catch (InterruptedException ignore) { } - - try - { - // lock to make sure we don't try adding beacons to the arrays while processing them - this.updateLock.lock(); - - Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); - - // fading by the overdraw prevention amount helps reduce beacons from rendering strangely - // on the border of DH's render distance - float dhFadeDistance = RenderUtil.getNearClipPlaneInBlocks(); - - - // Clear the existing box group so we can re-populate it. - // Since the box group is only used when we trigger an update, clearing it here - // and repopulating it is fine. - this.activeBeaconBoxRenderGroup.clear(); - - // While iterating over every beacon isn't a great way of doing this, - // when 940 beacons were tested this only took ~0.9 Milliseconds, so as long as - // we aren't freezing the render thread this method of culling works just fine. - for (DhApiRenderableBox box : this.fullBeaconBoxList) - { - // if a beacon is outside the vanilla render distance render it - double distance = Vec3d.getHorizontalDistance(cameraPos, box.minPos); - if (distance > dhFadeDistance) - { - this.activeBeaconBoxRenderGroup.add(box); - } - } - - this.updateRenderDataNextFrame = true; - } - catch (Exception e) - { - LOGGER.error("Unexpected issue while updating beacon culling. Error: " + e.getMessage(), e); - } - finally - { - this.updateLock.unlock(); - this.cullingThreadRunning = false; - } - }); - } - catch (RejectedExecutionException ignore) - { /* If this happens that means everything is already shut down and no culling is necessary */ } - } - } - - //endregion - - - - //================// - // helper classes // - //================// - //region - - private static class NegativeInfiniteBlockPosComparator implements Comparator - { - @Override - public int compare(BeaconBeamDTO beacon1, BeaconBeamDTO beacon2) - { - DhBlockPos blockPos1 = beacon1.blockPos; - DhBlockPos blockPos2 = beacon2.blockPos; - - // sort by X, then by Z - if (blockPos1.getX() != blockPos2.getX()) - { - return Integer.compare(blockPos1.getX(), blockPos2.getX()); - } - return Integer.compare(blockPos1.getZ(), blockPos2.getZ()); - } - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java deleted file mode 100644 index cef2e1ae6..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/CloudRenderHandler.java +++ /dev/null @@ -1,617 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.level.IDhClientLevel; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; -import com.seibel.distanthorizons.coreapi.ModInfo; -import com.seibel.distanthorizons.core.logging.DhLogger; - -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -public class CloudRenderHandler -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - private static final String CLOUD_RESOURCE_TEXTURE_PATH = "assets/distanthorizons/textures/clouds.png"; - - private static final boolean DEBUG_BORDER_COLORS = false; - - /** - * How wide an individual box is.
- * Measured in blocks. - */ - private static final int CLOUD_BOX_WIDTH = 128; - /** measured in blocks */ - private static final int CLOUD_BOX_THICKNESS = 32; - - /** - * How many cloud groups wide can we render at maximum?
- * 1 = 3x3 or 9 total
- * 2 = 5x5 or 25 total

- * - * 5 seems like a good count since it can cover up to around 2048 render distance. - */ - private static final int CLOUD_INSTANCE_RADIUS_COUNT = 5; - - private static final float MOVE_SPEED_IN_BLOCKS_PER_SECOND = 6.0f; - - - private final IDhApiRenderableBoxGroup[][] boxGroupByOffset - // radius * 2 to get the diameter - // + 1 so we get an odd number wide (needed so we can have a center position) - = new IDhApiRenderableBoxGroup[(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1][(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1]; - - private final IDhClientLevel level; - private final IMcGenericRenderer renderer; - - /** cached array so we don't need to re-create it each frame for each cloud group */ - private final Vec3d[] cullingCorners = new Vec3d[] - { - // the values of each will be overwritten during the culling pass - new Vec3d(), - new Vec3d(), - new Vec3d(), - new Vec3d(), - }; - - - private boolean disabledWarningLogged = false; - - - - //=============// - // constructor // - //=============// - //region - - public CloudRenderHandler(IDhClientLevel level, IMcGenericRenderer renderer) - { - this.level = level; - this.renderer = renderer; - - - - //=======================// - // get the cloud texture // - //=======================// - //region - - // default to a single empty slot in case the texture is broken - boolean[][] cloudLocations = new boolean[1][1]; - try - { - cloudLocations = getCloudsFromTexture(); - } - catch (FileNotFoundException e) - { - LOGGER.error(e.getMessage(), e); - } - catch (IOException e) - { - LOGGER.error("Unexpected issue getting cloud texture, error: ["+e.getMessage()+"].", e); - } - - if (cloudLocations.length != 0 && - cloudLocations.length != cloudLocations[0].length) - { - LOGGER.warn("Non-square cloud texture found, some parts of the texture will be clipped off."); - } - - //endregion - - - - //===================// - // parse the texture // - //===================// - //region - - int textureWidth = cloudLocations.length; - ArrayList boxList = new ArrayList<>(512); - for (int x = 0; x < textureWidth; x ++) - { - for (int z = 0; z < textureWidth; z ++) - { - if (cloudLocations[x][z]) - { - // start a new box in Z direction - int startZ = z; - int startX = x; - int endZ = startZ; - int endX = x+1; - - - - //==========================// - // merge in the Z direction // - //==========================// - - // Find the cloud's length in the Z direction - while (endZ < textureWidth - && cloudLocations[x][endZ]) - { - endZ++; - } - // update the z iterator so we can skip over everything included in this cloud - z = endZ - 1; - - - - //==========================// - // merge in the X direction // - //==========================// - - for (int currentX = startX + 1; currentX < textureWidth; currentX++) - { - boolean canMergeInXDir = true; - - // check if all locations in this column are true - for (int adjacentZ = startZ; adjacentZ < endZ; adjacentZ++) - { - if (!cloudLocations[currentX][adjacentZ]) - { - // at least one pixel in the texture is false, - // so we can't merge in this direction - canMergeInXDir = false; - break; - } - } - - - if (canMergeInXDir) - { - // mark the adjacent column as processed - for (int currentZ = startZ; currentZ < endZ; currentZ++) - { - // by flipping all the pixels in the adjacent column to false, - // we don't have to worry about adding another cloud - cloudLocations[currentX][currentZ] = false; - } - - endX = (currentX + 1); - } - else - { - break; - } - } - - - - //============================// - // Create the renderable box // - //============================// - - // endZ contains the last cloud index - // so the cloud now goes from startZ to endZ (inclusive) - int minXBlockPos = startX * CLOUD_BOX_WIDTH; - int minZBlockPos = startZ * CLOUD_BOX_WIDTH; - int maxXBlockPos = endX * CLOUD_BOX_WIDTH; - int maxZBlockPos = endZ * CLOUD_BOX_WIDTH; - - // this color is changed at render time based on the level time - Color color = new Color(255,255,255,255); - if (DEBUG_BORDER_COLORS) - { - // equals is included so the boarder is 2 blocks wide, making it easier to see - if (x <= 1) { color = Color.RED; } - else if (x >= textureWidth - 2) { color = Color.GREEN; } - if (z <= 1) { color = Color.BLUE; } - else if (z >= textureWidth - 2) { color = Color.BLACK; } - } - - DhApiRenderableBox box = new DhApiRenderableBox( - new DhApiVec3d(minXBlockPos, 0, minZBlockPos), - new DhApiVec3d(maxXBlockPos, CLOUD_BOX_THICKNESS, maxZBlockPos), - color, - EDhApiBlockMaterial.UNKNOWN - ); - boxList.add(box); - } - } - } - - //endregion - - - - //========================// - // create the renderables // - //========================// - //region - - // slightly lighter shading than the default - DhApiRenderableBoxGroupShading cloudShading = DhApiRenderableBoxGroupShading.getUnshaded(); - cloudShading.north = cloudShading.south = 0.9f; - cloudShading.east = cloudShading.west = 0.8f; - cloudShading.top = 1.0f; - cloudShading.bottom = 0.7f; - - - for (int x = -CLOUD_INSTANCE_RADIUS_COUNT; x <= CLOUD_INSTANCE_RADIUS_COUNT; x++) - { - for (int z = -CLOUD_INSTANCE_RADIUS_COUNT; z <= CLOUD_INSTANCE_RADIUS_COUNT; z++) - { - IDhApiRenderableBoxGroup boxGroup = GenericRenderObjectFactory.INSTANCE.createRelativePositionedGroup( - ModInfo.NAME + ":Clouds", - new DhApiVec3d(0, 0, 0), // the offset will be set during rendering - boxList); - - // since cloud colors are set by the level based on the time of day lighting should affect it - boxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); - boxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); - boxGroup.setSsaoEnabled(false); - boxGroup.setShading(cloudShading); - - CloudParams cloudParams = new CloudParams(textureWidth, x, z); - boxGroup.setPreRenderFunc((renderParam) -> this.preRender(renderParam, cloudParams)); - - renderer.add(boxGroup); - this.boxGroupByOffset[x+CLOUD_INSTANCE_RADIUS_COUNT][z+CLOUD_INSTANCE_RADIUS_COUNT] = boxGroup; - } - } - } - - //endregion - - - - //===========// - // rendering // - //===========// - //region - - private void preRender(DhApiRenderParam renderParam, CloudParams cloudParams) - { - IDhApiRenderableBoxGroup boxGroup = this.boxGroupByOffset[cloudParams.instanceOffsetX+CLOUD_INSTANCE_RADIUS_COUNT][cloudParams.instanceOffsetZ+CLOUD_INSTANCE_RADIUS_COUNT]; - - - - //===================// - // should we render? // - //===================// - - boolean renderClouds = Config.Client.Advanced.Graphics.GenericRendering.enableCloudRendering.get(); - boxGroup.setActive(renderClouds); - if(!renderClouds) - { - return; - } - - //if (!this.renderer.getInstancedRenderingAvailable()) - //{ - // if (!this.disabledWarningLogged) - // { - // this.disabledWarningLogged = true; - // LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled."); - // } - // boxGroup.setActive(false); - // return; - //} - - IClientLevelWrapper clientLevelWrapper = this.level.getClientLevelWrapper(); - if (clientLevelWrapper == null) - { - return; - } - - - - //================// - // cloud movement // - //================// - - long currentTime = System.currentTimeMillis(); - float deltaTime = (currentTime - cloudParams.lastFrameTime) / 1000.0f; // Delta time in seconds - cloudParams.lastFrameTime = currentTime; - - float deltaX = MOVE_SPEED_IN_BLOCKS_PER_SECOND * deltaTime; - // negative delta is to match vanilla's cloud movement - cloudParams.deltaOffsetX -= deltaX; - // wrap the cloud around after reaching the edge - cloudParams.deltaOffsetX %= cloudParams.widthInBlocks; - - - - //============================// - // camera movement and offset // - //============================// - - // camera position - int cameraPosX = (int)MC_RENDER.getCameraExactPosition().x; - int cameraPosZ = (int)MC_RENDER.getCameraExactPosition().z; - // offset the camera position by negative 1 width when below zero to fix off-by-one errors in the negative direction - if (cameraPosX < 0) { cameraPosX -= cloudParams.widthInBlocks; } - if (cameraPosZ < 0) { cameraPosZ -= cloudParams.widthInBlocks; } - - // determine how many cloud instances away from the origin we are - int cloudInstanceOffsetCountX = (cameraPosX / cloudParams.widthInBlocks); - int cloudInstanceOffsetCountZ = (cameraPosZ / cloudParams.widthInBlocks); - // calculate the new offset - float instanceOffsetX = (cloudInstanceOffsetCountX * cloudParams.widthInBlocks); - float instanceOffsetZ = (cloudInstanceOffsetCountZ * cloudParams.widthInBlocks); - - - float newMinPosX = - cloudParams.deltaOffsetX - + (cloudParams.instanceOffsetX * cloudParams.widthInBlocks) - + instanceOffsetX + cloudParams.halfWidthInBlocks; - float newMinPosY = this.level.getLevelWrapper().getMaxHeight() + 200; - float newMinPosZ = cloudParams.deltaOffsetZ - + (cloudParams.instanceOffsetZ * cloudParams.widthInBlocks) - + instanceOffsetZ + cloudParams.halfWidthInBlocks; - - boolean cullCloud = this.shouldCloudBeCulled( - newMinPosX, newMinPosY, newMinPosZ, - cloudParams - ); - if(cullCloud) - { - boxGroup.setActive(false); - } - - - - //===========================// - // update color and position // - //===========================// - - // if debug colors are enabled don't change them - if (!DEBUG_BORDER_COLORS - // don't modify cloud groups that aren't active - && boxGroup.isActive()) - { - // cloud color changes based on the time of day and weather so we need to get it from the level - Color newCloudColor = clientLevelWrapper.getCloudColor(renderParam.partialTicks); - - - // all boxes should have the same color, so we can get their current color - // via the first box - DhApiRenderableBox firstBox = boxGroup.get(0); - Color currentBoxColor = firstBox.color; - - // update the boxes if their color should be changed - if (!newCloudColor.equals(currentBoxColor)) - { - // Note: cloud instances may share boxes - // because of that this method may only need to be called once per all clouds - for (DhApiRenderableBox box : boxGroup) - { - box.color = newCloudColor; - } - } - - - // trigger an update if this cloud section has a different color - if (!cloudParams.previousColor.equals(newCloudColor)) - { - cloudParams.previousColor = newCloudColor; - - boxGroup.triggerBoxChange(); - } - } - - boxGroup.setOriginBlockPos(new DhApiVec3d(newMinPosX, newMinPosY, newMinPosZ)); - } - private boolean shouldCloudBeCulled( - float minPosX, float minPosY, float minPosZ, - CloudParams cloudParams) - { - //========================// - // skip center 3x3 clouds // - //========================// - - // always render the center 3x3 clouds, otherwise we may see - // an un-rendered border - if (cloudParams.instanceOffsetX >= -1 && cloudParams.instanceOffsetX <= 1 - && cloudParams.instanceOffsetZ >= -1 && cloudParams.instanceOffsetZ <= 1) - { - return false; - } - - - - //==============// - // culling prep // - //==============// - - // we need all 4 corners since we want to draw any clouds that - // could potentially be within render distance - this.cullingCorners[0].x = minPosX; - this.cullingCorners[0].y = minPosY; - this.cullingCorners[0].z = minPosZ; - - this.cullingCorners[1].x = minPosX; - this.cullingCorners[1].y = minPosY; - this.cullingCorners[1].z = minPosZ + cloudParams.widthInBlocks; - - this.cullingCorners[2].x = minPosX + cloudParams.widthInBlocks; - this.cullingCorners[2].y = minPosY; - this.cullingCorners[2].z = minPosZ; - - this.cullingCorners[3].x = minPosX + cloudParams.widthInBlocks; - this.cullingCorners[3].y = minPosY; - this.cullingCorners[3].z = minPosZ + cloudParams.widthInBlocks; - - Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); - Vec3f cameraLookAtVector = MC_RENDER.getLookAtVector(); - cameraLookAtVector.normalize(); - - double renderDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() - // * 1.5 is so we have a little extra buffer where clouds will render further than - // necessary to prevent seeing the cloud border - * LodUtil.CHUNK_WIDTH * 1.5; - - - - //===================// - // check each corner // - //===================// - - boolean allOutsideRenderDistance = true; - boolean allBehindCamera = true; - - for (Vec3d corner : this.cullingCorners) - { - // Check if the corner is within the render distance - // (ignoring height, since LODs also ignore height) - - Vec3d cornerNoHeight = new Vec3d(corner); - cornerNoHeight.y = 0; - Vec3d cameraPosNoHeight = new Vec3d(cameraPos); - cameraPosNoHeight.y = 0; - - double cornerDistance = cornerNoHeight.getDistance(cameraPosNoHeight); - if (cornerDistance <= renderDistance) - { - allOutsideRenderDistance = false; - } - - - // Check if the corner is in front of the camera (dot product > 0 means in front) - Vec3f toCorner = new Vec3f( - (float) (corner.x - cameraPos.x), - (float) (corner.y - cameraPos.y), - (float) (corner.z - cameraPos.z)); - toCorner.normalize(); - - if (cameraLookAtVector.dotProduct(toCorner) > 0) - { - allBehindCamera = false; - } - } - - // Cull if all corners are either behind the camera or outside the render distance - return allOutsideRenderDistance || allBehindCamera; - } - - //endregion - - - - //==================// - // texture handling // - //==================// - //region - - private static boolean[][] getCloudsFromTexture() throws FileNotFoundException, IOException - { - final ClassLoader loader = CloudRenderHandler.class.getClassLoader(); - - boolean[][] whitePixels = null; - try(InputStream imageInputStream = loader.getResourceAsStream(CLOUD_RESOURCE_TEXTURE_PATH)) - { - if (imageInputStream == null) - { - throw new FileNotFoundException("Unable to find cloud texture at resource path: ["+CLOUD_RESOURCE_TEXTURE_PATH+"]."); - } - - BufferedImage image = ImageIO.read(imageInputStream); - - int width = image.getWidth(); - int height = image.getHeight(); - - whitePixels = new boolean[width][height]; - - for (int x = 0; x < width; x ++) - { - for (int z = 0; z < width; z ++) - { - Color color = new Color(image.getRGB(x,z)); - whitePixels[x][z] = color.equals(Color.WHITE); - } - } - } - - return whitePixels; - } - - //endregion - - - - //================// - // helper classes // - //================// - //region - - private static class CloudParams - { - public final int textureWidth; - public final int widthInBlocks; - public final int halfWidthInBlocks; - - public final int instanceOffsetX; - public final int instanceOffsetZ; - - - /** how far this cloud group has moved in the X direction based on time */ - public float deltaOffsetX = 0; - /** how far this cloud group has moved in the Z direction based on time */ - public float deltaOffsetZ = 0; - - public long lastFrameTime = System.currentTimeMillis(); - - /** used so we can trigger a VBO update when necessary */ - public Color previousColor = Color.WHITE; - - - - // constructor // - - public CloudParams(int textureWidth, int instanceOffsetX, int instanceOffsetZ) - { - this.textureWidth = textureWidth; - this.widthInBlocks = (this.textureWidth * CLOUD_BOX_WIDTH); - this.halfWidthInBlocks = this.widthInBlocks / 2; - - this.instanceOffsetX = instanceOffsetX; - this.instanceOffsetZ = instanceOffsetZ; - } - - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java deleted file mode 100644 index 69fd166b0..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectRenderer.java +++ /dev/null @@ -1,735 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; -import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; -import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.jar.EPlatform; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.logging.f3.F3Screen; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ISodiumAccessor; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; -import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; -import com.seibel.distanthorizons.coreapi.ModInfo; -import org.lwjgl.opengl.ARBInstancedArrays; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL33; -import org.lwjgl.system.MemoryUtil; - -import java.awt.*; -import java.nio.ByteBuffer; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Handles rendering generic groups of {@link DhApiRenderableBox}. - * - * @see IDhApiCustomRenderRegister - * @see DhApiRenderableBox - */ -public class GenericObjectRenderer implements IMcGenericRenderer -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final ISodiumAccessor SODIUM = ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded(); - - /** - * Can be used to troubleshoot the renderer. - * If enabled several debug objects will render around (0,150,0). - */ - public static final boolean RENDER_DEBUG_OBJECTS = false; - - - // rendering setup - private boolean init = false; - - private IDhApiGenericObjectShaderProgram instancedShaderProgram; - private IDhApiGenericObjectShaderProgram directShaderProgram; - //private GLVertexBuffer boxVertexBuffer; - private GLElementBuffer boxIndexBuffer; - - private boolean instancedRenderingAvailable; - private boolean vertexAttribDivisorSupported; - private boolean instancedArraysSupported; - - - - private final ConcurrentHashMap boxGroupById = new ConcurrentHashMap<>(); - - - - /** A box from 0,0,0 to 1,1,1 */ - private static final float[] BOX_VERTICES = { - //region - // Pos x y z - - // min X, vertical face - 0, 0, 0, - 1, 0, 0, - 1, 1, 0, - 0, 1, 0, - // max X, vertical face - 0, 1, 1, - 1, 1, 1, - 1, 0, 1, - 0, 0, 1, - - // min Z, vertical face - 0, 0, 1, - 0, 0, 0, - 0, 1, 0, - 0, 1, 1, - // max Z, vertical face - 1, 0, 1, - 1, 1, 1, - 1, 1, 0, - 1, 0, 0, - - // min Y, horizontal face - 0, 0, 1, - 1, 0, 1, - 1, 0, 0, - 0, 0, 0, - // max Y, horizontal face - 0, 1, 1, - 1, 1, 1, - 1, 1, 0, - 0, 1, 0, - //endregion - }; - - - private static final int[] BOX_INDICES = { - //region - // min X, vertical face - 2, 1, 0, - 0, 3, 2, - // max X, vertical face - 6, 5, 4, - 4, 7, 6, - - // min Z, vertical face - 10, 9, 8, - 8, 11, 10, - // max Z, vertical face - 14, 13, 12, - 12, 15, 14, - - // min Y, horizontal face - 18, 17, 16, - 16, 19, 18, - // max Y, horizontal face - 20, 21, 22, - 22, 23, 20, - //endregion - }; - - - - //=============// - // constructor // - //=============// - //region - - public GenericObjectRenderer() { } - - public void init() - { - if (this.init) - { - return; - } - this.init = true; - - - - //===================================// - // is instanced rendering available? // - //===================================// - - this.vertexAttribDivisorSupported = GLProxy.getInstance().vertexAttribDivisorSupported; - this.instancedArraysSupported = GLProxy.getInstance().instancedArraysSupported; - boolean isMac = (EPlatform.get() == EPlatform.MACOS); - this.instancedRenderingAvailable = (this.vertexAttribDivisorSupported || this.instancedArraysSupported) && !isMac; - if (!this.instancedRenderingAvailable) - { - LOGGER.warn("Instanced rendering not supported by this GPU, falling back to direct rendering. Generic object rendering will be slow and some effects may be disabled."); - } - - - - //======================// - // startup the renderer // - //======================// - - this.instancedShaderProgram = new GenericObjectShaderProgram(true); - this.directShaderProgram = new GenericObjectShaderProgram(false); - - this.createBuffers(); - - if (RENDER_DEBUG_OBJECTS) - { - this.addGenericDebugObjects(); - } - } - private void createBuffers() - { - // box vertices - ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES); - boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); - boxVerticesBuffer.rewind(); - //this.boxVertexBuffer = new GLVertexBuffer(false); - //this.boxVertexBuffer.bind(); - //this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); - MemoryUtil.memFree(boxVerticesBuffer); - - // box vertex indexes - ByteBuffer solidIndexBuffer = MemoryUtil.memAlloc(BOX_INDICES.length * Integer.BYTES); - solidIndexBuffer.asIntBuffer().put(BOX_INDICES); - solidIndexBuffer.rewind(); - this.boxIndexBuffer = new GLElementBuffer(false); - this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW); - this.boxIndexBuffer.bind(); - MemoryUtil.memFree(solidIndexBuffer); - } - private void addGenericDebugObjects() - { - GenericRenderObjectFactory factory = GenericRenderObjectFactory.INSTANCE; - - - // single giant box - IDhApiRenderableBoxGroup singleGiantBoxGroup = factory.createForSingleBox( - ModInfo.NAME + ":CyanChunkBox", - new DhApiRenderableBox( - new DhApiVec3d(0,0,0), new DhApiVec3d(16,190,16), - new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125), - EDhApiBlockMaterial.WATER) - ); - singleGiantBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); - singleGiantBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); - this.add(singleGiantBoxGroup); - - - // single slender box - IDhApiRenderableBoxGroup singleTallBoxGroup = factory.createForSingleBox( - ModInfo.NAME + ":GreenBeacon", - new DhApiRenderableBox( - new DhApiVec3d(16,0,31), new DhApiVec3d(17,2000,32), - new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125), - EDhApiBlockMaterial.ILLUMINATED) - ); - singleTallBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); - singleTallBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); - this.add(singleTallBoxGroup); - - - // absolute box group - ArrayList absBoxList = new ArrayList<>(); - for (int i = 0; i < 18; i++) - { - absBoxList.add(new DhApiRenderableBox( - new DhApiVec3d(i,150+i,24), new DhApiVec3d(1+i,151+i,25), - new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue()), - EDhApiBlockMaterial.LAVA - ) - ); - } - IDhApiRenderableBoxGroup absolutePosBoxGroup = factory.createAbsolutePositionedGroup(ModInfo.NAME + ":OrangeStairs", absBoxList); - this.add(absolutePosBoxGroup); - - - // relative box group - ArrayList relBoxList = new ArrayList<>(); - for (int i = 0; i < 8; i+=2) - { - relBoxList.add(new DhApiRenderableBox( - new DhApiVec3d(0,i,0), new DhApiVec3d(1,1+i,1), - new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue()), - EDhApiBlockMaterial.METAL - ) - ); - } - IDhApiRenderableBoxGroup relativePosBoxGroup = factory.createRelativePositionedGroup( - ModInfo.NAME + ":MovingMagentaGroup", - new DhApiVec3d(24, 140, 24), - relBoxList); - relativePosBoxGroup.setPreRenderFunc((event) -> - { - DhApiVec3d pos = relativePosBoxGroup.getOriginBlockPos(); - pos.x += event.partialTicks / 2; - pos.x %= 32; - relativePosBoxGroup.setOriginBlockPos(pos); - }); - this.add(relativePosBoxGroup); - - - // massive relative box group - ArrayList massRelBoxList = new ArrayList<>(); - for (int x = 0; x < 50*2; x+=2) - { - for (int z = 0; z < 50*2; z+=2) - { - massRelBoxList.add(new DhApiRenderableBox( - new DhApiVec3d(-x, 0, -z), new DhApiVec3d(1-x, 1, 1-z), - new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue()), - EDhApiBlockMaterial.TERRACOTTA - ) - ); - } - } - IDhApiRenderableBoxGroup massRelativePosBoxGroup = factory.createRelativePositionedGroup( - ModInfo.NAME + ":MassRedGroup", - new DhApiVec3d(-25, 140, 0), - massRelBoxList); - massRelativePosBoxGroup.setPreRenderFunc((event) -> - { - DhApiVec3d blockPos = massRelativePosBoxGroup.getOriginBlockPos(); - blockPos.y += event.partialTicks / 4; - if (blockPos.y > 150f) - { - blockPos.y = 140f; - - Color newColor = (massRelativePosBoxGroup.get(0).color == Color.RED) ? Color.RED.darker() : Color.RED; - massRelativePosBoxGroup.forEach((box) -> { box.color = newColor; }); - massRelativePosBoxGroup.triggerBoxChange(); - } - - massRelativePosBoxGroup.setOriginBlockPos(blockPos); - }); - this.add(massRelativePosBoxGroup); - } - - //endregion - - - - //==============// - // registration // - //==============// - //region - - @Override - public void add(IDhApiRenderableBoxGroup iBoxGroup) throws IllegalArgumentException - { - if (!(iBoxGroup instanceof RenderableBoxGroup)) - { - throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"]."); - } - RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup; - - - long id = boxGroup.getId(); - if (this.boxGroupById.containsKey(id)) - { - throw new IllegalArgumentException("A box group with the ID [" + id + "] is already present."); - } - - this.boxGroupById.put(id, boxGroup); - } - - @Override - public IDhApiRenderableBoxGroup remove(long id) { return this.boxGroupById.remove(id); } - - public void clear() { this.boxGroupById.clear(); } - - //endregion - - - - //===========// - // rendering // - //===========// - //region - - /** - * @param renderingWithSsao - * if true that means this render call is happening before the SSAO pass - * and any objects rendered in this pass will have SSAO applied to them. - */ - @Override - public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao) - { - // render setup // - profiler.push("setup"); - - this.init(); - - boolean useInstancedRendering = this.instancedRenderingAvailable - && Config.Client.Advanced.Graphics.GenericRendering.enableInstancedRendering.get(); - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam); - - - boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get(); - if (renderWireframe) - { - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE); - GLMC.disableFaceCulling(); - } - else - { - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - GLMC.enableFaceCulling(); - } - - GLMC.enableBlend(); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); - - IDhApiGenericObjectShaderProgram shaderProgram = useInstancedRendering ? this.instancedShaderProgram : this.directShaderProgram; - IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class); - if (shaderProgramOverride != null && shaderProgram.overrideThisFrame()) - { - shaderProgram = shaderProgramOverride; - } - - shaderProgram.bind(renderEventParam); - //shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId()); - - this.boxIndexBuffer.bind(); - - Vec3d camPos = MC_RENDER.getCameraExactPosition(); - - - - // rendering // - - Collection boxList = this.boxGroupById.values(); - for (RenderableBoxGroup boxGroup : boxList) - { - // validation // - - // shouldn't happen, but just in case - if (boxGroup == null) - { - continue; - } - - // skip boxes that shouldn't render this pass - if (boxGroup.ssaoEnabled != renderingWithSsao) - { - continue; - } - - profiler.popPush("render prep"); - boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired - - // ignore inactive groups - if (!boxGroup.active) - { - continue; - } - - // allow API users to cancel this object's rendering - boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup)); - if (cancelRendering) - { - continue; - } - - // update instanced data if needed - if (useInstancedRendering) - { - boxGroup.tryUpdateInstancedDataAsync(); - - // skip groups that haven't been uploaded yet - if (boxGroup.vertexBufferContainer.getState() != NativeGlGenericObjectVertexContainer.EState.RENDER) - { - continue; - } - } - - - - // render // - - profiler.popPush("rendering"); - profiler.push(boxGroup.getResourceLocationNamespace()); - profiler.push(boxGroup.getResourceLocationPath()); - if (useInstancedRendering) - { - this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler); - } - else - { - this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, camPos, profiler); - } - profiler.pop(); // resource path - profiler.pop(); // resource namespace - - boxGroup.postRender(renderEventParam); - } - - - //==========// - // clean up // - //==========// - - profiler.popPush("cleanup"); - - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam); - - if (renderWireframe) - { - // default back to GL_FILL since all other rendering uses it - GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL); - GLMC.enableFaceCulling(); - } - - shaderProgram.unbind(); - - profiler.pop(); - } - - //endregion - - - - //=====================// - // instanced rendering // - //=====================// - //region - - private void renderBoxGroupInstanced( - IDhApiGenericObjectShaderProgram shaderProgram, DhApiRenderParam renderEventParam, - RenderableBoxGroup boxGroup, Vec3d camPos, - IProfilerWrapper profiler) - { - // update instance data // - - profiler.push("vertex setup"); - - DhApiRenderableBoxGroupShading shading = boxGroup.shading; - if (shading == null) - { - shading = DEFAULT_SHADING; - } - - shaderProgram.fillIndirectUniformData( - renderEventParam, - shading, boxGroup, - camPos); - - - - // Bind instance data // - profiler.popPush("binding"); - - NativeGlGenericObjectVertexContainer container = (NativeGlGenericObjectVertexContainer)(boxGroup.vertexBufferContainer); - - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color); - GL32.glEnableVertexAttribArray(1); - GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0); - this.vertexAttribDivisor(1, 1); - - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale); - GL32.glEnableVertexAttribArray(2); - this.vertexAttribDivisor(2, 1); - GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); - - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos); - GL32.glEnableVertexAttribArray(3); - this.vertexAttribDivisor(3, 1); - GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0); - - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos); - GL32.glEnableVertexAttribArray(4); - this.vertexAttribDivisor(4, 1); - GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); - - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material); - GL32.glEnableVertexAttribArray(5); - this.vertexAttribDivisor(5, 1); - GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0); - - - // Draw instanced - profiler.popPush("render"); - if (container.uploadedBoxCount > 0) - { - GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount); - } - - - // Clean up - profiler.popPush("cleanup"); - - GL32.glDisableVertexAttribArray(1); - GL32.glDisableVertexAttribArray(2); - GL32.glDisableVertexAttribArray(3); - GL32.glDisableVertexAttribArray(4); - GL32.glDisableVertexAttribArray(5); - - profiler.pop(); - } - /** - * Clean way to handle both {@link GL33#glVertexAttribDivisor} and {@link ARBInstancedArrays#glVertexAttribDivisorARB} - * based on which one is supported. - */ - private void vertexAttribDivisor(int index, int divisor) - { - if (this.vertexAttribDivisorSupported) - { - GL33.glVertexAttribDivisor(index, divisor); - } - else if(this.instancedArraysSupported) - { - ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor); - } - else - { - throw new IllegalStateException("Instanced rendering isn't supported by this machine. Direct rendering should have been used instead."); - } - } - - //endregion - - - - //==================// - // direct rendering // - //==================// - //region - - private void renderBoxGroupDirect( - IDhApiGenericObjectShaderProgram shaderProgram, - DhApiRenderParam renderEventParam, - RenderableBoxGroup boxGroup, Vec3d camPos, - IProfilerWrapper profiler) - { - profiler.popPush("shared uniforms"); - DhApiRenderableBoxGroupShading shading = boxGroup.shading; - if (shading == null) - { - shading = DhApiRenderableBoxGroupShading.getUnshaded(); - } - - shaderProgram.fillSharedDirectUniformData(renderEventParam, shading, boxGroup, camPos); - - for (int i = 0; i < boxGroup.size(); i++) - { - try - { - DhApiRenderableBox box = boxGroup.get(i); - if (box != null) - { - profiler.popPush("direct uniforms"); - shaderProgram.fillDirectUniformData(renderEventParam, boxGroup, box, camPos); - - profiler.popPush("render"); - GL32.glDrawElements(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0); - } - } - catch (IndexOutOfBoundsException e) - { - // Concurrency issue, the list was modified while rendering - // this can probably be ignored. - // However, if it does become a problem we can add locks to the box group. - break; - } - } - - profiler.pop(); - } - - //endregion - - - - //=========// - // getters // - //=========// - //region - - /** @throws IllegalStateException if {@link #init()} function hasn't been called yet */ - public boolean getInstancedRenderingAvailable() throws IllegalStateException - { - if (!this.init) - { - throw new IllegalStateException("GL initialization hasn't been completed."); - } - - return this.instancedRenderingAvailable; - } - - //endregion - - - - //=========// - // F3 menu // - //=========// - //region - - public String getVboRenderDebugMenuString() - { - // get counts - int totalGroupCount = this.boxGroupById.size(); - int totalBoxCount = 0; - - int activeGroupCount = 0; - int activeBoxCount = 0; - - for (long key : this.boxGroupById.keySet()) - { - RenderableBoxGroup renderGroup = this.boxGroupById.get(key); - if (renderGroup.active) - { - activeGroupCount++; - activeBoxCount += renderGroup.size(); - } - totalBoxCount += renderGroup.size(); - } - - - return "Generic Obj #: " + F3Screen.NUMBER_FORMAT.format(activeGroupCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalGroupCount) + ", " + - "Cube #: " + F3Screen.NUMBER_FORMAT.format(activeBoxCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalBoxCount); - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectShaderProgram.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectShaderProgram.java deleted file mode 100644 index 572f5f8f2..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericObjectShaderProgram.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.seibel.distanthorizons.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3i; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; -import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; - -public class GenericObjectShaderProgram extends ShaderProgram implements IDhApiGenericObjectShaderProgram -{ - public static final String VERTEX_SHADER_INSTANCED_PATH = "shaders/genericObject/instanced/vert.vert"; - public static final String VERTEX_SHADER_DIRECT_PATH = "shaders/genericObject/direct/vert.vert"; - public static final String FRAGMENT_SHADER_INSTANCED_PATH = "shaders/genericObject/instanced/frag.frag"; - public static final String FRAGMENT_SHADER_DIRECT_PATH = "shaders/genericObject/direct/frag.frag"; - - public final AbstractVertexAttribute va; - - - // shader uniforms - private final int directShaderTransformUniform; - private final int directShaderColorUniform; - - private final int instancedShaderOffsetChunkUniform; - private final int instancedShaderOffsetSubChunkUniform; - private final int instancedShaderCameraChunkPosUniform; - private final int instancedShaderCameraSubChunkPosUniform; - private final int instancedShaderProjectionModelViewMatrixUniform; - - private final int lightMapUniform; - private final int skyLightUniform; - private final int blockLightUniform; - - private final int northShadingUniform; - private final int southShadingUniform; - private final int eastShadingUniform; - private final int westShadingUniform; - private final int topShadingUniform; - private final int bottomShadingUniform; - - - - //=============// - // constructor // - //=============// - - public GenericObjectShaderProgram(boolean useInstancedRendering) - { - super( - useInstancedRendering ? VERTEX_SHADER_INSTANCED_PATH : VERTEX_SHADER_DIRECT_PATH, - useInstancedRendering ? FRAGMENT_SHADER_INSTANCED_PATH : FRAGMENT_SHADER_DIRECT_PATH, - "vPosition" - ); - - this.va = AbstractVertexAttribute.create(); - this.va.bind(); - // Pos - this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false)); - this.va.completeAndCheck(Float.BYTES * 3); - - this.directShaderTransformUniform = this.tryGetUniformLocation("uTransform"); - this.directShaderColorUniform = this.tryGetUniformLocation("uColor"); - - this.instancedShaderOffsetChunkUniform = this.tryGetUniformLocation("uOffsetChunk"); - this.instancedShaderOffsetSubChunkUniform = this.tryGetUniformLocation("uOffsetSubChunk"); - this.instancedShaderCameraChunkPosUniform = this.tryGetUniformLocation("uCameraPosChunk"); - this.instancedShaderCameraSubChunkPosUniform = this.tryGetUniformLocation("uCameraPosSubChunk"); - this.instancedShaderProjectionModelViewMatrixUniform = this.tryGetUniformLocation("uProjectionMvm"); - - this.lightMapUniform = this.getUniformLocation("uLightMap"); - this.skyLightUniform = this.getUniformLocation("uSkyLight"); - this.blockLightUniform = this.getUniformLocation("uBlockLight"); - this.northShadingUniform = this.getUniformLocation("uNorthShading"); - this.southShadingUniform = this.getUniformLocation("uSouthShading"); - this.eastShadingUniform = this.getUniformLocation("uEastShading"); - this.westShadingUniform = this.getUniformLocation("uWestShading"); - this.topShadingUniform = this.getUniformLocation("uTopShading"); - this.bottomShadingUniform = this.getUniformLocation("uBottomShading"); - - } - - - - //=========// - // methods // - //=========// - - @Override - public void bind(DhApiRenderParam renderEventParam) - { - super.bind(); - this.va.bind(); - } - @Override - public void unbind() - { - super.unbind(); - this.va.unbind(); - } - - @Override - public void free() - { - this.va.free(); - super.free(); - } - - @Override - public void bindVertexBuffer(int vbo) { this.va.bindBufferToAllBindingPoints(vbo); } - - @Override - public void fillIndirectUniformData( - DhApiRenderParam renderParameters, - DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup, - DhApiVec3d camPos - ) - { - Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix); - projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix); - - super.bind(); - - - - - this.setUniform(this.instancedShaderOffsetChunkUniform, - new DhApiVec3i( - LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x), - LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y), - LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z) - )); - this.setUniform(this.instancedShaderOffsetSubChunkUniform, - new Vec3f( - LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x), - LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y), - LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z) - )); - - this.setUniform(this.instancedShaderCameraChunkPosUniform, - new DhApiVec3i( - LodUtil.getChunkPosFromDouble(camPos.x), - LodUtil.getChunkPosFromDouble(camPos.y), - LodUtil.getChunkPosFromDouble(camPos.z) - )); - this.setUniform(this.instancedShaderCameraSubChunkPosUniform, - new Vec3f( - LodUtil.getSubChunkPosFromDouble(camPos.x), - LodUtil.getSubChunkPosFromDouble(camPos.y), - LodUtil.getSubChunkPosFromDouble(camPos.z) - )); - - this.setUniform(this.instancedShaderProjectionModelViewMatrixUniform, projectionMvmMatrix); - - this.setUniform(this.lightMapUniform, ILightMapWrapper.BOUND_INDEX); - this.setUniform(this.skyLightUniform, boxGroup.getSkyLight()); - this.setUniform(this.blockLightUniform, boxGroup.getBlockLight()); - - - this.setUniform(this.northShadingUniform, shading.north); - this.setUniform(this.southShadingUniform, shading.south); - this.setUniform(this.eastShadingUniform, shading.east); - this.setUniform(this.westShadingUniform, shading.west); - this.setUniform(this.topShadingUniform, shading.top); - this.setUniform(this.bottomShadingUniform, shading.bottom); - - - } - - - @Override - public void fillSharedDirectUniformData( - DhApiRenderParam renderParameters, - DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup, - DhApiVec3d camPos) - { - - this.setUniform(this.lightMapUniform, ILightMapWrapper.BOUND_INDEX); - this.setUniform(this.skyLightUniform, boxGroup.getSkyLight()); - this.setUniform(this.blockLightUniform, boxGroup.getBlockLight()); - - - this.setUniform(this.northShadingUniform, shading.north); - this.setUniform(this.southShadingUniform, shading.south); - this.setUniform(this.eastShadingUniform, shading.east); - this.setUniform(this.westShadingUniform, shading.west); - this.setUniform(this.topShadingUniform, shading.top); - this.setUniform(this.bottomShadingUniform, shading.bottom); - - } - - public void fillDirectUniformData( - DhApiRenderParam renderParameters, - IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box, - DhApiVec3d camPos) - { - Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix); - projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix); - - Mat4f boxTransform = Mat4f.createTranslateMatrix( - (float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x), - (float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y), - (float) (box.minPos.z + boxGroup.getOriginBlockPos().z - camPos.z)); - boxTransform.multiply(Mat4f.createScaleMatrix( - (float) (box.maxPos.x - box.minPos.x), - (float) (box.maxPos.y - box.minPos.y), - (float) (box.maxPos.z - box.minPos.z))); - projectionMvmMatrix.multiply(boxTransform); - this.setUniform(this.directShaderTransformUniform, projectionMvmMatrix); - - this.setUniform(this.directShaderColorUniform, box.color); - - } - - - - @Override - public int getId() { return this.id; } - - /** The base DH render program should always render */ - @Override - public boolean overrideThisFrame() { return true; } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericRenderObjectFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericRenderObjectFactory.java deleted file mode 100644 index 57d568880..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/GenericRenderObjectFactory.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.math.Vec3f; -import com.seibel.distanthorizons.core.logging.DhLogger; - -import java.util.List; -import java.util.*; - -/** - * Handles creating {@link DhApiRenderableBox}. - * - * @see IDhApiCustomRenderRegister - * @see DhApiRenderableBox - */ -public class GenericRenderObjectFactory implements IDhApiCustomRenderObjectFactory -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - public static final GenericRenderObjectFactory INSTANCE = new GenericRenderObjectFactory(); - - - - //=============// - // constructor // - //=============// - - private GenericRenderObjectFactory() { } - - - - //================// - // group creation // - //================// - - @Override - public IDhApiRenderableBoxGroup createForSingleBox(String resourceLocation, DhApiRenderableBox box) - { - ArrayList list = new ArrayList<>(); - list.add(box); - return this.createAbsolutePositionedGroup(resourceLocation, list); - } - - @Override - public IDhApiRenderableBoxGroup createRelativePositionedGroup(String resourceLocation, DhApiVec3d originBlockPos, List boxList) - { return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(originBlockPos.x, originBlockPos.y, originBlockPos.z), boxList, true); } - - @Override - public IDhApiRenderableBoxGroup createAbsolutePositionedGroup(String resourceLocation, List boxList) - { return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(0, 0, 0), boxList, false); } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java deleted file mode 100644 index b627a5263..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/IGenericObjectVertexBufferContainer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.seibel.distanthorizons.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; - -import java.util.List; - -public interface IGenericObjectVertexBufferContainer extends AutoCloseable -{ - void uploadDataToGpu(); - - void updateVertexData(List uploadBoxList); - - EState getState(); - void setState(EState state); - - @Override - void close(); - - - - //================// - // helper classes // - //================// - //region - - enum EState - { - NEW, - UPDATING_DATA, - READY_TO_UPLOAD, - RENDER, - - ERROR, - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java deleted file mode 100644 index 870614b2c..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/NativeGlGenericObjectVertexContainer.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.seibel.distanthorizons.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -import java.awt.*; -import java.util.List; - -/** - * For use by {@link RenderableBoxGroup} - * - * @see RenderableBoxGroup - */ -public class NativeGlGenericObjectVertexContainer implements IGenericObjectVertexBufferContainer -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - - - public int chunkPos = 0; - public int subChunkPos = 0; - public int scale = 0; - public int color = 0; - public int material = 0; - - public int[] chunkPosData = new int[0]; - public float[] subChunkPosData = new float[0]; - public float[] scalingData = new float[0]; - public float[] colorData = new float[0]; - public int[] materialData = new int[0]; - - public int uploadedBoxCount = 0; - - private EState state = EState.NEW; - @Override - public EState getState() { return this.state; } - @Override - public void setState(EState state) { this.state = state; } - - - - //===========================// - // render building/uploading // - //===========================// - //region - - /** needs to be done on the render thread */ - public void tryRunRenderThreadSetup() - { - if (this.chunkPos == 0) - { - this.chunkPos = GLMC.glGenBuffers(); - this.subChunkPos = GLMC.glGenBuffers(); - this.scale = GLMC.glGenBuffers(); - this.color = GLMC.glGenBuffers(); - this.material = GLMC.glGenBuffers(); - } - } - - public void updateVertexData(List uploadBoxList) - { - int boxCount = uploadBoxList.size(); - - - // recreate the data arrays if their size is different - if (this.uploadedBoxCount != boxCount) - { - this.uploadedBoxCount = boxCount; - - this.chunkPosData = new int[boxCount * 3]; // 3 elements XYZ - this.subChunkPosData = new float[boxCount * 3]; // 3 elements XYZ - this.scalingData = new float[boxCount * 3]; // 3 elements XYZ - - this.colorData = new float[boxCount * 4]; // 4 elements, RGBA - this.materialData = new int[boxCount]; - } - - - // transformation / scaling // - for (int i = 0; i < boxCount; i++) - { - DhApiRenderableBox box = uploadBoxList.get(i); - - int dataIndex = i * 3; - - this.chunkPosData[dataIndex] = LodUtil.getChunkPosFromDouble(box.minPos.x); - this.chunkPosData[dataIndex + 1] = LodUtil.getChunkPosFromDouble(box.minPos.y); - this.chunkPosData[dataIndex + 2] = LodUtil.getChunkPosFromDouble(box.minPos.z); - - this.subChunkPosData[dataIndex] = LodUtil.getSubChunkPosFromDouble(box.minPos.x); - this.subChunkPosData[dataIndex + 1] = LodUtil.getSubChunkPosFromDouble(box.minPos.y); - this.subChunkPosData[dataIndex + 2] = LodUtil.getSubChunkPosFromDouble(box.minPos.z); - - this.scalingData[dataIndex] = (float) (box.maxPos.x - box.minPos.x); - this.scalingData[dataIndex + 1] = (float) (box.maxPos.y - box.minPos.y); - this.scalingData[dataIndex + 2] = (float) (box.maxPos.z - box.minPos.z); - } - - - // colors/materials // - for (int i = 0; i < boxCount; i++) - { - DhApiRenderableBox box = uploadBoxList.get(i); - Color color = box.color; - int colorIndex = i * 4; - this.colorData[colorIndex] = color.getRed() / 255.0f; - this.colorData[colorIndex + 1] = color.getGreen() / 255.0f; - this.colorData[colorIndex + 2] = color.getBlue() / 255.0f; - this.colorData[colorIndex + 3] = color.getAlpha() / 255.0f; - - this.materialData[i] = box.material; - } - - this.state = NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD; - } - - public void uploadDataToGpu() - { - // Upload transformation matrices - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.chunkPos); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.chunkPosData, GL32.GL_DYNAMIC_DRAW); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.subChunkPos); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.subChunkPosData, GL32.GL_DYNAMIC_DRAW); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.scale); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.scalingData, GL32.GL_DYNAMIC_DRAW); - - // Upload colors - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.color); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.colorData, GL32.GL_DYNAMIC_DRAW); - - // Upload materials - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.material); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.materialData, GL32.GL_DYNAMIC_DRAW); - - this.state = EState.RENDER; - } - - //endregion - - - - //================// - // base overrides // - //================// - //region - - @Override - public void close() - { - tryDeleteBuffer(this.chunkPos); - tryDeleteBuffer(this.subChunkPos); - tryDeleteBuffer(this.scale); - tryDeleteBuffer(this.color); - tryDeleteBuffer(this.material); - } - private static void tryDeleteBuffer(int bufferId) - { - // usually unnecessary, but just in case - if (bufferId != 0) - { - GLMC.glDeleteBuffers(bufferId); - } - } - - //endregion - - - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java deleted file mode 100644 index 54a4ea7ba..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/generic/RenderableBoxGroup.java +++ /dev/null @@ -1,362 +0,0 @@ -package com.seibel.distanthorizons.core.render.renderer.generic; - -import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; -import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLogger; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; -import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.jetbrains.annotations.Nullable; - -import java.io.Closeable; -import java.util.*; -import java.util.List; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -public class RenderableBoxGroup - extends AbstractList - implements IDhApiRenderableBoxGroup, Closeable -{ - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); - - public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0); - - - - public final long id; - - public final String resourceLocationNamespace; - public final String resourceLocationPath; - - /** If false the boxes will be positioned relative to the level's origin */ - public final boolean positionBoxesRelativeToGroupOrigin; - - private final List boxList; - /** backup list which allows for uploading the boxes even it the main list is being modified on a different thread. */ - private final List uploadBoxList; - private final DhApiVec3d originBlockPos; - - - public boolean active = true; - public boolean ssaoEnabled = true; - private boolean vertexDataDirty = true; - - public byte skyLight = LodUtil.MAX_MC_LIGHT; - public byte blockLight = LodUtil.MIN_MC_LIGHT; - public DhApiRenderableBoxGroupShading shading = DhApiRenderableBoxGroupShading.getDefaultShaded(); - - @Nullable - public Consumer beforeRenderFunc; - public Consumer afterRenderFunc; - - // instance data - public IGenericObjectVertexBufferContainer vertexBufferContainer = WRAPPER_FACTORY.createInstancedVboContainer(); - /** double buffering for thread safety and to prevent locking the render thread during update */ - private IGenericObjectVertexBufferContainer altVertexBufferContainer = WRAPPER_FACTORY.createInstancedVboContainer(); - - - - //=================// - // getters/setters // - //=================// - //region - - @Override - public long getId() { return this.id; } - - @Override - public String getResourceLocationNamespace() { return this.resourceLocationNamespace; } - @Override - public String getResourceLocationPath() { return this.resourceLocationPath; } - - @Override - public void setOriginBlockPos(DhApiVec3d pos) - { - this.originBlockPos.x = pos.x; - this.originBlockPos.y = pos.y; - this.originBlockPos.z = pos.z; - } - - @Override - public DhApiVec3d getOriginBlockPos() { return new DhApiVec3d(this.originBlockPos.x, this.originBlockPos.y, this.originBlockPos.z); } - - - @Override - public void setSkyLight(int skyLight) - { - if (skyLight < LodUtil.MIN_MC_LIGHT - || skyLight > LodUtil.MAX_MC_LIGHT) - { - throw new IllegalArgumentException("Sky light ["+skyLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive)."); - } - this.skyLight = (byte)skyLight; - } - @Override - public int getSkyLight() { return this.skyLight; } - - @Override - public void setBlockLight(int blockLight) - { - if (blockLight < LodUtil.MIN_MC_LIGHT - || blockLight > LodUtil.MAX_MC_LIGHT) - { - throw new IllegalArgumentException("Block light ["+blockLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive)."); - } - this.blockLight = (byte)blockLight; - } - @Override - public int getBlockLight() { return this.blockLight; } - - @Override - public void setPreRenderFunc(Consumer func) { this.beforeRenderFunc = func; } - - @Override - public void setPostRenderFunc(Consumer func) { this.afterRenderFunc = func; } - - @Override - public void setActive(boolean active) { this.active = active; } - @Override - public boolean isActive() { return this.active; } - - @Override - public void setSsaoEnabled(boolean ssaoEnabled) { this.ssaoEnabled = ssaoEnabled; } - @Override - public boolean isSsaoEnabled() { return this.ssaoEnabled; } - - @Override - public void setShading(DhApiRenderableBoxGroupShading shading) { this.shading = shading; } - @Override - public DhApiRenderableBoxGroupShading getShading() { return this.shading; } - - //endregion - - - - //=============// - // constructor // - //=============// - //region - - public RenderableBoxGroup( - String resourceLocation, - DhApiVec3d originBlockPos, List boxList, - boolean positionBoxesRelativeToGroupOrigin) throws IllegalArgumentException - { - String[] splitResourceLocation = resourceLocation.split(":"); - if (splitResourceLocation.length != 2) - { - throw new IllegalArgumentException("Resource Location must be a string that's separated by a single colon, for example: [DistantHorizons:Beacons], your namespace ["+resourceLocation+"], contains ["+(splitResourceLocation.length-1)+"] colons."); - } - - this.resourceLocationNamespace = splitResourceLocation[0]; - this.resourceLocationPath = splitResourceLocation[1]; - - this.id = NEXT_ID_ATOMIC_INT.getAndIncrement(); - this.boxList = Collections.synchronizedList(new ArrayList<>(boxList)); - this.uploadBoxList = Collections.synchronizedList(new ArrayList<>(boxList)); - - this.originBlockPos = originBlockPos; - this.positionBoxesRelativeToGroupOrigin = positionBoxesRelativeToGroupOrigin; - } - - //endregion - - - - //=================// - // render building // - //=================// - //region - - @Override - public void triggerBoxChange() { this.vertexDataDirty = true; } - - /** - * Does nothing if the vertex data is already up-to-date - * and is meaningless if using direct rendering. - */ - public void tryUpdateInstancedDataAsync() - { - // if the alt container is done, swap it in - if (this.altVertexBufferContainer.getState() == NativeGlGenericObjectVertexContainer.EState.READY_TO_UPLOAD) - { - this.altVertexBufferContainer.uploadDataToGpu(); - - // swap VBO references for rendering - IGenericObjectVertexBufferContainer temp = this.vertexBufferContainer; - this.vertexBufferContainer = this.altVertexBufferContainer; - this.altVertexBufferContainer = temp; - - this.vertexDataDirty = false; - - return; - } - - - - // if the vertex data is already up to date, do nothing - if (!this.vertexDataDirty) - { - return; - } - - PriorityTaskPicker.Executor executor = ThreadPoolUtil.getRenderLoadingExecutor(); - if (executor == null || executor.isTerminated()) - { - return; - } - - // if the alternate container is already updating, don't double-queue it - if (this.altVertexBufferContainer.getState() == NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA) - { - return; - } - this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.UPDATING_DATA); - - - - //this.altInstancedVbos.tryRunRenderThreadSetup(); - - // copy over the box list so we can upload without concurrent modification issues - this.uploadBoxList.clear(); - synchronized (this.uploadBoxList) - { - this.uploadBoxList.addAll(this.boxList); - } - - try - { - executor.runTask(() -> - { - try - { - this.altVertexBufferContainer.updateVertexData(this.uploadBoxList); - } - catch (Exception e) - { - LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e); - this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.ERROR); - } - }); - } - catch (RejectedExecutionException ignore) - { - // the executor was shut down, it should be back up shortly and able to accept new jobs - this.altVertexBufferContainer.setState(NativeGlGenericObjectVertexContainer.EState.NEW); - } - } - - //endregion - - - - //===============// - // render events // - //===============// - //region - - /** - * This is called before every frame, even if {@link this#isActive()} returns false.
- * {@link this#isActive()} can be changed at this point before the object is rendered to the frame. - */ - public void preRender(DhApiRenderParam renderEventParam) - { - if (this.beforeRenderFunc != null) - { - this.beforeRenderFunc.accept(renderEventParam); - } - } - /** - * Called after rendering is completed.
- * Can be used to handle any necessary cleanup. - */ - public void postRender(DhApiRenderParam renderEventParam) - { - if (this.afterRenderFunc != null) - { - this.afterRenderFunc.accept(renderEventParam); - } - } - - //endregion - - - - //================// - // List Overrides // - //================// - //region - - @Override - public boolean add(DhApiRenderableBox box) { return this.boxList.add(box); } - @Override - public DhApiRenderableBox get(int index) { return this.boxList.get(index); } - @Override - public int size() { return this.boxList.size(); } - @Override - public boolean removeIf(Predicate filter) { return this.boxList.removeIf(filter); } - @Override - public boolean remove(Object obj) { return this.boxList.remove(obj); } - @Override - public DhApiRenderableBox remove(int index) { return this.boxList.remove(index); } - @Override - public void replaceAll(UnaryOperator operator) { this.boxList.replaceAll(operator); } - @Override - public void sort(Comparator comparator) { this.boxList.sort(comparator); } - @Override - public void forEach(Consumer action) { this.boxList.forEach(action); } - @Override - public Spliterator spliterator() { return this.boxList.spliterator(); } - @Override - public Stream stream() { return this.boxList.stream(); } - @Override - public Stream parallelStream() { return this.boxList.parallelStream(); } - @Override - public void clear() { this.boxList.clear(); } - - //endregion - - - - //================// - // base overrides // - //================// - //region - - @Override - public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:[("+this.originBlockPos.x+", "+this.originBlockPos.y+", "+this.originBlockPos.z+")], size:["+this.size()+"], active:["+this.active+"]"; } - - @Override - public void close() - { - GLProxy.queueRunningOnRenderThread(() -> - { - this.vertexBufferContainer.close(); - this.altVertexBufferContainer.close(); - }); - } - - //endregion - - - -} - \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java deleted file mode 100644 index 46ee19402..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/AbstractShaderRenderer.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -public abstract class AbstractShaderRenderer -{ - protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - - protected ShaderProgram shader; - - protected boolean init = false; - - - protected AbstractShaderRenderer() {} - - public void init() - { - if (this.init) return; - this.init = true; - - this.onInit(); - } - - public void render(float partialTicks) - { - this.init(); - - this.shader.bind(); - - this.onApplyUniforms(partialTicks); - - int width = MC_RENDER.getTargetFramebufferViewportWidth(); - int height = MC_RENDER.getTargetFramebufferViewportHeight(); - GL32.glViewport(0, 0, width, height); - - this.onRender(); - - this.shader.unbind(); - } - - public void free() - { - if (this.shader != null) - { - this.shader.free(); - } - } - - protected void onInit() {} - - protected void onApplyUniforms(float partialTicks) {} - - protected void onRender() {} -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java deleted file mode 100644 index 7bc27b240..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhApplyShader.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.glObject.GLState; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.logging.DhLogger; -import org.lwjgl.opengl.GL32; - -/** - * Copies {@link BlazeLodRenderer}'s currently active color and depth texture to Minecraft's framebuffer. - */ -public class DhApplyShader extends AbstractShaderRenderer -{ - public static DhApplyShader INSTANCE = new DhApplyShader(); - - private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - // uniforms - public int gDhColorTextureUniform; - public int gDepthMapUniform; - - - - //=======// - // setup // - //=======// - //region - - private DhApplyShader() { } - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/apply.frag", - "vPosition" - ); - - // uniform setup - this.gDhColorTextureUniform = this.shader.getUniformLocation("gDhColorTexture"); - this.gDepthMapUniform = this.shader.getUniformLocation("gDhDepthTexture"); - - } - - @Override - protected void onApplyUniforms(float partialTicks) { } - - //endregion - - - - //========// - // render // - //========// - //region - - @Override - protected void onRender() - { - if (MC_RENDER.mcRendersToFrameBuffer()) - { - this.renderToFrameBuffer(); - } - else - { - this.renderToMcTexture(); - } - } - private void renderToFrameBuffer() - { - int targetFrameBuffer = MC_RENDER.getTargetFramebuffer(); - if (targetFrameBuffer == -1) - { - return; - } - - - try (GLState state = new GLState()) - { - - GLMC.disableDepthTest(); - - // blending isn't needed, we're manually merging the MC and DH textures - // Note: this prevents the sun/moon and stars from rendering through transparent LODs, - // however this also fixes transparent LODs from glowing when rendered against the sky during the day - GLMC.disableBlend(); - - // old blending logic in case it's ever needed: - //GLMC.enableBlend(); - //GL32.glBlendEquation(GL32.GL_FUNC_ADD); - //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveColorTextureId()); - GL32.glUniform1i(this.gDhColorTextureUniform, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - GL32.glUniform1i(this.gDepthMapUniform, 1); - - // Copy to MC's framebuffer - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, targetFrameBuffer); - - ScreenQuad.INSTANCE.render(); - } - // everything's been restored, except at this point the MC framebuffer should now be used instead - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, targetFrameBuffer); - - } - private void renderToMcTexture() - { - int targetColorTextureId = MC_RENDER.getColorTextureId(); - if (targetColorTextureId == -1) - { - return; - } - - int dhFrameBufferId = BlazeLodRenderer.INSTANCE.getActiveFramebufferId(); - if (dhFrameBufferId == -1) - { - return; - } - - int mcFrameBufferId = MC_RENDER.getTargetFramebuffer(); - if (mcFrameBufferId == -1) - { - return; - } - - - - try (GLState state = new GLState()) - { - GLMC.disableDepthTest(); - - // blending isn't needed, we're just directly merging the MC and DH textures - // Note: this prevents the sun/moon and stars from rendering through transparent LODs, - // however this also fixes - GLMC.disableBlend(); - - // old blending logic in case it's ever needed: - //GLMC.enableBlend(); - //GL32.glBlendEquation(GL32.GL_FUNC_ADD); - //GLMC.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveColorTextureId()); - GL32.glUniform1i(this.gDhColorTextureUniform, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - GL32.glUniform1i(this.gDepthMapUniform, 1); - - - - GL32.glFramebufferTexture(GL32.GL_DRAW_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, targetColorTextureId, 0); - - // Copy to MC's texture via MC's framebuffer - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, dhFrameBufferId); - - ScreenQuad.INSTANCE.render(); - } - // everything's been restored, except at this point the MC framebuffer should now be used instead - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, mcFrameBufferId); - - } - - //endregion - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java deleted file mode 100644 index aa3740528..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/DhFadeShader.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -public class DhFadeShader extends AbstractShaderRenderer -{ - public static DhFadeShader INSTANCE = new DhFadeShader(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int frameBuffer = -1; - - private Mat4f inverseDhMvmProjMatrix; - - - // Uniforms - - /** Inverted Model View Projection matrix */ - public int uDhInvMvmProj = -1; - - public int uDhDepthTexture = -1; - public int uMcColorTexture = -1; - public int uDhColorTexture = -1; - - public int uStartFadeBlockDistance = -1; - public int uEndFadeBlockDistance = -1; - - - - //=============// - // constructor // - //=============// - - public DhFadeShader() { } - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/fade/dhFade.frag", - "vPosition" - ); - - // all uniforms should be tryGet... - // because disabling fade can cause the GLSL to optimize out most (if not all) uniforms - - // near fade - this.uDhInvMvmProj = this.shader.tryGetUniformLocation("uDhInvMvmProj"); - - this.uDhDepthTexture = this.shader.tryGetUniformLocation("uDhDepthTexture"); - this.uMcColorTexture = this.shader.tryGetUniformLocation("uMcColorTexture"); - this.uDhColorTexture = this.shader.tryGetUniformLocation("uDhColorTexture"); - - this.uStartFadeBlockDistance = this.shader.tryGetUniformLocation("uStartFadeBlockDistance"); - this.uEndFadeBlockDistance = this.shader.tryGetUniformLocation("uEndFadeBlockDistance"); - - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - this.shader.setUniform(this.uDhInvMvmProj, this.inverseDhMvmProjMatrix); - - - float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks(); - float fadeStartDistance = dhFarClipDistance * 0.5f; - float fadeEndDistance = dhFarClipDistance * 0.9f; - - this.shader.setUniform(this.uStartFadeBlockDistance, fadeStartDistance); - this.shader.setUniform(this.uEndFadeBlockDistance, fadeEndDistance); - - } - - public void setProjectionMatrix(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix) - { - Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix); - Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix); - - Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix); - inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix); - inverseDhModelViewProjectionMatrix.invert(); - this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix; - } - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); - - if (depthTextureId == -1 - || colorTextureId == -1) - { - // the renderer is currently being re-built and/or inactive, - // we don't need to/can't render fading - return; - } - - - - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer); - GLMC.disableScissorTest(); - GLMC.disableDepthTest(); - GLMC.disableBlend(); - - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(depthTextureId); - GL32.glUniform1i(this.uDhDepthTexture, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(MC_RENDER.getColorTextureId()); - GL32.glUniform1i(this.uMcColorTexture, 1); - - GLMC.glActiveTexture(GL32.GL_TEXTURE2); - GLMC.glBindTexture(colorTextureId); - GL32.glUniform1i(this.uDhColorTexture, 2); - - - ScreenQuad.INSTANCE.render(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java deleted file mode 100644 index e3940cafa..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FadeApplyShader.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.VanillaFadeRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -/** - * Draws the Fade texture onto Minecraft's FrameBuffer.

- * - * See Also:
- * {@link VanillaFadeRenderer} - Parent to this shader.
- * {@link VanillaFadeShader} - draws the Fade texture.
- */ -public class FadeApplyShader extends AbstractShaderRenderer -{ - public static FadeApplyShader INSTANCE = new FadeApplyShader(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - - public int fadeTexture; - - public int readFramebuffer; - public int drawFramebuffer; - - // uniforms - public int uFadeColorTextureUniform = -1; - - - - //=============// - // constructor // - //=============// - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/fade/apply.frag", - "vPosition" - ); - - // uniform setup - this.uFadeColorTextureUniform = this.shader.getUniformLocation("uFadeColorTextureUniform"); - - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(this.fadeTexture); - GL32.glUniform1i(this.uFadeColorTextureUniform, 0); - - } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - GLMC.disableBlend(); - - // Depth testing must be disabled otherwise this application shader won't apply anything. - // setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually, - // it should be automatically restored after rendering is complete. - GLMC.disableDepthTest(); - - - // apply the rendered Fade to Minecraft's framebuffer - GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.readFramebuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, this.drawFramebuffer); - - ScreenQuad.INSTANCE.render(); - - GLMC.enableDepthTest(); - - } - - - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java deleted file mode 100644 index e3136f663..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogApplyShader.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.FogRenderer; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL32; - -/** - * Draws the Fog texture onto DH's FrameBuffer.

- * - * See Also:
- * {@link FogRenderer} - Parent to this shader.
- * {@link FogShader} - draws the Fog texture.
- */ -public class FogApplyShader extends AbstractShaderRenderer -{ - public static FogApplyShader INSTANCE = new FogApplyShader(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int fogTexture; - - // uniforms - public int colorTextureUniform; - public int depthTextureUniform; - - - - //=============// - // constructor // - //=============// - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/fog/apply.frag", - "vPosition" - ); - - // uniform setup - this.colorTextureUniform = this.shader.getUniformLocation("uColorTexture"); - this.depthTextureUniform = this.shader.getUniformLocation("uDepthTexture"); - - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(this.fogTexture); - GL32.glUniform1i(this.colorTextureUniform, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - GL32.glUniform1i(this.depthTextureUniform, 1); - - } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - GLMC.enableBlend(); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA); - - // Depth testing must be disabled otherwise this application shader won't apply anything. - // setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually, - // it should be automatically restored after rendering is complete. - GLMC.disableDepthTest(); - - - // apply the rendered Fog to DH's framebuffer - GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, FogShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, BlazeLodRenderer.INSTANCE.getActiveFramebufferId()); - - ScreenQuad.INSTANCE.render(); - - GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, 0); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java deleted file mode 100644 index c7c7181e7..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/FogShader.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode; -import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection; -import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode; -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -import java.awt.*; - -public class FogShader extends AbstractShaderRenderer -{ - public static final FogShader INSTANCE = new FogShader(); - - private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - - - - public int frameBuffer; - - private Mat4f inverseMvmProjMatrix; - - - - //==========// - // Uniforms // - //==========// - - public int uDepthMap; - /** Inverted Model View Projection matrix */ - public int uInvMvmProj; - - // fog uniforms - public int uFogColor; - public int uFogScale; - public int uFogVerticalScale; - public int uFogDebugMode; - public int uFogFalloffType; - - // far fog - public int uFarFogStart; - public int uFarFogLength; - public int uFarFogMin; - public int uFarFogRange; - public int uFarFogDensity; - - // height fog - public int uHeightFogStart; - public int uHeightFogLength; - public int uHeightFogMin; - public int uHeightFogRange; - public int uHeightFogDensity; - - public int uHeightFogEnabled; - public int uHeightFogFalloffType; - public int uHeightBasedOnCamera; - public int uHeightFogBaseHeight; - public int uHeightFogAppliesUp; - public int uHeightFogAppliesDown; - public int uUseSphericalFog; - public int uHeightFogMixingMode; - public int uCameraBlockYPos; - - - - //=============// - // constructor // - //=============// - - public FogShader() { } - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/fog/fog.frag", - "vPosition" - ); - - // all uniforms should be tryGet... - // because disabling fog can cause the GLSL to optimize out most (if not all) uniforms - - this.uDepthMap = this.shader.getUniformLocation("uDepthMap"); - this.uInvMvmProj = this.shader.getUniformLocation("uInvMvmProj"); - - // Fog uniforms - this.uFogScale = this.shader.getUniformLocation("uFogScale"); - this.uFogVerticalScale = this.shader.getUniformLocation("uFogVerticalScale"); - this.uFogColor = this.shader.getUniformLocation("uFogColor"); - this.uFogDebugMode = this.shader.getUniformLocation("uFogDebugMode"); - this.uFogFalloffType = this.shader.getUniformLocation("uFogFalloffType"); - - // fog config - this.uFarFogStart = this.shader.getUniformLocation("uFarFogStart"); - this.uFarFogLength = this.shader.getUniformLocation("uFarFogLength"); - this.uFarFogMin = this.shader.getUniformLocation("uFarFogMin"); - this.uFarFogRange = this.shader.getUniformLocation("uFarFogRange"); - this.uFarFogDensity = this.shader.getUniformLocation("uFarFogDensity"); - - // height fog - this.uHeightFogStart = this.shader.getUniformLocation("uHeightFogStart"); - this.uHeightFogLength = this.shader.getUniformLocation("uHeightFogLength"); - this.uHeightFogMin = this.shader.getUniformLocation("uHeightFogMin"); - this.uHeightFogRange = this.shader.getUniformLocation("uHeightFogRange"); - this.uHeightFogDensity = this.shader.getUniformLocation("uHeightFogDensity"); - - this.uHeightFogEnabled = this.shader.getUniformLocation("uHeightFogEnabled"); - this.uHeightFogFalloffType = this.shader.getUniformLocation("uHeightFogFalloffType"); - this.uHeightBasedOnCamera = this.shader.getUniformLocation("uHeightBasedOnCamera"); - this.uHeightFogBaseHeight = this.shader.getUniformLocation("uHeightFogBaseHeight"); - this.uHeightFogAppliesUp = this.shader.getUniformLocation("uHeightFogAppliesUp"); - this.uHeightFogAppliesDown = this.shader.getUniformLocation("uHeightFogAppliesDown"); - this.uUseSphericalFog = this.shader.getUniformLocation("uUseSphericalFog"); - this.uHeightFogMixingMode = this.shader.getUniformLocation("uHeightFogMixingMode"); - this.uCameraBlockYPos = this.shader.getUniformLocation("uCameraBlockYPos"); - - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH; - - - - if (this.inverseMvmProjMatrix != null) - { - this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix); - } - - - // Fog uniforms - this.shader.setUniform(this.uFogColor, this.getFogColor(partialTicks)); - this.shader.setUniform(this.uFogScale, 1.f / lodDrawDistance); - this.shader.setUniform(this.uFogVerticalScale, 1.f / MC.getWrappedClientLevel().getMaxHeight()); - // only used for debugging - this.shader.setUniform(this.uFogDebugMode, 0); // 1 = render everything with fog color // 7 = use debug rendering - this.shader.setUniform(this.uFogFalloffType, Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value); - - - // fog config - float farFogStart = Config.Client.Advanced.Graphics.Fog.farFogStart.get(); - float farFogEnd = Config.Client.Advanced.Graphics.Fog.farFogEnd.get(); - float farFogMin = Config.Client.Advanced.Graphics.Fog.farFogMin.get(); - float farFogMax = Config.Client.Advanced.Graphics.Fog.farFogMax.get(); - float farFogDensity = Config.Client.Advanced.Graphics.Fog.farFogDensity.get(); - - // override fog if underwater - if (MC_RENDER.isFogStateSpecial()) - { - // hide everything behind fog - farFogStart = 0.0f; - farFogEnd = 0.0f; - } - - this.shader.setUniform(this.uFarFogStart, farFogStart); - this.shader.setUniform(this.uFarFogLength, farFogEnd - farFogStart); - this.shader.setUniform(this.uFarFogMin, farFogMin); - this.shader.setUniform(this.uFarFogRange, farFogMax - farFogMin); - this.shader.setUniform(this.uFarFogDensity, farFogDensity); - - - // height config - EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get(); - boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL; - boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL; - EDhApiHeightFogDirection heightFogCameraDirection = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection.get(); - - float heightFogStart = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogStart.get(); - float heightFogEnd = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get(); - float heightFogMin = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get(); - float heightFogMax = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get(); - float heightFogDensity = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get(); - - this.shader.setUniform(this.uHeightFogStart, heightFogStart); - this.shader.setUniform(this.uHeightFogLength, heightFogEnd - heightFogStart); - this.shader.setUniform(this.uHeightFogMin, heightFogMin); - this.shader.setUniform(this.uHeightFogRange, heightFogMax - heightFogMin); - this.shader.setUniform(this.uHeightFogDensity, heightFogDensity); - - - this.shader.setUniform(this.uHeightFogEnabled, heightFogEnabled); - this.shader.setUniform(this.uHeightFogFalloffType, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value); - this.shader.setUniform(this.uHeightFogBaseHeight, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get()); - this.shader.setUniform(this.uHeightBasedOnCamera, heightFogCameraDirection.basedOnCamera); - this.shader.setUniform(this.uHeightFogAppliesUp, heightFogCameraDirection.fogAppliesUp); - this.shader.setUniform(this.uHeightFogAppliesDown, heightFogCameraDirection.fogAppliesDown); - this.shader.setUniform(this.uUseSphericalFog, useSphericalFog); - this.shader.setUniform(this.uHeightFogMixingMode, heightFogMixingMode.value); - this.shader.setUniform(this.uCameraBlockYPos, (float)MC_RENDER.getCameraExactPosition().y); - - } - private Color getFogColor(float partialTicks) - { - Color fogColor; - - if (Config.Client.Advanced.Graphics.Fog.colorMode.get() == EDhApiFogColorMode.USE_SKY_COLOR) - { - fogColor = MC_RENDER.getSkyColor(); - } - else - { - fogColor = MC_RENDER.getFogColor(partialTicks); - } - - return fogColor; - } - - public void setProjectionMatrix(Mat4f modelViewProjectionMatrix) - { - this.inverseMvmProjMatrix = new Mat4f(modelViewProjectionMatrix); - this.inverseMvmProjMatrix.invert(); - } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer); - GLMC.disableScissorTest(); - GLMC.disableDepthTest(); - GLMC.disableBlend(); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - GL32.glUniform1i(this.uDepthMap, 0); - - // this is necessary for MC 1.16 (IE Legacy OpenGL) - // otherwise the framebuffer isn't cleared correctly and the fog smears across the screen - if (MC_RENDER.runningLegacyOpenGL()) - { - // in another part of the DH code we set the fog color to opaque, here it needs to be transparent - float[] clearColorValues = new float[4]; - GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues); - GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 0.0f); - - GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT); - } - - - ScreenQuad.INSTANCE.render(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java deleted file mode 100644 index 77da0c811..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOApplyShader.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL32; - -/** - * Draws the SSAO texture onto DH's FrameBuffer.

- * - * See Also:
- * {@link SSAORenderer} - Parent to this shader.
- * {@link SSAOShader} - draws the SSAO texture.
- */ -public class SSAOApplyShader extends AbstractShaderRenderer -{ - public static SSAOApplyShader INSTANCE = new SSAOApplyShader(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int ssaoTexture; - - // uniforms - public int gSSAOMapUniform; - public int gDepthMapUniform; - public int gViewSizeUniform; - public int gBlurRadiusUniform; - public int gNearUniform; - public int gFarUniform; - - - - //=============// - // constructor // - //=============// - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/ssao/apply.frag", - "vPosition" - ); - - // uniform setup - this.gSSAOMapUniform = this.shader.getUniformLocation("gSSAOMap"); - this.gDepthMapUniform = this.shader.getUniformLocation("gDepthMap"); - this.gViewSizeUniform = this.shader.tryGetUniformLocation("gViewSize"); - this.gBlurRadiusUniform = this.shader.tryGetUniformLocation("gBlurRadius"); - this.gNearUniform = this.shader.tryGetUniformLocation("gNear"); - this.gFarUniform = this.shader.tryGetUniformLocation("gFar"); - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - GL32.glUniform1i(this.gDepthMapUniform, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(this.ssaoTexture); - GL32.glUniform1i(this.gSSAOMapUniform, 1); - - GL32.glUniform1i(this.gBlurRadiusUniform, 2); - - if (this.gViewSizeUniform >= 0) - { - GL32.glUniform2f(this.gViewSizeUniform, - MC_RENDER.getTargetFramebufferViewportWidth(), - MC_RENDER.getTargetFramebufferViewportHeight()); - } - - if (this.gNearUniform >= 0) - { - GL32.glUniform1f(this.gNearUniform, - RenderUtil.getNearClipPlaneInBlocks()); - } - - if (this.gFarUniform >= 0) - { - float farClipPlane = RenderUtil.getFarClipPlaneDistanceInBlocks(); - GL32.glUniform1f(this.gFarUniform, farClipPlane); - } - } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - GLMC.enableBlend(); - GL32.glBlendEquation(GL32.GL_FUNC_ADD); - GLMC.glBlendFuncSeparate(GL32.GL_ZERO, GL32.GL_SRC_ALPHA, GL32.GL_ZERO, GL32.GL_ONE); - - // Depth testing must be disabled otherwise this application shader won't apply anything. - // setting this isn't necessary in vanilla, but some mods may change this, requiring it to be set manually, - // it should be automatically restored after rendering is complete. - GLMC.disableDepthTest(); - - // apply the rendered SSAO to the LODs - GLMC.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, SSAOShader.INSTANCE.frameBuffer); - GLMC.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, BlazeLodRenderer.INSTANCE.getActiveFramebufferId()); - - - ScreenQuad.INSTANCE.render(); - - } -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java deleted file mode 100644 index 3026b4968..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/SSAOShader.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.SSAORenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import org.lwjgl.opengl.GL32; - -/** - * Draws the SSAO to a texture.

- * - * See Also:
- * {@link SSAORenderer} - Parent to this shader.
- * {@link SSAOApplyShader} - draws the SSAO texture to DH's FrameBuffer.
- */ -public class SSAOShader extends AbstractShaderRenderer -{ - public static SSAOShader INSTANCE = new SSAOShader(); - - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int frameBuffer; - - private Mat4f projection; - private Mat4f invertedProjection; - - - // uniforms - public int uProj; - public int uInvProj; - public int uSampleCount; - public int uRadius; - public int uStrength; - public int uMinLight; - public int uBias; - public int uDepthMap; - public int uFadeDistanceInBlocks; - - - - //=============// - // constructor // - //=============// - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/ssao/ao.frag", - "vPosition" - ); - - // uniform setup - this.uProj = this.shader.getUniformLocation("uProj"); - this.uInvProj = this.shader.getUniformLocation("uInvProj"); - this.uSampleCount = this.shader.getUniformLocation("uSampleCount"); - this.uRadius = this.shader.getUniformLocation("uRadius"); - this.uStrength = this.shader.getUniformLocation("uStrength"); - this.uMinLight = this.shader.getUniformLocation("uMinLight"); - this.uBias = this.shader.getUniformLocation("uBias"); - this.uDepthMap = this.shader.getUniformLocation("uDepthMap"); - this.uFadeDistanceInBlocks = this.shader.getUniformLocation("uFadeDistanceInBlocks"); - } - - - - //=============// - // render prep // - //=============// - - public void setProjectionMatrix(Mat4f projectionMatrix) - { - this.projection = projectionMatrix; - - this.invertedProjection = new Mat4f(projectionMatrix); - this.invertedProjection.invert(); - } - - @Override - protected void onApplyUniforms(float partialTicks) - { - this.shader.setUniform(this.uProj, this.projection); - - this.shader.setUniform(this.uInvProj, this.invertedProjection); - - this.shader.setUniform(this.uSampleCount, 6); - this.shader.setUniform(this.uRadius, 4.0f); - this.shader.setUniform(this.uStrength, 0.2f); - this.shader.setUniform(this.uMinLight, 0.25f); - this.shader.setUniform(this.uBias, 0.02f); - this.shader.setUniform(this.uFadeDistanceInBlocks, 1_600.0f); - - GL32.glUniform1i(this.uDepthMap, 0); - - } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer); - GLMC.disableScissorTest(); - GLMC.disableDepthTest(); - GLMC.disableBlend(); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(BlazeLodRenderer.INSTANCE.getActiveDepthTextureId()); - - ScreenQuad.INSTANCE.render(); - } -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java deleted file mode 100644 index 843a4218a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/shaders/VanillaFadeShader.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.renderer.shaders; - -import com.seibel.distanthorizons.core.config.Config; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.ScreenQuad; -import com.seibel.distanthorizons.core.util.RenderUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftGLWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import org.lwjgl.opengl.GL32; - -public class VanillaFadeShader extends AbstractShaderRenderer -{ - public static VanillaFadeShader INSTANCE = new VanillaFadeShader(); - - private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final IMinecraftGLWrapper GLMC = SingletonInjector.INSTANCE.get(IMinecraftGLWrapper.class); - - - public int frameBuffer = -1; - - private Mat4f inverseMcMvmProjMatrix; - private Mat4f inverseDhMvmProjMatrix; - private float levelMaxHeight; - - - // Uniforms - public int uMcDepthTexture = -1; - public int uDhDepthTexture = -1; - public int uCombinedMcDhColorTexture = -1; - public int uDhColorTexture = -1; - - /** Inverted Model View Projection matrix */ - public int uDhInvMvmProj = -1; - public int uMcInvMvmProj = -1; - - public int uStartFadeBlockDistance = -1; - public int uEndFadeBlockDistance = -1; - public int uMaxLevelHeight = -1; - - public int uOnlyRenderLods = -1; - - - - //=============// - // constructor // - //=============// - - public VanillaFadeShader() { } - - @Override - public void onInit() - { - this.shader = new ShaderProgram( - "shaders/quadApply.vert", - "shaders/fade/vanillaFade.frag", - "vPosition" - ); - - // all uniforms should be tryGet... - // because disabling fade can cause the GLSL to optimize out most (if not all) uniforms - - // near fade - this.uDhInvMvmProj = this.shader.tryGetUniformLocation("uDhInvMvmProj"); - this.uMcInvMvmProj = this.shader.tryGetUniformLocation("uMcInvMvmProj"); - - this.uMcDepthTexture = this.shader.tryGetUniformLocation("uMcDepthTexture"); - this.uDhDepthTexture = this.shader.tryGetUniformLocation("uDhDepthTexture"); - this.uCombinedMcDhColorTexture = this.shader.tryGetUniformLocation("uCombinedMcDhColorTexture"); - this.uDhColorTexture = this.shader.tryGetUniformLocation("uDhColorTexture"); - - this.uStartFadeBlockDistance = this.shader.tryGetUniformLocation("uStartFadeBlockDistance"); - this.uEndFadeBlockDistance = this.shader.tryGetUniformLocation("uEndFadeBlockDistance"); - this.uMaxLevelHeight = this.shader.tryGetUniformLocation("uMaxLevelHeight"); - - this.uOnlyRenderLods = this.shader.tryGetUniformLocation("uOnlyRenderLods"); - - } - - - - //=============// - // render prep // - //=============// - - @Override - protected void onApplyUniforms(float partialTicks) - { - this.shader.setUniform(this.uMcInvMvmProj, this.inverseMcMvmProjMatrix); - this.shader.setUniform(this.uDhInvMvmProj, this.inverseDhMvmProjMatrix); - - - float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks(); - // this added value prevents the near clip plane and discard circle from touching, which looks bad - dhNearClipDistance += 16f; - - // measured in blocks - // these multipliers in James' tests should provide a fairly smooth transition - // without having underdraw issues - float fadeStartDistance = dhNearClipDistance * 1.5f; - float fadeEndDistance = dhNearClipDistance * 1.9f; - - this.shader.setUniform(this.uStartFadeBlockDistance, fadeStartDistance); - this.shader.setUniform(this.uEndFadeBlockDistance, fadeEndDistance); - - this.shader.setUniform(this.uMaxLevelHeight, this.levelMaxHeight); - - this.shader.setUniform(this.uOnlyRenderLods, Config.Client.Advanced.Debugging.lodOnlyMode.get()); - } - - public void setProjectionMatrix(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix) - { - Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(mcProjectionMatrix); - inverseMcModelViewProjectionMatrix.multiply(mcModelViewMatrix); - inverseMcModelViewProjectionMatrix.invert(); - this.inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix; - - - Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix); - Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix); - - Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix); - inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix); - inverseDhModelViewProjectionMatrix.invert(); - this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix; - } - public void setLevelMaxHeight(int levelMaxHeight) { this.levelMaxHeight = levelMaxHeight; } - - - - //========// - // render // - //========// - - @Override - protected void onRender() - { - int depthTextureId = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); - int colorTextureId = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); - - if (depthTextureId == -1 - || colorTextureId == -1) - { - // the renderer is currently being re-built and/or inactive, - // we don't need to/can't render fading - return; - } - - - - GLMC.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.frameBuffer); - GLMC.disableScissorTest(); - GLMC.disableDepthTest(); - GLMC.disableBlend(); - - GLMC.glActiveTexture(GL32.GL_TEXTURE0); - GLMC.glBindTexture(MC_RENDER.getDepthTextureId()); - GL32.glUniform1i(this.uMcDepthTexture, 0); - - GLMC.glActiveTexture(GL32.GL_TEXTURE1); - GLMC.glBindTexture(depthTextureId); - GL32.glUniform1i(this.uDhDepthTexture, 1); - - GLMC.glActiveTexture(GL32.GL_TEXTURE2); - GLMC.glBindTexture(MC_RENDER.getColorTextureId()); - GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2); - - GLMC.glActiveTexture(GL32.GL_TEXTURE3); - GLMC.glBindTexture(colorTextureId); - GL32.glUniform1i(this.uDhColorTexture, 3); - - - ScreenQuad.INSTANCE.render(); - } - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormat.java b/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormat.java deleted file mode 100644 index 919ac68d9..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormat.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.vertexFormat; - -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; - -import it.unimi.dsi.fastutil.ints.IntArrayList; -import it.unimi.dsi.fastutil.ints.IntList; - -/** - * This is used to represent a single vertex - * stored in GPU memory, - *

- * A (almost) exact copy of Minecraft's - * VertexFormat class, several methods - * were commented out since we didn't need them. - * - * @author James Seibel - * @version 12-9-2021 - */ -public class LodVertexFormat -{ - private final ImmutableList elements; - private final IntList offsets = new IntArrayList(); - private final int byteSize; - - public LodVertexFormat(ImmutableList elementList) - { - this.elements = elementList; - int i = 0; - - for (LodVertexFormatElement LodVertexFormatElement : elementList) - { - this.offsets.add(i); - i += LodVertexFormatElement.getByteSize(); - } - - this.byteSize = i; - } - - public int getByteSize() - { - return this.byteSize; - } - - public ImmutableList getElements() - { - return this.elements; - } - - - // Forge added method - public int getOffset(int index) - { - return offsets.getInt(index); - } - - - - @Override - public String toString() - { - return "format: " + this.elements.size() + " elements: " + this.elements.stream().map(Object::toString).collect(Collectors.joining(" ")); - } - - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - else if (obj != null && this.getClass() == obj.getClass()) - { - LodVertexFormat vertexFormat = (LodVertexFormat) obj; - return this.byteSize == vertexFormat.byteSize && this.elements.equals(vertexFormat.elements); - } - else - { - return false; - } - } - - @Override - public int hashCode() - { - return this.elements.hashCode(); - } - - - - - - - - /* not currently needed setupBufferState() - public void setupBufferState(long p_227892_1_) - { - if (!RenderSystem.isOnRenderThread()) - { - RenderSystem.recordRenderCall(() -> - { - this.setupBufferState(p_227892_1_); - }); - } - else - { - int i = this.getVertexSize(); - List list = this.getElements(); - - for (int j = 0; j < list.size(); ++j) - { - list.get(j).setupBufferState(p_227892_1_ + this.offsets.getInt(j), i); - } - - } - } - */ - - /* not currently needed clearBufferState() - public void clearBufferState() - { - if (!RenderSystem.isOnRenderThread()) - { - RenderSystem.recordRenderCall(this::clearBufferState); - } - else - { - for (LodVertexFormatElement LodVertexFormatElement : this.getElements()) - { - LodVertexFormatElement.clearBufferState(); - } - - } - } - */ - - - /* not currently needed has-Position/Normal/Color/UV - public boolean hasPosition() - { - return elements.stream().anyMatch(e -> e.getUsage() == LodVertexFormatElement.Usage.POSITION); - } - - public boolean hasNormal() - { - return elements.stream().anyMatch(e -> e.getUsage() == LodVertexFormatElement.Usage.NORMAL); - } - - public boolean hasColor() - { - return elements.stream().anyMatch(e -> e.getUsage() == LodVertexFormatElement.Usage.COLOR); - } - - public boolean hasUV(int which) - { - return elements.stream().anyMatch(e -> e.getUsage() == LodVertexFormatElement.Usage.UV && e.getIndex() == which); - } - */ - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java b/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java deleted file mode 100644 index 16d843f7a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/LodVertexFormatElement.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.vertexFormat; - -import org.lwjgl.opengl.GL32; - -/** - * This object is used to build LodVertexFormats. - *

- * A (almost) exact copy of Minecraft's - * VertexFormatElement class.
- * A number of things were removed from the original - * object since we didn't need them, specifically "usage". - * - * @author James Seibel - * @version 11-13-2021 - */ -public class LodVertexFormatElement -{ - private final LodVertexFormatElement.DataType dataType; - /** James isn't sure what index is for */ - private final int index; - private final int count; - private final int byteSize; - private final boolean isPadding; - - public LodVertexFormatElement(int newIndex, LodVertexFormatElement.DataType newType, int newCount, boolean isPadding) - { - this.dataType = newType; - this.index = newIndex; - this.count = newCount; - this.byteSize = newType.getSize() * this.count; - this.isPadding = isPadding; - } - - public final boolean getIsPadding() - { - return isPadding; - } - - public final LodVertexFormatElement.DataType getType() - { - return this.dataType; - } - - public final int getIndex() - { - return this.index; - } - - public final int getByteSize() - { - return this.byteSize; - } - - // added by Forge - public int getElementCount() - { - return count; - } - - - - public enum DataType - { - FLOAT(4, "Float", GL32.GL_FLOAT), - UBYTE(1, "Unsigned Byte", GL32.GL_UNSIGNED_BYTE), - BYTE(1, "Byte", GL32.GL_BYTE), - USHORT(2, "Unsigned Short", GL32.GL_UNSIGNED_SHORT), - SHORT(2, "Short", GL32.GL_SHORT), - UINT(4, "Unsigned Int", GL32.GL_UNSIGNED_INT), - INT(4, "Int", GL32.GL_INT); - - private final int size; - private final String name; - private final int glType; - - DataType(int sizeInBytes, String newName, int openGlDataType) - { - this.size = sizeInBytes; - this.name = newName; - this.glType = openGlDataType; - } - - public int getSize() - { - return this.size; - } - - public String getName() - { - return this.name; - } - - public int getGlType() - { - return this.glType; - } - } - - - - - @Override - public int hashCode() - { - int i = this.dataType.hashCode(); - i = 31 * i + this.index; - return 31 * i + this.count; - } - - @Override - public String toString() - { - return this.count + "," + this.dataType.getName(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - else if (obj != null && this.getClass() == obj.getClass()) - { - LodVertexFormatElement LodVertexFormatElement = (LodVertexFormatElement) obj; - if (this.count != LodVertexFormatElement.count) - { - return false; - } - else if (this.index != LodVertexFormatElement.index) - { - return false; - } - else if (this.dataType != LodVertexFormatElement.dataType) - { - return false; - } - else - { - return false; - } - } - else - { - return false; - } - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/VertexFormats.java b/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/VertexFormats.java deleted file mode 100644 index 8d6850734..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/vertexFormat/VertexFormats.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.render.vertexFormat; - -import com.google.common.collect.ImmutableList; - -/** - * A (almost) exact copy of MC's - * DefaultVertexFormats class. - */ -public class VertexFormats -{ - public static final LodVertexFormatElement ELEMENT_POSITION = new LodVertexFormatElement(3, LodVertexFormatElement.DataType.USHORT, 3, false); - public static final LodVertexFormatElement ELEMENT_COLOR = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.UBYTE, 4, false); - public static final LodVertexFormatElement ELEMENT_BYTE_PADDING = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, true); - - public static final LodVertexFormatElement ELEMENT_LIGHT = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.UBYTE, 1, false); - public static final LodVertexFormatElement ELEMENT_IRIS_MATERIAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false); - public static final LodVertexFormatElement ELEMENT_IRIS_NORMAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false); - - - public static final LodVertexFormat POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX = new LodVertexFormat(ImmutableList.builder() - .add(ELEMENT_POSITION) - .add(ELEMENT_BYTE_PADDING) - .add(ELEMENT_LIGHT) - .add(ELEMENT_COLOR) - .add(ELEMENT_IRIS_MATERIAL_INDEX) - .add(ELEMENT_IRIS_NORMAL_INDEX) - .add(ELEMENT_BYTE_PADDING) - .add(ELEMENT_BYTE_PADDING) // padding is to make sure the format is a multiple of 4 - .build()); - -} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftGLWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftGLWrapper.java deleted file mode 100644 index f4201e4f8..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftGLWrapper.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 Lesser General 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 License for more details. - * - * You should have received a copy of the GNU Lesser General License - * along with this program. If not, see . - */ - -package com.seibel.distanthorizons.core.wrapperInterfaces.minecraft; - -import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -import org.lwjgl.opengl.GL32; - -import java.util.ArrayList; -import java.util.UUID; - -/** - * Used to sync GL state changes between DH and MC. - * This is specifically important for other mods that change MC's rendering like Iris. - */ -public interface IMinecraftGLWrapper extends IBindable -{ - - // scissor // - - /** @see GL32#GL_SCISSOR_TEST */ - void enableScissorTest(); - /** @see GL32#GL_SCISSOR_TEST */ - void disableScissorTest(); - - - // stencil // - - ///** @see GL32#GL_SCISSOR_TEST */ - //void enableScissorTest() { GlStateManager._enableScissorTest(); } - ///** @see GL32#GL_SCISSOR_TEST */ - //void disableScissorTest() { GlStateManager._disableScissorTest(); } - - - // depth // - - /** @see GL32#GL_DEPTH_TEST */ - void enableDepthTest(); - /** @see GL32#GL_DEPTH_TEST */ - void disableDepthTest(); - - /** @see GL32#glDepthFunc(int) */ - void glDepthFunc(int func); - - /** @see GL32#glDepthMask(boolean) */ - void enableDepthMask(); - /** @see GL32#glDepthMask(boolean) */ - void disableDepthMask(); - - - - // blending // - - /** @see GL32#GL_BLEND */ - void enableBlend(); - /** @see GL32#GL_BLEND */ - void disableBlend(); - - /** @see GL32#glBlendFunc */ - void glBlendFunc(int sfactor, int dfactor); - /** @see GL32#glBlendFuncSeparate */ - void glBlendFuncSeparate(int sfactorRGB, int dfactorRGB, int sfactorAlpha, int dfactorAlpha); - - - // frame buffers // - - /** @see GL32#glBindFramebuffer */ - void glBindFramebuffer(int target, int framebuffer); - - - // buffers // - - /** @see GL32#glGenBuffers() */ - int glGenBuffers(); - - /** @see GL32#glDeleteBuffers(int) */ - void glDeleteBuffers(int buffer); - - - - // culling // - - /** @see GL32#GL_CULL_FACE */ - void enableFaceCulling(); - /** @see GL32#GL_CULL_FACE */ - void disableFaceCulling(); - - - // textures // - - /** @see GL32#glGenTextures() */ - int glGenTextures(); - /** @see GL32#glDeleteTextures(int) */ - void glDeleteTextures(int texture); - - /** @see GL32#glActiveTexture(int) */ - void glActiveTexture(int textureId); - /** - * Only works for textures bound via this system.
- * Returns the bound {@link GL32#GL_TEXTURE_BINDING_2D} - */ - int getActiveTexture(); - - /** - * Always binds to {@link GL32#GL_TEXTURE_2D} - * @see GL32#glBindTexture(int, int) - */ - void glBindTexture(int texture); - -} From c84dbfceaf1ced1699295fc7f744d73430b3fc7f Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 16:26:48 -0500 Subject: [PATCH 27/46] update some imports --- .../seibel/distanthorizons/core/Initializer.java | 2 -- .../core/file/fullDatafile/V2/DataMigratorV1.java | 10 ++-------- .../fullDatafile/V2/FullDataSourceProviderV2.java | 9 +++++---- .../V2/FullDataUpdatePropagatorV2.java | 6 +++--- .../file/fullDatafile/V2/FullDataUpdaterV2.java | 14 ++++++-------- .../core/level/AbstractDhLevel.java | 3 +-- .../core/level/ClientLevelModule.java | 5 ++--- .../distanthorizons/core/level/DhClientLevel.java | 3 --- .../core/level/DhClientServerLevel.java | 5 ----- .../distanthorizons/core/level/DhServerLevel.java | 2 -- .../distanthorizons/core/level/IDhLevel.java | 1 - .../distanthorizons/core/logging/f3/F3Screen.java | 2 -- .../AbstractFullDataNetworkRequestQueue.java | 1 - .../core/render/QuadTree/LodRenderSection.java | 4 +--- .../core/render/RenderBufferHandler.java | 3 ++- .../seibel/distanthorizons/core/util/LodUtil.java | 2 -- .../core/wrapperInterfaces/IWrapperFactory.java | 2 +- .../minecraft/IMinecraftClientWrapper.java | 8 -------- .../wrapperInterfaces/misc/ILightMapWrapper.java | 7 ------- .../render/IMcFarFadeRenderer.java | 4 +--- .../render/IMcGenericRenderer.java | 3 +-- 21 files changed, 25 insertions(+), 71 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java b/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java index d4f358aab..50cf8d2aa 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java @@ -27,7 +27,6 @@ import com.seibel.distanthorizons.core.config.eventHandlers.IgnoredDimensionCsvH import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.MinecraftTextFormat; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericRenderObjectFactory; import com.seibel.distanthorizons.core.sql.DatabaseUpdater; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.world.DhApiWorldProxy; @@ -36,7 +35,6 @@ import com.seibel.distanthorizons.core.api.external.methods.data.DhApiTerrainDat import com.seibel.distanthorizons.api.DhApi; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.coreapi.util.StringUtil; import net.jpountz.lz4.LZ4FrameOutputStream; import com.seibel.distanthorizons.core.logging.DhLogger; import org.sqlite.SQLiteJDBCLoader; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java index 000ddbb2c..344e7d91b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java @@ -9,9 +9,9 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import java.io.File; import java.io.IOException; @@ -22,7 +22,7 @@ import java.util.List; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; -public class DataMigratorV1 implements IDebugRenderable, AutoCloseable +public class DataMigratorV1 implements AutoCloseable { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); @@ -332,12 +332,6 @@ public class DataMigratorV1 implements IDebugRenderable, AutoCloseable // overrides // //===========// - @Override - public void debugRender(DebugRenderer renderer) - { - // nothing currently needed - } - @Override public void close() { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java index 278cf6fe0..3dd6fd4be 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.file.fullDatafile.V2; import com.seibel.distanthorizons.api.enums.config.EDhApiDataCompressionMode; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.file.fullDatafile.IDataSourceUpdateListenerFunc; import com.seibel.distanthorizons.core.file.structure.ISaveStructure; @@ -30,7 +31,6 @@ import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo; @@ -38,6 +38,7 @@ import com.seibel.distanthorizons.core.sql.repo.FullDataSourceV2Repo; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import it.unimi.dsi.fastutil.longs.LongArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -108,7 +109,8 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable this.updatePropagator = new FullDataUpdatePropagatorV2(this, this.dataUpdater, this.levelId); this.dataMigratorV1 = new DataMigratorV1(this.dataUpdater, this.level, this.levelId, this.saveDir); - DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus); + IMcDebugRenderer debugRenderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); + debugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus); } @@ -447,11 +449,10 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable //===========// @Override - public void debugRender(DebugRenderer renderer) + public void debugRender(IMcDebugRenderer renderer) { this.dataUpdater.debugRender(renderer); this.updatePropagator.debugRender(renderer); - this.dataMigratorV1.debugRender(renderer); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java index b57350515..9aa7c6448 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java @@ -7,12 +7,12 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import it.unimi.dsi.fastutil.longs.LongArrayList; import java.awt.*; @@ -388,10 +388,10 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab //region @Override - public void debugRender(DebugRenderer renderer) + public void debugRender(IMcDebugRenderer renderer) { this.updatingPosSet - .forEach((pos) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); + .forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java index 4a41b3167..81941efdb 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java @@ -7,11 +7,11 @@ import com.seibel.distanthorizons.core.file.fullDatafile.IDataSourceUpdateListen import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.threading.PositionalLockProvider; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -225,20 +225,18 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable //===========// @Override - public void debugRender(DebugRenderer renderer) + public void debugRender(IMcDebugRenderer renderer) { this.lockedPosSet - .forEach((pos) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); + .forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); this.queuedUpdateCountsByPos - .forEach((pos, updateCountRef) -> { renderer.renderBox(new DebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); + .forEach((pos, updateCountRef) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); } @Override - public void close() - { - this.isShutdownRef.set(true); - } + public void close() { this.isShutdownRef.set(true); } + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java index b1b786924..fd6c817f2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.level; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkModifiedEvent; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; +import com.seibel.distanthorizons.core.render.renderer.CloudRenderHandler; import com.seibel.distanthorizons.core.util.delayedSaveCache.DelayedBeaconSaveCache; import com.seibel.distanthorizons.core.util.delayedSaveCache.DelayedDataSourceSaveCache; import com.seibel.distanthorizons.core.generation.DhLightingEngine; @@ -29,8 +30,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; -import com.seibel.distanthorizons.core.render.renderer.generic.CloudRenderHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; import com.seibel.distanthorizons.core.sql.dto.ChunkHashDTO; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java index 1b58f5902..65ee554c0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java @@ -28,7 +28,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -54,9 +53,9 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu public final AtomicReference ClientRenderStateRef = new AtomicReference<>(); /** * This is handled outside of the {@link ClientRenderState} to prevent destroying - * the {@link GenericObjectRenderer} when changing render distances or enabling/disabling rendering.

+ * the {@link IMcGenericRenderer} when changing render distances or enabling/disabling rendering.

* - * Destroying the {@link GenericObjectRenderer} would cause any existing bindings to be + * Destroying the {@link IMcGenericRenderer} would cause any existing bindings to be * erroneously removed. */ public final IMcGenericRenderer genericRenderer = WRAPPER_FACTORY.createGenericRenderer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java index 3acc1a7b0..c6e22e3a4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java @@ -36,9 +36,7 @@ import com.seibel.distanthorizons.core.network.event.ScopedNetworkEventSource; import com.seibel.distanthorizons.core.network.messages.fullData.FullDataPartialUpdateMessage; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -49,7 +47,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.annotation.CheckForNull; -import java.awt.*; import java.io.File; import java.io.IOException; import java.sql.SQLException; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java index d692ffee9..ce1c1541c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java @@ -19,22 +19,17 @@ package com.seibel.distanthorizons.core.level; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.MinecraftTextFormat; import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManager; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.jetbrains.annotations.Nullable; -import java.awt.*; import java.io.IOException; import java.sql.SQLException; import java.util.List; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java index a4ef3c7c1..0f6a833d6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java @@ -23,10 +23,8 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManager; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; -import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.sql.SQLException; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java index b687537ec..702269eae 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java @@ -27,7 +27,6 @@ import com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataSource import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java index a66f3a4d6..84a538ccd 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java @@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.util.objects.pooling.PhantomArrayListPool; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; @@ -43,7 +42,6 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import java.text.NumberFormat; import java.util.*; -import java.util.concurrent.ThreadPoolExecutor; public class F3Screen { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java index 2e24f586e..eaedb4abb 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java @@ -18,7 +18,6 @@ import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceR import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceResponseMessage; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.LodUtil; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java index b24d8b2d6..0c88cb5bf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java @@ -33,11 +33,9 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; +import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; -import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler; import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo; import com.seibel.distanthorizons.core.util.LodUtil; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index a1ef966ac..1206c9e4b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -34,7 +34,8 @@ import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection; import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.DhFrustumBounds; +import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.NeverCullFrustum; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java index e24634518..db0807842 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java @@ -20,8 +20,6 @@ package com.seibel.distanthorizons.core.util; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.render.vertexFormat.VertexFormats; -import com.seibel.distanthorizons.core.render.vertexFormat.LodVertexFormat; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.logging.DhLogger; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index 6cf1f48c0..376e99487 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -21,9 +21,9 @@ package com.seibel.distanthorizons.core.wrapperInterfaces; import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.render.renderer.generic.IGenericObjectVertexBufferContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IGenericObjectVertexBufferContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java index 6df688cf8..092b98d5d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/minecraft/IMinecraftClientWrapper.java @@ -19,18 +19,10 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.minecraft; -import java.util.ArrayList; -import java.util.UUID; - -import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.pos.DhChunkPos; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; -import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; -import org.apache.logging.log4j.Level; public interface IMinecraftClientWrapper extends IBindable { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java index a029bf1a9..b270d1b0e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java @@ -20,7 +20,6 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.misc; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -import org.lwjgl.opengl.GL32; /** * @author James Seibel @@ -28,12 +27,6 @@ import org.lwjgl.opengl.GL32; */ public interface ILightMapWrapper extends IBindable { - /** - * which texture index IE 0,1,2... the lightmap will be bound to.
- * Related to but different from {@link GL32#GL_TEXTURE0}. - */ - int BOUND_INDEX = 0; - void bind(); void unbind(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java index 07d6e120a..c3e6fa0ee 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java @@ -19,9 +19,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IMcFarFadeRenderer extends IBindable diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java index 8edbe9f73..a38b2ac42 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java @@ -20,8 +20,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; From 82c832a4af4fdc88454d6924c2e1a1dc33cf33a3 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 16:30:45 -0500 Subject: [PATCH 28/46] Add RenderThreadTaskHandler --- .../core/api/internal/ClientApi.java | 8 +- .../api/internal/ClientPluginChannelApi.java | 4 +- .../core/config/gui/EmbeddedFrameUtil.java | 196 ------------------ .../render/QuadTree/LodRenderSection.java | 7 - .../core/render/RenderThreadTaskHandler.java | 144 +++++++++++++ 5 files changed, 149 insertions(+), 210 deletions(-) delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/config/gui/EmbeddedFrameUtil.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 2a9eb17ad..132598e0a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -31,6 +31,8 @@ import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.network.messages.MessageRegistry; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; +import com.seibel.distanthorizons.core.render.RenderParams; +import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.render.renderer.*; import com.seibel.distanthorizons.core.util.TimerUtil; import com.seibel.distanthorizons.core.util.math.Vec3d; @@ -49,7 +51,6 @@ import com.seibel.distanthorizons.api.enums.rendering.EDhApiDebugRendering; import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.world.DhClientWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; @@ -464,11 +465,8 @@ public class ClientApi try { - // make sure the GLProxy is created for future use - GLProxy glProxy = GLProxy.getInstance(); - // these tasks always need to be called, regardless of whether the renderer is enabled or not to prevent memory leaks - glProxy.runRenderThreadTasks(); + RenderThreadTaskHandler.INSTANCE.runRenderThreadTasks(); } catch (Exception e) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java index afb1f05e8..90a3a356f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java @@ -9,7 +9,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.network.event.internal.CloseInternalEvent; import com.seibel.distanthorizons.core.network.messages.base.LevelInitMessage; import com.seibel.distanthorizons.core.network.session.NetworkSession; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; +import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import org.jetbrains.annotations.NotNull; @@ -90,7 +90,7 @@ public class ClientPluginChannelApi LOGGER.info("Server level key received: [" + msg.levelKey + "]."); - GLProxy.queueRunningOnRenderThread(() -> + RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() -> { IClientLevelWrapper clientLevel = MC.getWrappedClientLevel(true); IServerKeyedClientLevel existingKeyedClientLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/gui/EmbeddedFrameUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/config/gui/EmbeddedFrameUtil.java deleted file mode 100644 index 49bf35b04..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/gui/EmbeddedFrameUtil.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.config.gui; - -import com.seibel.distanthorizons.core.jar.EPlatform; -import org.jetbrains.annotations.NotNull; -import org.lwjgl.system.jawt.JAWT; -import org.lwjgl.system.macosx.*; - -import java.awt.*; -import java.lang.reflect.*; -import java.util.regex.*; - -import static org.lwjgl.glfw.GLFWNativeCocoa.*; -import static org.lwjgl.glfw.GLFWNativeWin32.*; -import static org.lwjgl.glfw.GLFWNativeX11.*; -import static org.lwjgl.system.JNI.*; -import static org.lwjgl.system.jawt.JAWTFunctions.*; -import static org.lwjgl.system.macosx.ObjCRuntime.*; - -// Some of the code is from https://github.com/LWJGL/lwjgl3/blob/master/modules/samples/src/test/java/org/lwjgl/demo/system/jawt/EmbeddedFrameUtil.java -// which is licensed under https://www.lwjgl.org/license - -/** - * Some utils for embedding awt and swing items into lwjgl windows - * - * @author Ran - * @author coolGi - */ -public final class EmbeddedFrameUtil -{ - - private static final int JAVA_VERSION; - - private static final JAWT awt; - - static - { - Pattern p = Pattern.compile("^(?:1[.])?([1-9][0-9]*)[.-]"); - Matcher m = p.matcher(System.getProperty("java.version")); - - if (!m.find()) - { - throw new IllegalStateException("Failed to parse java.version"); - } - - JAVA_VERSION = Integer.parseInt(m.group(1)); - - awt = JAWT.calloc(); - awt.version(JAVA_VERSION < 9 ? JAWT_VERSION_1_4 : JAWT_VERSION_9); - if (!JAWT_GetAWT(awt)) - { - throw new RuntimeException("GetAWT failed"); - } - } - - private static String getEmbeddedFrameImpl() - { - switch (EPlatform.get()) - { - case LINUX: - return "sun.awt.X11.XEmbeddedFrame"; - case WINDOWS: - return "sun.awt.windows.WEmbeddedFrame"; - case MACOS: - return "sun.lwawt.macosx.CViewEmbeddedFrame"; - default: - throw new IllegalStateException(); - } - } - - private static long getEmbeddedFrameHandle(long window) - { - switch (EPlatform.get()) - { - case LINUX: - return glfwGetX11Window(window); - case WINDOWS: - return glfwGetWin32Window(window); - case MACOS: - long objc_msgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend"); - return invokePPP(glfwGetCocoaWindow(window), sel_getUid("contentView"), objc_msgSend); - default: - throw new IllegalStateException(); - } - } - - public static Frame embeddedFrameCreate(long window) - { - if (JAVA_VERSION < 9) - { - try - { - @SuppressWarnings("unchecked") - Class EmdeddedFrame = (Class) Class.forName(getEmbeddedFrameImpl()); - Constructor c = EmdeddedFrame.getConstructor(long.class); - - return c.newInstance(getEmbeddedFrameHandle(window)); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - else - { - return nJAWT_CreateEmbeddedFrame(getEmbeddedFrameHandle(window), awt.CreateEmbeddedFrame()); - } - } - - static void embeddedFrameSynthesizeWindowActivation(Frame embeddedFrame, boolean doActivate) - { - if (JAVA_VERSION < 9) - { - try - { - embeddedFrame - .getClass() - .getMethod("synthesizeWindowActivation", boolean.class) - .invoke(embeddedFrame, doActivate); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - else - { - JAWT_SynthesizeWindowActivation(embeddedFrame, doActivate, awt.SynthesizeWindowActivation()); - } - } - - public static void embeddedFrameSetBounds(Frame embeddedFrame, int x, int y, int width, int height) - { - if (JAVA_VERSION < 9) - { - try - { - Method setLocationPrivate = embeddedFrame - .getClass() - .getSuperclass() - .getDeclaredMethod("setBoundsPrivate", int.class, int.class, int.class, int.class); - setLocationPrivate.setAccessible(true); - setLocationPrivate.invoke(embeddedFrame, x, y, width, height); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - else - { - JAWT_SetBounds(embeddedFrame, x, y, width, height, awt.SetBounds()); - } - } - - - public static void hideFrame(@NotNull Frame embeddedFrame) - { - embeddedFrame.setVisible(false); - embeddedFrameSynthesizeWindowActivation(embeddedFrame, false); - } - - public static void showFrame(@NotNull Frame embeddedFrame) - { - embeddedFrameSynthesizeWindowActivation(embeddedFrame, true); - embeddedFrame.setVisible(true); - } - public static void placeAtCenter(Frame embeddedFrame, int windowWidth, int windowHeight, int frameWidth, int frameHeight, float scale) - { - float scaleFactor = (100.0F - scale) / 100.0F; - float newWidth = frameWidth * scaleFactor; - float newHeight = frameHeight * scaleFactor; - float newX = (windowWidth - newWidth) / 2F; - float newY = (windowHeight - newHeight) / 2F; - embeddedFrameSetBounds(embeddedFrame, Math.round(newX), Math.round(newY), Math.round(newWidth), Math.round(newHeight)); - } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java index 0c88cb5bf..39f3c217e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java @@ -150,13 +150,6 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable /** @return true if the upload started, false if it wasn't able to for any reason */ public synchronized boolean uploadRenderDataToGpuAsync() { - if (!GLProxy.hasInstance()) - { - // it's possible to try uploading buffers before the GLProxy has been initialized - // which would cause the system to crash - return false; - } - if (this.getAndBuildRenderDataFutureRef.get() != null) { // don't accidentally queue multiple uploads at the same time diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java new file mode 100644 index 000000000..dc068a552 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java @@ -0,0 +1,144 @@ +package com.seibel.distanthorizons.core.render; + +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.logging.DhLogger; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.util.TimerUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; + +import java.util.Timer; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class RenderThreadTaskHandler +{ + public static final DhLogger LOGGER = new DhLoggerBuilder() + .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) + .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) + .build(); + + private static final ConcurrentLinkedQueue RENDER_THREAD_RUNNABLE_QUEUE = new ConcurrentLinkedQueue<>(); + + private static final Timer TIMER = TimerUtil.CreateTimer("Cleanup timer"); + private static final long MS_BETWEEN_CLEANUP_TICKS = 1_000L; + private static final long MS_BEFORE_RUN_CLEANUP_TIMER = 1_000L; + + + public static final RenderThreadTaskHandler INSTANCE = new RenderThreadTaskHandler(); + + + private long msSinceGlTasksRun = System.currentTimeMillis(); + + + + //=============// + // constructor // + //=============// + //region + + private RenderThreadTaskHandler() { TIMER.scheduleAtFixedRate(TimerUtil.createTimerTask(this::manualCleanupTick), MS_BETWEEN_CLEANUP_TICKS, MS_BETWEEN_CLEANUP_TICKS); } + + //endregion + + + + //==============// + // task queuing // + //==============// + //region + + public void queueRunningOnRenderThread(Runnable renderCall) + { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + RENDER_THREAD_RUNNABLE_QUEUE.add(() -> this.createRenderThreadRunnable(renderCall, stackTrace)); + } + private void createRenderThreadRunnable(Runnable renderCall, StackTraceElement[] stackTrace) + { + try + { + renderCall.run(); + } + catch (Exception e) + { + RuntimeException error = new RuntimeException("Uncaught Exception during GL call execution:", e); + error.setStackTrace(stackTrace); + LOGGER.error("[" + Thread.currentThread().getName() + "] ran into an unexpected error running a GL call, Error: ["+ e.getMessage() +"].", error); + } + } + + //endregion + + + + //===========// + // run tasks // + //===========// + //region + + /** + * Doesn't do any thread/GL Context validation. + * Running this outside of the render thread may cause crashes or other issues. + */ + public void runRenderThreadTasks() + { + IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + + int frameLimit = MC_RENDER.getFrameLimit(); + if (frameLimit <= 1) + { + frameLimit = 4; // 240 FPS + } + + // https://fpstoms.com/ + int msPerFrame = 1000 / frameLimit; + this.runRenderThreadTasks(msPerFrame); + } + private void runRenderThreadTasks(long msMaxRunTime) + { + long startTimeMs = System.currentTimeMillis(); + this.msSinceGlTasksRun = startTimeMs; + + Runnable runnable = RENDER_THREAD_RUNNABLE_QUEUE.poll(); + while(runnable != null) + { + runnable.run(); + + // only try running for 4ms (240 FPS) at a time to prevent random lag spikes + long currentTimeMs = System.currentTimeMillis(); + long runDuration = currentTimeMs - startTimeMs; + if (runDuration > msMaxRunTime) + { + break; + } + + runnable = RENDER_THREAD_RUNNABLE_QUEUE.poll(); + } + } + + /** + * Should only be called if our render code isn't being hit for some reason. + * Normally this only happens if there's a mod that limits MC's framerate to 0. + */ + private void manualCleanupTick() + { + long nowMs = System.currentTimeMillis(); + long msSinceLast = nowMs - this.msSinceGlTasksRun; + if (msSinceLast > MS_BEFORE_RUN_CLEANUP_TIMER) + { + return; + } + + // We haven't gotten a frame for a while, + // this means we could have GL jobs building up. + // Run the queued tasks on MC's executor (hopefully this should always run, + // even if DH's render code isn't being hit). + IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + MC.executeOnRenderThread(() -> this.runRenderThreadTasks(1_000)); + } + + //end region + + + +} From 67b2467beee770c7498c19a7eb89a5bc5276c999 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 16:34:25 -0500 Subject: [PATCH 29/46] change where vertex size is found --- .../java/com/seibel/distanthorizons/core/util/LodUtil.java | 4 ---- .../core/wrapperInterfaces/render/IMcLodRenderer.java | 7 ++++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java index db0807842..5554fc005 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/LodUtil.java @@ -106,10 +106,6 @@ public class LodUtil */ public static final int MAX_ALLOCATABLE_DIRECT_MEMORY = 64 * 1024 * 1024; - /** the format of data stored in the GPU buffers */ - @Deprecated - public static final LodVertexFormat DH_VERTEX_FORMAT = VertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX; - //=========// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java index 075c77e96..7b02a532c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java @@ -19,9 +19,8 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render; -import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; @@ -33,8 +32,10 @@ public interface IMcLodRenderer extends IBindable SortedArraySet bufferContainers, IProfilerWrapper profiler); - int getVertexSize(); + @Deprecated // TODO put somewhere else + int getVertexByteSize(); + // TODO should these go somewhere else? void applyToMcTexture(); void clearDepth(); void clearColor(); From 17cdb0f745063f3572b864aecd85b9155b31472d Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 16:35:17 -0500 Subject: [PATCH 30/46] re-add some core rendering handlers --- .../core/render/RenderParams.java | 221 +++++++ .../render/renderer/BeaconRenderHandler.java | 333 ++++++++++ .../render/renderer/CloudRenderHandler.java | 619 ++++++++++++++++++ .../cullingFrustum/DhFrustumBounds.java | 69 ++ .../cullingFrustum/NeverCullFrustum.java | 41 ++ 5 files changed, 1283 insertions(+) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/DhFrustumBounds.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/NeverCullFrustum.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java new file mode 100644 index 000000000..98ce8e75f --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java @@ -0,0 +1,221 @@ +package com.seibel.distanthorizons.core.render; + +import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.core.api.internal.SharedApi; +import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.jar.EPlatform; +import com.seibel.distanthorizons.core.level.IDhClientLevel; +import com.seibel.distanthorizons.core.util.RenderUtil; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.util.math.Vec3d; +import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; +import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.world.IDhClientWorld; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; + +/** + * An extension of {@link DhApiRenderParam} + * that allows additional validation and putting all + * rendering variables in a single place. + */ +public class RenderParams extends DhApiRenderParam +{ + private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + + private static final long TIME_FOR_MAC_TO_FINISH_COMPILING_IN_MS = 10_000; + private static boolean initialLoadingComplete = false; + + + public IDhClientWorld dhClientWorld; + public IDhClientLevel dhClientLevel; + /** more specific override of the API value {@link DhApiRenderParam#clientLevelWrapper} */ + public IClientLevelWrapper clientLevelWrapper; + public ILightMapWrapper lightmap; + public RenderBufferHandler renderBufferHandler; + public IMcGenericRenderer genericRenderer; + public Vec3d exactCameraPosition; + /** @see DhRenderState#vanillaFogEnabled */ + public boolean vanillaFogEnabled; + + public boolean validationRun = false; + + + + //=============// + // constructor // + //=============// + //region + + public RenderParams(EDhApiRenderPass renderPass, DhRenderState renderState) + { + this(renderPass, + renderState.partialTickTime, + renderState.mcProjectionMatrix, renderState.mcModelViewMatrix, + renderState.clientLevelWrapper, + renderState.vanillaFogEnabled + ); + } + private RenderParams( + EDhApiRenderPass renderPass, + float newPartialTicks, + Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix, + IClientLevelWrapper clientLevelWrapper, + boolean vanillaFogEnabled + ) + { + super(renderPass, + newPartialTicks, + RenderUtil.getNearClipPlaneInBlocks(), RenderUtil.getFarClipPlaneDistanceInBlocks(), + newMcProjectionMatrix, newMcModelViewMatrix, + RenderUtil.createLodProjectionMatrix(newMcProjectionMatrix), RenderUtil.createLodModelViewMatrix(newMcModelViewMatrix), + clientLevelWrapper.getMinHeight(), + clientLevelWrapper); + + + this.dhClientWorld = SharedApi.tryGetDhClientWorld(); + if (this.dhClientWorld != null) + { + this.dhClientLevel = (IDhClientLevel) this.dhClientWorld.getLevel(clientLevelWrapper); + if (this.dhClientLevel != null) + { + this.renderBufferHandler = this.dhClientLevel.getRenderBufferHandler(); + this.genericRenderer = this.dhClientLevel.getGenericRenderer(); + } + } + + this.clientLevelWrapper = clientLevelWrapper; + this.lightmap = MC_RENDER.getLightmapWrapper(this.clientLevelWrapper); + + if (MC_CLIENT.playerExists()) + { + this.exactCameraPosition = MC_RENDER.getCameraExactPosition(); + } + + this.vanillaFogEnabled = vanillaFogEnabled; + + } + + //endregion + + + + //======================// + // parameter validation // + //======================// + //region + + /** + * Should be called before rendering is done. + * @return a message if LODs shouldn't be rendered, null if the LODs can render + */ + public String getValidationErrorMessage(long firstRenderTimeMs) + { + // Note: all strings here should be constants to prevent String allocations + + this.validationRun = true; + + + if (!MC_CLIENT.playerExists()) + { + return "No Player Exists"; + } + + if (this.dhClientWorld == null) + { + return "No DH Client World Loaded"; + } + + if (this.dhClientLevel == null) + { + return "No DH Client Level Loaded"; + } + + if (this.clientLevelWrapper == null) + { + return "No Client Level Wrapper Loaded"; + } + + if (this.lightmap == null) + { + return "No Lightmap Loaded"; + } + + if (this.renderBufferHandler == null) + { + return "No RenderBufferHandler Present"; + } + + if (this.genericRenderer == null) + { + return "No Generic Renderer Present"; + } + + if (this.dhModelViewMatrix == null + || this.mcModelViewMatrix == null) + { + return "No MVM or Proj Matrix Given"; + } + + if (AbstractOptifineAccessor.optifinePresent() + && MC_RENDER.getTargetFramebuffer() == -1) + { + // wait for MC to finish setting up their renderer + return "Optifine Target Frame Buffer not set"; + } + + + // potential fix for a segfault when + // Sodium and DH are running together + if (EPlatform.get() == EPlatform.MACOS + && !initialLoadingComplete) + { + // Once MC starts rendering, wait a few seconds so + // MC/Sodium can finish their shader compiling before DH does its own. + // This will allow DH to compile its own shaders after Sodium finishes + // compiling its own. + long nowMs = System.currentTimeMillis(); + long firstAllowedRenderTimeMs = firstRenderTimeMs + TIME_FOR_MAC_TO_FINISH_COMPILING_IN_MS; + if (nowMs < firstAllowedRenderTimeMs) + { + return "Waiting for initial MC compile..."; + } + + + // null shouldn't happen, but just in case + PriorityTaskPicker.Executor renderLoadExecutor = ThreadPoolUtil.getRenderLoadingExecutor(); + if (renderLoadExecutor == null) + { + return "Waiting for DH Threadpool..."; + } + + // wait for DH to finish loading, by the time that's done + // java should have finished all of DH's JIT compiling, + // which will hopefully mean less concurrency and thus a lower + // chance of breaking + // (plus this gives Sodium/vanill a bit longer to finish their setup) + int taskCount = renderLoadExecutor.getQueueSize(); + if (taskCount > 0) + { + return "Waiting for DH JIT compiling..."; + } + + initialLoadingComplete = true; + } + + + return null; + } + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java new file mode 100644 index 000000000..aef4e9bd1 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java @@ -0,0 +1,333 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.render.renderer; + +import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; +import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; +import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.RenderUtil; +import com.seibel.distanthorizons.core.util.math.Vec3d; +import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.coreapi.ModInfo; +import com.seibel.distanthorizons.core.logging.DhLogger; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Predicate; + +public class BeaconRenderHandler +{ + private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + private static final IDhApiCustomRenderObjectFactory GENERIC_OBJECT_FACTORY = SingletonInjector.INSTANCE.get(IDhApiCustomRenderObjectFactory.class); + + /** how often should we check if a beacon should be culled? */ + private static final int MAX_CULLING_FREQUENCY_IN_MS = 1_000; + + private static final Comparator NEGATIVE_BLOCKPOS_COMPARATOR = new NegativeInfiniteBlockPosComparator(); + + + + private final ReentrantLock updateLock = new ReentrantLock(); + + /** only contains the beacons currently being rendered (culled beacons will be missing) */ + private final IDhApiRenderableBoxGroup activeBeaconBoxRenderGroup; + /** contains all beacons that could be rendered (including those that are being culled) */ + private final ArrayList fullBeaconBoxList = new ArrayList<>(); + /** contains all beacons that could be rendered */ + private final HashSet fullBeaconBlockPosSet = new HashSet<>(); + + private boolean cullingThreadRunning = false; + private boolean updateRenderDataNextFrame = false; + + + + //=============// + // constructor // + //=============// + //region + + public BeaconRenderHandler(@NotNull IMcGenericRenderer renderer) + { + this.activeBeaconBoxRenderGroup = GENERIC_OBJECT_FACTORY.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0)); + this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); + this.activeBeaconBoxRenderGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); + this.activeBeaconBoxRenderGroup.setSsaoEnabled(false); + this.activeBeaconBoxRenderGroup.setShading(DhApiRenderableBoxGroupShading.getUnshaded()); + this.activeBeaconBoxRenderGroup.setPreRenderFunc(this::beforeRender); + + renderer.add(this.activeBeaconBoxRenderGroup); + } + + //endregion + + + + //=================// + // render handling // + //=================// + //region + + public void startRenderingBeacons(ArrayList beaconList, byte detailLevel) + { + try + { + this.updateLock.lock(); + + + // how wide should each beacon be? + int beaconBlockWidth = 1; + if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get()) + { + beaconBlockWidth = DhSectionPos.getBlockWidth(detailLevel); + } + + + ArrayList sortedBeaconList = new ArrayList<>(beaconList); + + // merge distant beams if requested + if (Config.Client.Advanced.Graphics.GenericRendering.expandDistantBeacons.get()) + { + // sort beacons from neg inf -> pos inf + // so we can consistently merge adjacent beacons + sortedBeaconList.sort(NEGATIVE_BLOCKPOS_COMPARATOR); + + // go through each beacon... + for (int outerIndex = 0; outerIndex < sortedBeaconList.size(); outerIndex++) + { + BeaconBeamDTO outerBeacon = sortedBeaconList.get(outerIndex); + DhBlockPos outerBlockPos = outerBeacon.blockPos; + + // ...and remove any beacons that are within the block width to prevent overlaps + for (int mergeIndex = outerIndex + 1; mergeIndex < sortedBeaconList.size(); mergeIndex++) + { + BeaconBeamDTO beaconToMerge = sortedBeaconList.get(mergeIndex); + DhBlockPos mergeBlockPos = beaconToMerge.blockPos; + + int xDiff = mergeBlockPos.getX() - outerBlockPos.getX(); + int zDiff = mergeBlockPos.getZ() - outerBlockPos.getZ(); + + // merge (remove) this beacon if + // it's close to the outer beacon + if (xDiff < beaconBlockWidth + && zDiff < beaconBlockWidth) + { + sortedBeaconList.remove(mergeIndex); + mergeIndex--; // minus 1 so we don't go past the end of the array when incrementing in the for loop up top + } + } + } + } + + + //LOGGER.info("startRenderingBeacons ["+sortedBeaconList+"]"); + + // add each beacon to the renderer + for (int i = 0; i < sortedBeaconList.size(); i++) + { + BeaconBeamDTO beacon = sortedBeaconList.get(i); + if (!this.fullBeaconBlockPosSet.add(beacon.blockPos)) + { + // skip already present beacons + continue; + } + + + int maxBeaconBeamHeight = Config.Client.Advanced.Graphics.GenericRendering.beaconRenderHeight.get(); + DhApiRenderableBox beaconBox = new DhApiRenderableBox( + new DhApiVec3d(beacon.blockPos.getX(), beacon.blockPos.getY() + 1, beacon.blockPos.getZ()), + new DhApiVec3d(beacon.blockPos.getX() + beaconBlockWidth, maxBeaconBeamHeight, beacon.blockPos.getZ() + beaconBlockWidth), + beacon.color, + EDhApiBlockMaterial.ILLUMINATED + ); + + this.activeBeaconBoxRenderGroup.add(beaconBox); + this.fullBeaconBoxList.add(beaconBox); + this.activeBeaconBoxRenderGroup.triggerBoxChange(); + } + } + finally + { + this.updateLock.unlock(); + } + } + + public void stopRenderingBeaconsInRange(long pos) + { + try + { + this.updateLock.lock(); + + Predicate removeBoxPredicate = (DhApiRenderableBox box) -> + { + DhBlockPos blockPos = new DhBlockPos((int)box.minPos.x, (int)box.minPos.y, (int)box.minPos.z); + boolean contains = DhSectionPos.contains(pos, blockPos); + //if (contains) + //{ + // LOGGER.info("stopRenderingBeaconsInRange ["+DhSectionPos.toString(pos)+"] ["+blockPos+"]"); + //} + return contains; + }; + this.activeBeaconBoxRenderGroup.removeIf(removeBoxPredicate); + this.fullBeaconBoxList.removeIf(removeBoxPredicate); + + this.fullBeaconBlockPosSet.removeIf((DhBlockPos blockPos) -> DhSectionPos.contains(pos, blockPos)); + + this.activeBeaconBoxRenderGroup.triggerBoxChange(); + } + finally + { + this.updateLock.unlock(); + } + } + + + private void beforeRender(DhApiRenderParam renderEventParam) + { + if (Config.Client.Advanced.Graphics.Culling.disableBeaconDistanceCulling.get()) + { + // this could be called only when the player moves, but it's an extremely cheap check, + // so there isn't much of a reason to bother + this.tryUpdateBeaconCullingAsync(); + } + + + // this must be called on the render thread to prevent concurrency issues + if (this.updateRenderDataNextFrame) + { + this.activeBeaconBoxRenderGroup.triggerBoxChange(); + this.updateRenderDataNextFrame = false; + } + this.activeBeaconBoxRenderGroup.setActive(Config.Client.Advanced.Graphics.GenericRendering.enableBeaconRendering.get()); + } + /** does nothing if the culling thread is already running */ + private void tryUpdateBeaconCullingAsync() + { + ThreadPoolExecutor executor = ThreadPoolUtil.getBeaconCullingExecutor(); + if (executor != null + && !this.cullingThreadRunning) + { + this.cullingThreadRunning = true; + + try + { + executor.execute(() -> + { + try + { + Thread.sleep(MAX_CULLING_FREQUENCY_IN_MS); + } + catch (InterruptedException ignore) { } + + try + { + // lock to make sure we don't try adding beacons to the arrays while processing them + this.updateLock.lock(); + + Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); + + // fading by the overdraw prevention amount helps reduce beacons from rendering strangely + // on the border of DH's render distance + float dhFadeDistance = RenderUtil.getNearClipPlaneInBlocks(); + + + // Clear the existing box group so we can re-populate it. + // Since the box group is only used when we trigger an update, clearing it here + // and repopulating it is fine. + this.activeBeaconBoxRenderGroup.clear(); + + // While iterating over every beacon isn't a great way of doing this, + // when 940 beacons were tested this only took ~0.9 Milliseconds, so as long as + // we aren't freezing the render thread this method of culling works just fine. + for (DhApiRenderableBox box : this.fullBeaconBoxList) + { + // if a beacon is outside the vanilla render distance render it + double distance = Vec3d.getHorizontalDistance(cameraPos, box.minPos); + if (distance > dhFadeDistance) + { + this.activeBeaconBoxRenderGroup.add(box); + } + } + + this.updateRenderDataNextFrame = true; + } + catch (Exception e) + { + LOGGER.error("Unexpected issue while updating beacon culling. Error: " + e.getMessage(), e); + } + finally + { + this.updateLock.unlock(); + this.cullingThreadRunning = false; + } + }); + } + catch (RejectedExecutionException ignore) + { /* If this happens that means everything is already shut down and no culling is necessary */ } + } + } + + //endregion + + + + //================// + // helper classes // + //================// + //region + + private static class NegativeInfiniteBlockPosComparator implements Comparator + { + @Override + public int compare(BeaconBeamDTO beacon1, BeaconBeamDTO beacon2) + { + DhBlockPos blockPos1 = beacon1.blockPos; + DhBlockPos blockPos2 = beacon2.blockPos; + + // sort by X, then by Z + if (blockPos1.getX() != blockPos2.getX()) + { + return Integer.compare(blockPos1.getX(), blockPos2.getX()); + } + return Integer.compare(blockPos1.getZ(), blockPos2.getZ()); + } + } + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java new file mode 100644 index 000000000..76e18d55b --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java @@ -0,0 +1,619 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.render.renderer; + +import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.level.IDhClientLevel; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.math.Vec3d; +import com.seibel.distanthorizons.core.util.math.Vec3f; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.distanthorizons.coreapi.ModInfo; +import com.seibel.distanthorizons.core.logging.DhLogger; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +public class CloudRenderHandler +{ + private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + private static final IDhApiCustomRenderObjectFactory GENERIC_OBJECT_FACTORY = SingletonInjector.INSTANCE.get(IDhApiCustomRenderObjectFactory.class); + + private static final String CLOUD_RESOURCE_TEXTURE_PATH = "assets/distanthorizons/textures/clouds.png"; + + private static final boolean DEBUG_BORDER_COLORS = false; + + /** + * How wide an individual box is.
+ * Measured in blocks. + */ + private static final int CLOUD_BOX_WIDTH = 128; + /** measured in blocks */ + private static final int CLOUD_BOX_THICKNESS = 32; + + /** + * How many cloud groups wide can we render at maximum?
+ * 1 = 3x3 or 9 total
+ * 2 = 5x5 or 25 total

+ * + * 5 seems like a good count since it can cover up to around 2048 render distance. + */ + private static final int CLOUD_INSTANCE_RADIUS_COUNT = 5; + + private static final float MOVE_SPEED_IN_BLOCKS_PER_SECOND = 6.0f; + + + private final IDhApiRenderableBoxGroup[][] boxGroupByOffset + // radius * 2 to get the diameter + // + 1 so we get an odd number wide (needed so we can have a center position) + = new IDhApiRenderableBoxGroup[(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1][(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1]; + + private final IDhClientLevel level; + private final IMcGenericRenderer renderer; + + /** cached array so we don't need to re-create it each frame for each cloud group */ + private final Vec3d[] cullingCorners = new Vec3d[] + { + // the values of each will be overwritten during the culling pass + new Vec3d(), + new Vec3d(), + new Vec3d(), + new Vec3d(), + }; + + + private boolean disabledWarningLogged = false; + + + + //=============// + // constructor // + //=============// + //region + + public CloudRenderHandler(IDhClientLevel level, IMcGenericRenderer renderer) + { + this.level = level; + this.renderer = renderer; + + + + //=======================// + // get the cloud texture // + //=======================// + //region + + // default to a single empty slot in case the texture is broken + boolean[][] cloudLocations = new boolean[1][1]; + try + { + cloudLocations = getCloudsFromTexture(); + } + catch (FileNotFoundException e) + { + LOGGER.error(e.getMessage(), e); + } + catch (IOException e) + { + LOGGER.error("Unexpected issue getting cloud texture, error: ["+e.getMessage()+"].", e); + } + + if (cloudLocations.length != 0 && + cloudLocations.length != cloudLocations[0].length) + { + LOGGER.warn("Non-square cloud texture found, some parts of the texture will be clipped off."); + } + + //endregion + + + + //===================// + // parse the texture // + //===================// + //region + + int textureWidth = cloudLocations.length; + ArrayList boxList = new ArrayList<>(512); + for (int x = 0; x < textureWidth; x ++) + { + for (int z = 0; z < textureWidth; z ++) + { + if (cloudLocations[x][z]) + { + // start a new box in Z direction + int startZ = z; + int startX = x; + int endZ = startZ; + int endX = x+1; + + + + //==========================// + // merge in the Z direction // + //==========================// + + // Find the cloud's length in the Z direction + while (endZ < textureWidth + && cloudLocations[x][endZ]) + { + endZ++; + } + // update the z iterator so we can skip over everything included in this cloud + z = endZ - 1; + + + + //==========================// + // merge in the X direction // + //==========================// + + for (int currentX = startX + 1; currentX < textureWidth; currentX++) + { + boolean canMergeInXDir = true; + + // check if all locations in this column are true + for (int adjacentZ = startZ; adjacentZ < endZ; adjacentZ++) + { + if (!cloudLocations[currentX][adjacentZ]) + { + // at least one pixel in the texture is false, + // so we can't merge in this direction + canMergeInXDir = false; + break; + } + } + + + if (canMergeInXDir) + { + // mark the adjacent column as processed + for (int currentZ = startZ; currentZ < endZ; currentZ++) + { + // by flipping all the pixels in the adjacent column to false, + // we don't have to worry about adding another cloud + cloudLocations[currentX][currentZ] = false; + } + + endX = (currentX + 1); + } + else + { + break; + } + } + + + + //============================// + // Create the renderable box // + //============================// + + // endZ contains the last cloud index + // so the cloud now goes from startZ to endZ (inclusive) + int minXBlockPos = startX * CLOUD_BOX_WIDTH; + int minZBlockPos = startZ * CLOUD_BOX_WIDTH; + int maxXBlockPos = endX * CLOUD_BOX_WIDTH; + int maxZBlockPos = endZ * CLOUD_BOX_WIDTH; + + // this color is changed at render time based on the level time + Color color = new Color(255,255,255,255); + if (DEBUG_BORDER_COLORS) + { + // equals is included so the boarder is 2 blocks wide, making it easier to see + if (x <= 1) { color = Color.RED; } + else if (x >= textureWidth - 2) { color = Color.GREEN; } + if (z <= 1) { color = Color.BLUE; } + else if (z >= textureWidth - 2) { color = Color.BLACK; } + } + + DhApiRenderableBox box = new DhApiRenderableBox( + new DhApiVec3d(minXBlockPos, 0, minZBlockPos), + new DhApiVec3d(maxXBlockPos, CLOUD_BOX_THICKNESS, maxZBlockPos), + color, + EDhApiBlockMaterial.UNKNOWN + ); + boxList.add(box); + } + } + } + + //endregion + + + + //========================// + // create the renderables // + //========================// + //region + + // slightly lighter shading than the default + DhApiRenderableBoxGroupShading cloudShading = DhApiRenderableBoxGroupShading.getUnshaded(); + cloudShading.north = cloudShading.south = 0.9f; + cloudShading.east = cloudShading.west = 0.8f; + cloudShading.top = 1.0f; + cloudShading.bottom = 0.7f; + + + for (int x = -CLOUD_INSTANCE_RADIUS_COUNT; x <= CLOUD_INSTANCE_RADIUS_COUNT; x++) + { + for (int z = -CLOUD_INSTANCE_RADIUS_COUNT; z <= CLOUD_INSTANCE_RADIUS_COUNT; z++) + { + IDhApiRenderableBoxGroup boxGroup = GENERIC_OBJECT_FACTORY.createRelativePositionedGroup( + ModInfo.NAME + ":Clouds", + new DhApiVec3d(0, 0, 0), // the offset will be set during rendering + boxList); + + // since cloud colors are set by the level based on the time of day lighting should affect it + boxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); + boxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT); + boxGroup.setSsaoEnabled(false); + boxGroup.setShading(cloudShading); + + CloudParams cloudParams = new CloudParams(textureWidth, x, z); + boxGroup.setPreRenderFunc((renderParam) -> this.preRender(renderParam, cloudParams)); + + renderer.add(boxGroup); + this.boxGroupByOffset[x+CLOUD_INSTANCE_RADIUS_COUNT][z+CLOUD_INSTANCE_RADIUS_COUNT] = boxGroup; + } + } + } + + //endregion + + + + //===========// + // rendering // + //===========// + //region + + private void preRender(DhApiRenderParam renderParam, CloudParams cloudParams) + { + IDhApiRenderableBoxGroup boxGroup = this.boxGroupByOffset[cloudParams.instanceOffsetX+CLOUD_INSTANCE_RADIUS_COUNT][cloudParams.instanceOffsetZ+CLOUD_INSTANCE_RADIUS_COUNT]; + + + + //===================// + // should we render? // + //===================// + + boolean renderClouds = Config.Client.Advanced.Graphics.GenericRendering.enableCloudRendering.get(); + boxGroup.setActive(renderClouds); + if(!renderClouds) + { + return; + } + + //if (!this.renderer.getInstancedRenderingAvailable()) + //{ + // if (!this.disabledWarningLogged) + // { + // this.disabledWarningLogged = true; + // LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled."); + // } + // boxGroup.setActive(false); + // return; + //} + + IClientLevelWrapper clientLevelWrapper = this.level.getClientLevelWrapper(); + if (clientLevelWrapper == null) + { + return; + } + + + + //================// + // cloud movement // + //================// + + long currentTime = System.currentTimeMillis(); + float deltaTime = (currentTime - cloudParams.lastFrameTime) / 1000.0f; // Delta time in seconds + cloudParams.lastFrameTime = currentTime; + + float deltaX = MOVE_SPEED_IN_BLOCKS_PER_SECOND * deltaTime; + // negative delta is to match vanilla's cloud movement + cloudParams.deltaOffsetX -= deltaX; + // wrap the cloud around after reaching the edge + cloudParams.deltaOffsetX %= cloudParams.widthInBlocks; + + + + //============================// + // camera movement and offset // + //============================// + + // camera position + int cameraPosX = (int)MC_RENDER.getCameraExactPosition().x; + int cameraPosZ = (int)MC_RENDER.getCameraExactPosition().z; + // offset the camera position by negative 1 width when below zero to fix off-by-one errors in the negative direction + if (cameraPosX < 0) { cameraPosX -= cloudParams.widthInBlocks; } + if (cameraPosZ < 0) { cameraPosZ -= cloudParams.widthInBlocks; } + + // determine how many cloud instances away from the origin we are + int cloudInstanceOffsetCountX = (cameraPosX / cloudParams.widthInBlocks); + int cloudInstanceOffsetCountZ = (cameraPosZ / cloudParams.widthInBlocks); + // calculate the new offset + float instanceOffsetX = (cloudInstanceOffsetCountX * cloudParams.widthInBlocks); + float instanceOffsetZ = (cloudInstanceOffsetCountZ * cloudParams.widthInBlocks); + + + float newMinPosX = + cloudParams.deltaOffsetX + + (cloudParams.instanceOffsetX * cloudParams.widthInBlocks) + + instanceOffsetX + cloudParams.halfWidthInBlocks; + float newMinPosY = this.level.getLevelWrapper().getMaxHeight() + 200; + float newMinPosZ = cloudParams.deltaOffsetZ + + (cloudParams.instanceOffsetZ * cloudParams.widthInBlocks) + + instanceOffsetZ + cloudParams.halfWidthInBlocks; + + boolean cullCloud = this.shouldCloudBeCulled( + newMinPosX, newMinPosY, newMinPosZ, + cloudParams + ); + if(cullCloud) + { + boxGroup.setActive(false); + } + + + + //===========================// + // update color and position // + //===========================// + + // if debug colors are enabled don't change them + if (!DEBUG_BORDER_COLORS + // don't modify cloud groups that aren't active + && boxGroup.isActive()) + { + // cloud color changes based on the time of day and weather so we need to get it from the level + Color newCloudColor = clientLevelWrapper.getCloudColor(renderParam.partialTicks); + + + // all boxes should have the same color, so we can get their current color + // via the first box + DhApiRenderableBox firstBox = boxGroup.get(0); + Color currentBoxColor = firstBox.color; + + // update the boxes if their color should be changed + if (!newCloudColor.equals(currentBoxColor)) + { + // Note: cloud instances may share boxes + // because of that this method may only need to be called once per all clouds + for (DhApiRenderableBox box : boxGroup) + { + box.color = newCloudColor; + } + } + + + // trigger an update if this cloud section has a different color + if (!cloudParams.previousColor.equals(newCloudColor)) + { + cloudParams.previousColor = newCloudColor; + + boxGroup.triggerBoxChange(); + } + } + + boxGroup.setOriginBlockPos(new DhApiVec3d(newMinPosX, newMinPosY, newMinPosZ)); + } + private boolean shouldCloudBeCulled( + float minPosX, float minPosY, float minPosZ, + CloudParams cloudParams) + { + //========================// + // skip center 3x3 clouds // + //========================// + + // always render the center 3x3 clouds, otherwise we may see + // an un-rendered border + if (cloudParams.instanceOffsetX >= -1 && cloudParams.instanceOffsetX <= 1 + && cloudParams.instanceOffsetZ >= -1 && cloudParams.instanceOffsetZ <= 1) + { + return false; + } + + + + //==============// + // culling prep // + //==============// + + // we need all 4 corners since we want to draw any clouds that + // could potentially be within render distance + this.cullingCorners[0].x = minPosX; + this.cullingCorners[0].y = minPosY; + this.cullingCorners[0].z = minPosZ; + + this.cullingCorners[1].x = minPosX; + this.cullingCorners[1].y = minPosY; + this.cullingCorners[1].z = minPosZ + cloudParams.widthInBlocks; + + this.cullingCorners[2].x = minPosX + cloudParams.widthInBlocks; + this.cullingCorners[2].y = minPosY; + this.cullingCorners[2].z = minPosZ; + + this.cullingCorners[3].x = minPosX + cloudParams.widthInBlocks; + this.cullingCorners[3].y = minPosY; + this.cullingCorners[3].z = minPosZ + cloudParams.widthInBlocks; + + Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); + Vec3f cameraLookAtVector = MC_RENDER.getLookAtVector(); + cameraLookAtVector.normalize(); + + double renderDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() + // * 1.5 is so we have a little extra buffer where clouds will render further than + // necessary to prevent seeing the cloud border + * LodUtil.CHUNK_WIDTH * 1.5; + + + + //===================// + // check each corner // + //===================// + + boolean allOutsideRenderDistance = true; + boolean allBehindCamera = true; + + for (Vec3d corner : this.cullingCorners) + { + // Check if the corner is within the render distance + // (ignoring height, since LODs also ignore height) + + Vec3d cornerNoHeight = new Vec3d(corner); + cornerNoHeight.y = 0; + Vec3d cameraPosNoHeight = new Vec3d(cameraPos); + cameraPosNoHeight.y = 0; + + double cornerDistance = cornerNoHeight.getDistance(cameraPosNoHeight); + if (cornerDistance <= renderDistance) + { + allOutsideRenderDistance = false; + } + + + // Check if the corner is in front of the camera (dot product > 0 means in front) + Vec3f toCorner = new Vec3f( + (float) (corner.x - cameraPos.x), + (float) (corner.y - cameraPos.y), + (float) (corner.z - cameraPos.z)); + toCorner.normalize(); + + if (cameraLookAtVector.dotProduct(toCorner) > 0) + { + allBehindCamera = false; + } + } + + // Cull if all corners are either behind the camera or outside the render distance + return allOutsideRenderDistance || allBehindCamera; + } + + //endregion + + + + //==================// + // texture handling // + //==================// + //region + + private static boolean[][] getCloudsFromTexture() throws FileNotFoundException, IOException + { + final ClassLoader loader = CloudRenderHandler.class.getClassLoader(); + + boolean[][] whitePixels = null; + try(InputStream imageInputStream = loader.getResourceAsStream(CLOUD_RESOURCE_TEXTURE_PATH)) + { + if (imageInputStream == null) + { + throw new FileNotFoundException("Unable to find cloud texture at resource path: ["+CLOUD_RESOURCE_TEXTURE_PATH+"]."); + } + + BufferedImage image = ImageIO.read(imageInputStream); + + int width = image.getWidth(); + int height = image.getHeight(); + + whitePixels = new boolean[width][height]; + + for (int x = 0; x < width; x ++) + { + for (int z = 0; z < width; z ++) + { + Color color = new Color(image.getRGB(x,z)); + whitePixels[x][z] = color.equals(Color.WHITE); + } + } + } + + return whitePixels; + } + + //endregion + + + + //================// + // helper classes // + //================// + //region + + private static class CloudParams + { + public final int textureWidth; + public final int widthInBlocks; + public final int halfWidthInBlocks; + + public final int instanceOffsetX; + public final int instanceOffsetZ; + + + /** how far this cloud group has moved in the X direction based on time */ + public float deltaOffsetX = 0; + /** how far this cloud group has moved in the Z direction based on time */ + public float deltaOffsetZ = 0; + + public long lastFrameTime = System.currentTimeMillis(); + + /** used so we can trigger a VBO update when necessary */ + public Color previousColor = Color.WHITE; + + + + // constructor // + + public CloudParams(int textureWidth, int instanceOffsetX, int instanceOffsetZ) + { + this.textureWidth = textureWidth; + this.widthInBlocks = (this.textureWidth * CLOUD_BOX_WIDTH); + this.halfWidthInBlocks = this.widthInBlocks / 2; + + this.instanceOffsetX = instanceOffsetX; + this.instanceOffsetZ = instanceOffsetZ; + } + + } + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/DhFrustumBounds.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/DhFrustumBounds.java new file mode 100644 index 000000000..5fe059b34 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/DhFrustumBounds.java @@ -0,0 +1,69 @@ +package com.seibel.distanthorizons.core.render.renderer.cullingFrustum; + +import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum; +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import org.joml.FrustumIntersection; +import org.joml.Matrix4f; +import org.joml.Matrix4fc; +import org.joml.Vector3f; + + +public class DhFrustumBounds implements IDhApiCullingFrustum +{ + private final FrustumIntersection frustum; + private final Vector3f boundsMin = new Vector3f(); + private final Vector3f boundsMax = new Vector3f(); + public float worldMinY; + public float worldMaxY; + + + + //=============// + // constructor // + //=============// + + public DhFrustumBounds() + { + this.frustum = new FrustumIntersection(); + } + + + + //=========// + // methods // + //=========// + + @Override + public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f dhWorldViewProjection) + { + this.worldMinY = worldMinBlockY; + this.worldMaxY = worldMaxBlockY; + + Matrix4f worldViewProjection = new Matrix4f(Mat4f.createJomlMatrix(dhWorldViewProjection)); + this.frustum.set(worldViewProjection); + + Matrix4fc matWorldViewProjectionInv = new Matrix4f(worldViewProjection).invert(); + matWorldViewProjectionInv.frustumAabb(this.boundsMin, this.boundsMax); + } + + @Override + public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) + { + Vector3f lodMin = new Vector3f(lodBlockPosMinX, this.worldMinY, lodBlockPosMinZ); + Vector3f lodMax = new Vector3f(lodBlockPosMinX + lodBlockWidth, this.worldMaxY, lodBlockPosMinZ + lodBlockWidth); + + return this.frustum.testAab(lodMin, lodMax); + } + + + + //=====================// + // overridable methods // + //=====================// + + @Override + public int getPriority() { return IOverrideInjector.CORE_PRIORITY; } + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/NeverCullFrustum.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/NeverCullFrustum.java new file mode 100644 index 000000000..e6ca60d54 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/cullingFrustum/NeverCullFrustum.java @@ -0,0 +1,41 @@ +package com.seibel.distanthorizons.core.render.renderer.cullingFrustum; + +import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum; +import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum; +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector; + +/** + * Dummy {@link IDhApiCullingFrustum} that allows everything through.
+ * Useful when a frustum is required, but culling shouldn't be done. + */ +public class NeverCullFrustum implements IDhApiCullingFrustum, IDhApiShadowCullingFrustum +{ + //=============// + // constructor // + //=============// + + public NeverCullFrustum() { } + + + + //=========// + // methods // + //=========// + + @Override + public void update(int worldMinBlockY, int worldMaxBlockY, DhApiMat4f dhWorldViewProjection) { /* update isn't needed */ } + + @Override + public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel) { return true; } + + + + //=====================// + // overridable methods // + //=====================// + + @Override + public int getPriority() { return IOverrideInjector.CORE_PRIORITY; } + +} From 49e34d78a521e3f795b06eb556025aa458dc2bb0 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 17:35:24 -0500 Subject: [PATCH 31/46] update debug wireframe renderer --- .../IDhApiCustomRenderObjectFactory.java | 3 +- .../DhApiRenderParam.java | 6 + .../distanthorizons/core/Initializer.java | 9 +- .../methods/data/DhApiTerrainDataRepo.java | 10 +- .../core/api/internal/SharedApi.java | 6 +- .../bufferBuilding/LodBufferContainer.java | 46 +-- .../render/bufferBuilding/LodQuadBuilder.java | 26 +- .../file/fullDatafile/V2/DataMigratorV1.java | 2 - .../V2/FullDataSourceProviderV2.java | 13 +- .../V2/FullDataUpdatePropagatorV2.java | 6 +- .../fullDatafile/V2/FullDataUpdaterV2.java | 8 +- .../core/generation/DhLightingEngine.java | 11 +- .../core/generation/WorldGenerationQueue.java | 17 +- .../AbstractFullDataNetworkRequestQueue.java | 13 +- .../core/render/QuadTree/LodQuadTree.java | 16 +- .../render/QuadTree/LodRenderSection.java | 22 +- .../AbstractDebugWireframeRenderer.java | 323 ++++++++++++++++++ .../render/renderer/BlazeLodRenderer.java | 9 +- .../render/renderer/IDebugRenderable.java | 2 +- .../render/IMcDebugRenderer.java | 33 -- 20 files changed, 455 insertions(+), 126 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java delete mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java diff --git a/api/src/main/java/com/seibel/distanthorizons/api/interfaces/render/IDhApiCustomRenderObjectFactory.java b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/render/IDhApiCustomRenderObjectFactory.java index 334c3edd1..793280d9d 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/interfaces/render/IDhApiCustomRenderObjectFactory.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/interfaces/render/IDhApiCustomRenderObjectFactory.java @@ -3,6 +3,7 @@ package com.seibel.distanthorizons.api.interfaces.render; import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; import com.seibel.distanthorizons.api.objects.math.DhApiVec3f; import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; import java.util.List; @@ -18,7 +19,7 @@ import java.util.List; * @version 2024-7-3 * @since API 3.0.0 */ -public interface IDhApiCustomRenderObjectFactory +public interface IDhApiCustomRenderObjectFactory extends IBindable { /** * Creates a {@link IDhApiRenderableBoxGroup} from for the given {@link DhApiRenderableBox} diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/sharedParameterObjects/DhApiRenderParam.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/sharedParameterObjects/DhApiRenderParam.java index decd51a50..0709c0786 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/sharedParameterObjects/DhApiRenderParam.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/sharedParameterObjects/DhApiRenderParam.java @@ -60,6 +60,8 @@ public class DhApiRenderParam implements IDhApiEventParam public final DhApiMat4f dhProjectionMatrix; /** The model view matrix Distant Horizons is using to render this frame. */ public final DhApiMat4f dhModelViewMatrix; + /** combination of the MVM and projection matrices */ + public final DhApiMat4f dhMvmProjMatrix; public final int worldYOffset; @@ -111,6 +113,10 @@ public class DhApiRenderParam implements IDhApiEventParam this.dhProjectionMatrix = newDhProjectionMatrix; this.dhModelViewMatrix = newDhModelViewMatrix; + DhApiMat4f combinedMatrix = new DhApiMat4f(this.dhProjectionMatrix); + combinedMatrix.multiply(this.dhModelViewMatrix); + this.dhMvmProjMatrix = combinedMatrix; + this.worldYOffset = worldYOffset; this.clientLevelWrapper = clientLevelWrapper; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java b/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java index 50cf8d2aa..51a7ebb24 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/Initializer.java @@ -20,6 +20,7 @@ package com.seibel.distanthorizons.core; import com.github.luben.zstd.ZstdOutputStream; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderEvent; import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.config.Config; @@ -160,13 +161,17 @@ public class Initializer DhApi.Delayed.terrainRepo = DhApiTerrainDataRepo.INSTANCE; DhApi.Delayed.worldProxy = DhApiWorldProxy.INSTANCE; DhApi.Delayed.renderProxy = DhApiRenderProxy.INSTANCE; - DhApi.Delayed.customRenderObjectFactory = GenericRenderObjectFactory.INSTANCE; DhApi.Delayed.wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class); if (DhApi.Delayed.wrapperFactory == null) { - LOGGER.error("Programmer Error: No ["+IWrapperFactory.class.getSimpleName()+"] assigned to the DhApi."); + MC_CLIENT.crashMinecraft("Programmer Error: No ["+IWrapperFactory.class.getSimpleName()+"] assigned to the DhApi.", new Exception()); } + DhApi.Delayed.customRenderObjectFactory = SingletonInjector.INSTANCE.get(IDhApiCustomRenderObjectFactory.class); + if (DhApi.Delayed.customRenderObjectFactory == null) + { + MC_CLIENT.crashMinecraft("Programmer Error: No ["+IDhApiCustomRenderObjectFactory.class.getSimpleName()+"] assigned to the DhApi.", new Exception()); + } DhApi.events.bind(DhApiBeforeRenderEvent.class, IgnoredDimensionCsvHandler.INSTANCE); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java index 49c3b7a9a..7b23d02e7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java @@ -34,7 +34,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.util.DhApiTerrainDataPointUtil; import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.util.LodUtil; @@ -66,6 +66,8 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + // debugging values private static volatile boolean debugThreadRunning = false; private static DhApiTerrainDataCache debugDataCache = new DhApiTerrainDataCache(); @@ -588,9 +590,9 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo if (rayCast.success && rayCast.payload != null) { - DebugRenderer.makeParticle( - new DebugRenderer.BoxParticle( - new DebugRenderer.Box( + DEBUG_RENDERER.makeParticle( + new AbstractDebugWireframeRenderer.BoxParticle( + new AbstractDebugWireframeRenderer.Box( DhSectionPos.encode((byte) 0, rayCast.payload.pos.x, rayCast.payload.pos.z), rayCast.payload.dataPoint.bottomYBlockPos, rayCast.payload.dataPoint.topYBlockPos, diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java index 87a44ff21..4fb7b1718 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java @@ -32,7 +32,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhChunkPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo; import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; @@ -57,6 +57,7 @@ public class SharedApi /** will be null on the server-side */ @Nullable private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + private static final AbstractDebugWireframeRenderer DEBUG_WIREFRAME_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); public static final WorldChunkUpdateManager WORLD_CHUNK_UPDATE_MANAGER = WorldChunkUpdateManager.INSTANCE; // local fariable for quick access @@ -105,7 +106,8 @@ public class SharedApi else { ThreadPoolUtil.shutdownThreadPools(); - DebugRenderer.clearRenderables(); + + DEBUG_WIREFRAME_RENDERER.clearRenderables(); if (MC_RENDER != null) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index 95338fe68..d3a15ecc5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -24,9 +24,8 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; -import com.seibel.distanthorizons.core.render.glObject.GLProxy; +import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.util.LodUtil; -import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; @@ -49,13 +48,6 @@ public class LodBufferContainer implements AutoCloseable private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); - /** number of bytes a single quad takes */ - public static final int QUADS_BYTE_SIZE = LodUtil.DH_VERTEX_FORMAT.getByteSize() * 4; - /** how big a single VBO can be in bytes */ - public static final int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB - public static final int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE; - public static final int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE; - /** the position closest to minimum X/Z infinity and the level's lowest Y */ public final DhBlockPos minCornerBlockPos; @@ -75,6 +67,7 @@ public class LodBufferContainer implements AutoCloseable //==============// // constructors // //==============// + //region public LodBufferContainer(long pos, DhBlockPos minCornerBlockPos) { @@ -86,11 +79,14 @@ public class LodBufferContainer implements AutoCloseable this.uniformContainer.createUniformData(this); } + //endregion + //==================// // buffer uploading // //==================// + //region /** Should be run on a DH thread. */ public synchronized CompletableFuture makeAndUploadBuffersAsync(LodQuadBuilder builder) @@ -128,12 +124,12 @@ public class LodBufferContainer implements AutoCloseable ArrayList opaqueBuffers = builder.makeOpaqueVertexBuffers(); ArrayList transparentBuffers = builder.makeTransparentVertexBuffers(); - this.vbos = resizeBuffer(this.vbos, opaqueBuffers.size()); - this.vbosTransparent = resizeBuffer(this.vbosTransparent, transparentBuffers.size()); + this.vbos = resizeBufferArray(this.vbos, opaqueBuffers.size()); + this.vbosTransparent = resizeBufferArray(this.vbosTransparent, transparentBuffers.size()); // upload on MC's render thread - GLProxy.queueRunningOnRenderThread(() -> + RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() -> { try { @@ -144,11 +140,9 @@ public class LodBufferContainer implements AutoCloseable throw new InterruptedException(); } - EDhApiGpuUploadMethod gpuUploadMethod = GLProxy.getInstance().getGpuUploadMethod(); - // upload on the render thread - uploadBuffersDirect(this.vbos, opaqueBuffers, gpuUploadMethod); - uploadBuffersDirect(this.vbosTransparent, transparentBuffers, gpuUploadMethod); + uploadBuffers(this.vbos, opaqueBuffers); + uploadBuffers(this.vbosTransparent, transparentBuffers); this.buffersUploaded = true; // success @@ -182,7 +176,7 @@ public class LodBufferContainer implements AutoCloseable return future; } - private static IVertexBufferWrapper[] resizeBuffer(IVertexBufferWrapper[] vbos, int newSize) + private static IVertexBufferWrapper[] resizeBufferArray(IVertexBufferWrapper[] vbos, int newSize) { if (vbos.length == newSize) { @@ -203,9 +197,7 @@ public class LodBufferContainer implements AutoCloseable } return newVbos; } - private static void uploadBuffersDirect( - IVertexBufferWrapper[] vbos, ArrayList byteBuffers, - EDhApiGpuUploadMethod uploadMethod) throws InterruptedException + private static void uploadBuffers(IVertexBufferWrapper[] vbos, ArrayList byteBuffers) throws InterruptedException { int vboIndex = 0; for (int i = 0; i < byteBuffers.size(); i++) @@ -227,7 +219,7 @@ public class LodBufferContainer implements AutoCloseable ByteBuffer buffer = byteBuffers.get(i); int size = buffer.limit() - buffer.position(); - int vertexCount = size / lodRenderer.getVertexSize(); + int vertexCount = size / lodRenderer.getVertexByteSize(); try { @@ -249,11 +241,14 @@ public class LodBufferContainer implements AutoCloseable } } + //endregion + //================// // helper methods // //================// + //region /** can be used when debugging */ public boolean hasNonNullVbos() { return this.vbos != null || this.vbosTransparent != null; } @@ -278,11 +273,14 @@ public class LodBufferContainer implements AutoCloseable public boolean uploadInProgress() { return this.uploadFutureRef.get() != null; } + //endregion + //================// // base overrides // //================// + //region /** * This method is called when object is no longer in use. @@ -295,7 +293,7 @@ public class LodBufferContainer implements AutoCloseable { this.buffersUploaded = false; - GLProxy.queueRunningOnRenderThread(() -> + RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() -> { for (IVertexBufferWrapper buffer : this.vbos) { @@ -317,4 +315,8 @@ public class LodBufferContainer implements AutoCloseable }); } + //endregion + + + } 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 3bba59013..c2c3c112a 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 @@ -32,6 +32,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.util.MathUtil; import org.lwjgl.system.MemoryUtil; @@ -306,7 +307,7 @@ public class LodQuadBuilder // create a new buffer if (buffer == null || !buffer.hasRemaining()) { - buffer = MemoryUtil.memAlloc(LodBufferContainer.FULL_SIZED_BUFFER); + buffer = MemoryUtil.memAlloc(getMaxBufferByteSize()); byteBufferList.add(buffer); } @@ -481,17 +482,26 @@ public class LodQuadBuilder return i; } - /** Returns how many GpuBuffers will be needed to render opaque quads in this builder. */ - public int getCurrentNeededOpaqueVertexBufferCount() { return MathUtil.ceilDiv(this.getCurrentOpaqueQuadsCount(), LodBufferContainer.MAX_QUADS_PER_BUFFER); } - /** Returns how many GpuBuffers will be needed to render transparent quads in this builder. */ - public int getCurrentNeededTransparentVertexBufferCount() + private static int maxBufferByteSize = -1; + public static int getMaxBufferByteSize() { - if (!this.doTransparency) + if (maxBufferByteSize != -1) { - return 0; + return maxBufferByteSize; } - return MathUtil.ceilDiv(this.getCurrentTransparentQuadsCount(), LodBufferContainer.MAX_QUADS_PER_BUFFER); + IMcLodRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); + + /** number of bytes a single quad takes */ + int QUADS_BYTE_SIZE = LOD_RENDERER.getVertexByteSize() * 4; + /** how big a single VBO can be in bytes */ + int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB + int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE; + int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE; + + maxBufferByteSize = FULL_SIZED_BUFFER; + + return FULL_SIZED_BUFFER; } ///endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java index 344e7d91b..e65a8e46b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/DataMigratorV1.java @@ -9,9 +9,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import java.io.File; import java.io.IOException; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java index 3dd6fd4be..a1b57ce35 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataSourceProviderV2.java @@ -31,6 +31,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo; @@ -38,7 +39,6 @@ import com.seibel.distanthorizons.core.sql.repo.FullDataSourceV2Repo; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import it.unimi.dsi.fastutil.longs.LongArrayList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,7 +57,9 @@ import java.util.concurrent.atomic.AtomicBoolean; public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); - + + private static final AbstractDebugWireframeRenderer DEBUG_WIREFRAME_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + private static final Set CORRUPT_DATA_ERRORS_LOGGED = Collections.newSetFromMap(new ConcurrentHashMap<>()); /** @@ -109,8 +111,7 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable this.updatePropagator = new FullDataUpdatePropagatorV2(this, this.dataUpdater, this.levelId); this.dataMigratorV1 = new DataMigratorV1(this.dataUpdater, this.level, this.levelId, this.saveDir); - IMcDebugRenderer debugRenderer = SingletonInjector.INSTANCE.get(IMcDebugRenderer.class); - debugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus); + DEBUG_WIREFRAME_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus); } @@ -449,7 +450,7 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable //===========// @Override - public void debugRender(IMcDebugRenderer renderer) + public void debugRender(AbstractDebugWireframeRenderer renderer) { this.dataUpdater.debugRender(renderer); this.updatePropagator.debugRender(renderer); @@ -466,6 +467,8 @@ public class FullDataSourceProviderV2 implements IDebugRenderable, AutoCloseable this.updatePropagator.close(); this.dataMigratorV1.close(); + DEBUG_WIREFRAME_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showFullDataUpdateStatus); + this.repo.close(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java index 9aa7c6448..69b01734d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java @@ -7,12 +7,12 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import it.unimi.dsi.fastutil.longs.LongArrayList; import java.awt.*; @@ -388,10 +388,10 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab //region @Override - public void debugRender(IMcDebugRenderer renderer) + public void debugRender(AbstractDebugWireframeRenderer renderer) { this.updatingPosSet - .forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); + .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java index 81941efdb..3e249d80f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java @@ -7,11 +7,11 @@ import com.seibel.distanthorizons.core.file.fullDatafile.IDataSourceUpdateListen import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.threading.PositionalLockProvider; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcDebugRenderer; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -225,13 +225,13 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable //===========// @Override - public void debugRender(IMcDebugRenderer renderer) + public void debugRender(AbstractDebugWireframeRenderer renderer) { this.lockedPosSet - .forEach((pos) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); + .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); this.queuedUpdateCountsByPos - .forEach((pos, updateCountRef) -> { renderer.render(new IMcDebugRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); + .forEach((pos, updateCountRef) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 28176238b..d50055f6b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -20,13 +20,14 @@ package com.seibel.distanthorizons.core.generation; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.util.FullDataPointUtil; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; @@ -52,6 +53,8 @@ public class DhLightingEngine private static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLightingEngine INSTANCE = new DhLightingEngine(); + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + /** * Minor garbage collection optimization.
* Since these objects are always mutated anyway, using a {@link ThreadLocal} will allow us to @@ -725,9 +728,9 @@ public class DhLightingEngine // a color can be set to null if you only want to troubleshoot up to a certain light level if (color != null) { - DebugRenderer.makeParticle( - new DebugRenderer.BoxParticle( - new DebugRenderer.Box(DhSectionPos.encode((byte) 0, chunkMinX + x, chunkMinZ + z), y, y + 1, 0.2f, color), + DEBUG_RENDERER.makeParticle( + new AbstractDebugWireframeRenderer.BoxParticle( + new AbstractDebugWireframeRenderer.Box(DhSectionPos.encode((byte) 0, chunkMinX + x, chunkMinZ + z), y, y + 1, 0.2f, color), 10.0, 0f ) ); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java index 71d45101e..a05af17f8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java @@ -36,7 +36,7 @@ import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.util.ExceptionUtil; import com.seibel.distanthorizons.core.util.LodUtil.AssertFailureException; @@ -61,6 +61,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); private final IDhApiWorldGenerator generator; @@ -110,7 +111,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb this.lowestDataDetail = generator.getLargestDataDetailLevel(); this.highestDataDetail = generator.getSmallestDataDetailLevel(); - DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); + DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); LOGGER.info("Created world gen queue"); } @@ -623,7 +624,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb ///region debug @Override - public void debugRender(DebugRenderer renderer) + public void debugRender(AbstractDebugWireframeRenderer renderer) { int levelMinY = this.level.getLevelWrapper().getMinHeight(); int levelMaxY = this.level.getLevelWrapper().getMaxHeight(); @@ -637,16 +638,16 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // blue - queued this.waitingTasks.keySet().forEach((Long pos) -> { - renderer.renderBox( - new DebugRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.blue) + renderer.render( + new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.blue) ); }); // red - in progress this.inProgressGenTasksByLodPos.forEach((Long pos, DataSourceRetrievalTask task) -> { - renderer.renderBox( - new DebugRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.red) + renderer.render( + new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.red) ); }); } @@ -732,7 +733,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb this.generator.close(); - DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); + DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showWorldGenQueue); try diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java index eaedb4abb..6a76ace30 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java @@ -18,6 +18,7 @@ import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceR import com.seibel.distanthorizons.core.network.messages.fullData.FullDataSourceResponseMessage; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.LodUtil; @@ -42,6 +43,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende .build(); private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); private static final int MAX_RETRY_ATTEMPTS = 3; @@ -85,7 +87,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende this.level = level; this.changedOnly = changedOnly; this.showDebugWireframeConfig = showDebugWireframeConfig; - DebugRenderer.register(this, this.showDebugWireframeConfig); + DEBUG_RENDERER.register(this, this.showDebugWireframeConfig); } @@ -384,10 +386,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende } @Override - public void close() - { - DebugRenderer.unregister(this, this.showDebugWireframeConfig); - } + public void close() { DEBUG_RENDERER.unregister(this, this.showDebugWireframeConfig); } @@ -396,7 +395,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende //===========// @Override - public void debugRender(DebugRenderer renderer) + public void debugRender(AbstractDebugWireframeRenderer renderer) { if (MC_CLIENT.getWrappedClientLevel() != this.level.getClientLevelWrapper()) { @@ -427,7 +426,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende } } - renderer.renderBox(new DebugRenderer.Box(pos, -32f, 64f, 0.05f, color)); + renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 64f, 0.05f, color)); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java index c1108f6fa..75eb7fe38 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java @@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.render.QuadTree; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.listeners.IConfigListener; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataSourceProviderV2; import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataUpdatePropagatorV2; @@ -33,9 +34,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; +import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; -import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.WorldGenUtil; @@ -67,6 +68,9 @@ import java.util.concurrent.locks.ReentrantLock; public class LodQuadTree extends QuadTree implements IDebugRenderable, IConfigListener, AutoCloseable { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + /** there should only ever be one {@link LodQuadTree} so having the thread static should be fine */ private static final ThreadPoolExecutor FULL_DATA_RETRIEVAL_QUEUE_THREAD = ThreadUtil.makeSingleThreadPool("LodQuadTree Data Retrieval Queue"); @@ -135,7 +139,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen { super(viewDiameterInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); - DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); + DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); this.level = level; this.fullDataSourceProvider = fullDataSourceProvider; @@ -973,7 +977,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen //region debugging @Override - public void debugRender(DebugRenderer debugRenderer) + public void debugRender(AbstractDebugWireframeRenderer debugRenderer) { this.populateListWithEnabledRenderSections(this.debugNodeList); @@ -1012,7 +1016,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen int levelHeightRange = (levelMaxY - levelMinY); int maxY = levelMaxY - (levelHeightRange / 2); - debugRenderer.renderBox(new DebugRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color)); + debugRenderer.render(new AbstractDebugWireframeRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color)); } } @@ -1030,7 +1034,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen { LOGGER.info("Shutting down LodQuadTree..."); - DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); + DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showQuadTreeRenderStatus); Config.Common.WorldGenerator.enableDistantGeneration.removeListener(this); Config.Server.enableServerGeneration.removeListener(this); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java index 39f3c217e..203291073 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java @@ -33,6 +33,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.BeaconRenderHandler; import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; @@ -60,6 +61,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable { private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final AbstractDebugWireframeRenderer DEBUG_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); @@ -135,7 +137,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable this.beaconRenderHandler = this.quadTree.beaconRenderHandler; this.beaconBeamRepo = this.level.getBeaconBeamRepo(); - DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); + DEBUG_RENDERER.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); } //endregion constructor @@ -443,9 +445,9 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get()) { // show that this position has just been disabled - DebugRenderer.makeParticle( - new DebugRenderer.BoxParticle( - new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()), + DEBUG_RENDERER.makeParticle( + new AbstractDebugWireframeRenderer.BoxParticle( + new AbstractDebugWireframeRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()), 0.2, 32f ) ); @@ -504,7 +506,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable //region base methods @Override - public void debugRender(DebugRenderer debugRenderer) + public void debugRender(AbstractDebugWireframeRenderer debugRenderer) { Color color = Color.red; if (this.renderingEnabled) @@ -530,7 +532,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable int levelHeightRange = (levelMaxY - levelMinY); int maxY = levelMaxY - (levelHeightRange / 2); - debugRenderer.renderBox(new DebugRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color)); + debugRenderer.render(new AbstractDebugWireframeRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color)); } @Override @@ -546,14 +548,14 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable @Override public void close() { - DebugRenderer.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); + DEBUG_RENDERER.unregister(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus); if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get()) { // show a particle for the closed section - DebugRenderer.makeParticle( - new DebugRenderer.BoxParticle( - new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.RED.darker()), + DEBUG_RENDERER.makeParticle( + new AbstractDebugWireframeRenderer.BoxParticle( + new AbstractDebugWireframeRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.RED.darker()), 0.5, 32f ) ); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java new file mode 100644 index 000000000..e736c94dc --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java @@ -0,0 +1,323 @@ +package com.seibel.distanthorizons.core.render.renderer; + +import com.seibel.distanthorizons.core.config.Config; +import com.seibel.distanthorizons.core.config.types.ConfigEntry; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.logging.DhLogger; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.render.RenderParams; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.util.math.Vec3d; +import com.seibel.distanthorizons.core.util.math.Vec3f; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.concurrent.PriorityBlockingQueue; + +public abstract class AbstractDebugWireframeRenderer implements IBindable +{ + protected static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder() + .maxCountPerSecond(1) + .build(); + + protected static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + + + protected final RendererLists rendererLists = new RendererLists(); + protected final PriorityBlockingQueue particles = new PriorityBlockingQueue<>(); + + // used when rendering + @Deprecated // all rendering should be done in a single pass + protected Mat4f dhMvmProjMatrixThisFrame; + @Deprecated // all rendering should be done in a single pass + protected Vec3f camPosFloatThisFrame; + + + + //===========// + // rendering // + //===========// + //region + + public void renderPass(RenderParams renderParams) + { + this.dhMvmProjMatrixThisFrame = new Mat4f(renderParams.dhMvmProjMatrix); + Vec3d camPos = MC_RENDER.getCameraExactPosition(); + this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z); + + + this.rendererLists.render(this); + + + // particle rendering + BoxParticle head = null; + while ((head = this.particles.poll()) != null && head.isDead()) + { /* remove dead particles */ } + if (head != null) + { + // re-add the popped off head + this.particles.add(head); + } + } + + public abstract void render(Box box); + + //endregion + + + + //==============// + // registration // + //==============// + //region + + public void makeParticle(BoxParticle particle) + { + if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get()) + { + this.particles.add(particle); + } + } + + public void register(IDebugRenderable renderable, ConfigEntry config) { this.addRenderer(renderable, config); } + public void addRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.addRenderable(renderable, config); } + + public void unregister(IDebugRenderable renderable, ConfigEntry config) { this.removeRenderer(renderable, config); } + public void removeRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.removeRenderable(renderable, config); } + + public void clearRenderables() { this.rendererLists.clearRenderables(); } + + //endregion + + + + //================// + // helper classes // + //================// + //region + + public static final class Box + { + public Vec3f minPos; + public Vec3f maxPos; + public Color color; + + + + public Box(long pos, float minY, float maxY, float marginPercent, Color color) + { + float edgeOffset = DhSectionPos.getBlockWidth(pos) * marginPercent; + + int minBlockPosX = DhSectionPos.getMinCornerBlockX(pos); + int minBlockPosZ = DhSectionPos.getMinCornerBlockZ(pos); + int maxBlockPosX = minBlockPosX + DhSectionPos.getBlockWidth(pos); + int maxBlockPosZ = minBlockPosZ + DhSectionPos.getBlockWidth(pos); + + this.minPos = new Vec3f(minBlockPosX + edgeOffset, minY, minBlockPosZ + edgeOffset); + this.maxPos = new Vec3f(maxBlockPosX - edgeOffset, maxY, maxBlockPosZ - edgeOffset); + this.color = color; + } + + /** only used for */ + public Box(Vec3f minPos, Vec3f maxPos, Color color) + { + this.minPos = minPos; + this.maxPos = maxPos; + this.color = color; + } + + } + + public static final class BoxParticle implements Comparable + { + public Box box; + public long startMsTime; + public long durationInMs; + public float yChange; + + + private BoxParticle(Box box, long startMsTime, long durationInMs, float yChange) + { + this.box = box; + this.startMsTime = startMsTime; + this.durationInMs = durationInMs; + this.yChange = yChange; + } + + public BoxParticle(Box box, double secondDuration, float yChange) + { this(box, System.currentTimeMillis(), (long) (secondDuration * 1_000), yChange); } + + + @Override + public int compareTo(@NotNull BoxParticle particle) + { return Long.compare(this.startMsTime + this.durationInMs, particle.startMsTime + particle.durationInMs); } + + /** will change each time it's called based on the yChange value and time */ + public Box createNewRenderBox() + { + long nowMs = System.currentTimeMillis(); + + float percent = (nowMs - this.startMsTime) / (float) this.durationInMs; + percent = (float) Math.pow(percent, 4); + float yDiff = this.yChange * percent; + + return new Box( + new Vec3f(this.box.minPos.x, this.box.minPos.y + yDiff, this.box.minPos.z), + new Vec3f(this.box.maxPos.x, this.box.maxPos.y + yDiff, this.box.maxPos.z), + this.box.color); + } + + public boolean isDead() { return (System.currentTimeMillis() - this.startMsTime) > this.durationInMs; } + + } + + protected static class RendererLists + { + public final LinkedList> generalRenderableList = new LinkedList<>(); + + private final HashMap, LinkedList>> renderableListByConfig = new HashMap<>(); + + + + //==============// + // registration // + //==============// + //region + + public void addRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config) + { + synchronized (this) + { + if (config != null) + { + if (!this.renderableListByConfig.containsKey(config)) + { + this.renderableListByConfig.put(config, new LinkedList<>()); + } + + LinkedList> renderableList = this.renderableListByConfig.get(config); + renderableList.add(new WeakReference<>(renderable)); + } + else + { + this.generalRenderableList.add(new WeakReference<>(renderable)); + } + } + } + + public void removeRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config) + { + synchronized (this) + { + if (config != null) + { + if (this.renderableListByConfig.containsKey(config)) + { + LinkedList> renderableList = this.renderableListByConfig.get(config); + this.removeRenderableFromInternalList(renderableList, renderable); + } + } + else + { + this.removeRenderableFromInternalList(this.generalRenderableList, renderable); + } + } + } + private void removeRenderableFromInternalList(LinkedList> rendererList, IDebugRenderable renderable) + { + Iterator> iterator = rendererList.iterator(); + while (iterator.hasNext()) + { + WeakReference renderableRef = iterator.next(); + if (renderableRef.get() == null) + { + iterator.remove(); + continue; + } + + if (renderableRef.get() == renderable) + { + iterator.remove(); + return; + } + } + } + + public void clearRenderables() + { + for (ConfigEntry config : this.renderableListByConfig.keySet()) + { + LinkedList> renderableList = this.renderableListByConfig.get(config); + if (config.get() && renderableList != null) + { + renderableList.clear(); + } + } + } + + //endregion + + + + //===========// + // rendering // + //===========// + //region + + public void render(AbstractDebugWireframeRenderer debugRenderer) + { + this.renderList(debugRenderer, this.generalRenderableList); + + for (ConfigEntry config : this.renderableListByConfig.keySet()) + { + LinkedList> renderableList = this.renderableListByConfig.get(config); + if (config.get() && renderableList != null && renderableList.size() != 0) + { + this.renderList(debugRenderer, renderableList); + } + } + } + private void renderList(AbstractDebugWireframeRenderer debugRenderer, LinkedList> rendererList) + { + synchronized (this) + { + try + { + Iterator> iterator = rendererList.iterator(); + while (iterator.hasNext()) + { + WeakReference ref = iterator.next(); + IDebugRenderable renderable = ref.get(); + if (renderable == null) + { + iterator.remove(); + continue; + } + + renderable.debugRender(debugRenderer); + } + } + catch (Exception e) + { + RATE_LIMITED_LOGGER.error("Unexpected Debug renderer error, Error: "+e.getMessage(), e); + } + } + } + + //endregion + } + + //endregion + + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java index b1227b8cb..0e3faa4c9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java @@ -19,7 +19,6 @@ package com.seibel.distanthorizons.core.render.renderer; -import com.seibel.distanthorizons.api.enums.rendering.EDhApiRendererMode; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; @@ -28,6 +27,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -148,6 +148,7 @@ public class BlazeLodRenderer IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class); IMcFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IMcFarFadeRenderer.class); + AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); @@ -231,7 +232,7 @@ public class BlazeLodRenderer profiler.popPush("Debug wireframes"); // Note: this can be very slow if a lot of boxes are being rendered - DebugRenderer.INSTANCE.render(renderParams); + debugWireframeRenderer.renderPass(renderParams); } profiler.popPush("Apply to MC"); @@ -258,8 +259,8 @@ public class BlazeLodRenderer Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - FogRenderer.INSTANCE.render(combinedMatrix, renderParams.partialTicks); + + fogRenderer.render(combinedMatrix, renderParams.partialTicks); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/IDebugRenderable.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/IDebugRenderable.java index 30d45c4bc..05883941d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/IDebugRenderable.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/IDebugRenderable.java @@ -21,6 +21,6 @@ package com.seibel.distanthorizons.core.render.renderer; public interface IDebugRenderable { - void debugRender(DebugRenderer r); + void debugRender(AbstractDebugWireframeRenderer r); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java deleted file mode 100644 index 01e59399a..000000000 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcDebugRenderer.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the Distant Horizons mod - * licensed under the GNU LGPL 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 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.core.wrapperInterfaces.render; - -import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; -import com.seibel.distanthorizons.core.render.renderer.RenderParams; -import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; - -import java.util.Collection; - -public interface IMcDebugRenderer extends IBindable -{ - void render(RenderParams renderEventParam, Collection boxCollection); - void render(DebugRenderer.Box box); - -} From 2ea3d645e81f955de253a5a290c53fc5987c1d8e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 17:39:58 -0500 Subject: [PATCH 32/46] remove deprication warnings --- .../AbstractDebugWireframeRenderer.java | 3 -- .../IGenericObjectVertexBufferContainer.java | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java index e736c94dc..8bd7aa51f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java @@ -35,9 +35,7 @@ public abstract class AbstractDebugWireframeRenderer implements IBindable protected final PriorityBlockingQueue particles = new PriorityBlockingQueue<>(); // used when rendering - @Deprecated // all rendering should be done in a single pass protected Mat4f dhMvmProjMatrixThisFrame; - @Deprecated // all rendering should be done in a single pass protected Vec3f camPosFloatThisFrame; @@ -319,5 +317,4 @@ public abstract class AbstractDebugWireframeRenderer implements IBindable - } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java new file mode 100644 index 000000000..c68d8d2b2 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java @@ -0,0 +1,40 @@ +package com.seibel.distanthorizons.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; + +import java.util.List; + +public interface IGenericObjectVertexBufferContainer extends AutoCloseable +{ + void uploadDataToGpu(); + + void updateVertexData(List uploadBoxList); + + EState getState(); + void setState(EState state); + + @Override + void close(); + + + + //================// + // helper classes // + //================// + //region + + enum EState + { + NEW, + UPDATING_DATA, + READY_TO_UPLOAD, + RENDER, + + ERROR, + } + + //endregion + + + +} From 1dd244e889498ac84fb227a49b2c026e1de5b90e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 18:59:19 -0500 Subject: [PATCH 33/46] Rename and reorganize render pass interfaces --- .../core/api/internal/ClientApi.java | 12 ++++++------ .../render/bufferBuilding/LodBufferContainer.java | 8 ++++---- .../render/bufferBuilding/LodQuadBuilder.java | 5 ++--- .../core/level/AbstractDhLevel.java | 4 ++-- .../core/level/ClientLevelModule.java | 8 ++++---- .../distanthorizons/core/level/DhClientLevel.java | 4 ++-- .../core/level/DhClientServerLevel.java | 4 ++-- .../distanthorizons/core/level/DhServerLevel.java | 4 ++-- .../distanthorizons/core/level/IDhLevel.java | 4 ++-- .../distanthorizons/core/logging/f3/F3Screen.java | 4 ++-- .../core/render/QuadTree/LodQuadTree.java | 4 ++-- .../distanthorizons/core/render/RenderParams.java | 4 ++-- .../core/render/renderer/BeaconRenderHandler.java | 4 ++-- .../core/render/renderer/BlazeLodRenderer.java | 14 +++++++------- .../core/render/renderer/CloudRenderHandler.java | 6 +++--- .../core/wrapperInterfaces/IWrapperFactory.java | 12 ++++++------ .../IDhGenericObjectVertexBufferContainer.java} | 4 ++-- .../ILodContainerUniformBufferWrapper.java | 2 +- .../{ => objects}/IUniformBufferWrapper.java | 2 +- .../render/{ => objects}/IVertexBufferWrapper.java | 2 +- .../IDhFarFadeRenderer.java} | 4 ++-- .../IDhFogRenderer.java} | 4 ++-- .../IDhGenericRenderer.java} | 4 ++-- .../IDhSsaoRenderer.java} | 6 ++---- .../IDhTerrainRenderer.java} | 4 ++-- .../IDhTestTriangleRenderer.java} | 4 ++-- .../IDhVanillaFadeRenderer.java} | 4 ++-- 27 files changed, 69 insertions(+), 72 deletions(-) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IGenericObjectVertexBufferContainer.java => objects/IDhGenericObjectVertexBufferContainer.java} (85%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{ => objects}/ILodContainerUniformBufferWrapper.java (99%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{ => objects}/IUniformBufferWrapper.java (99%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{ => objects}/IVertexBufferWrapper.java (99%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcFarFadeRenderer.java => renderPass/IDhFarFadeRenderer.java} (93%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcFogRenderer.java => renderPass/IDhFogRenderer.java} (94%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcGenericRenderer.java => renderPass/IDhGenericRenderer.java} (94%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcSsaoRenderer.java => renderPass/IDhSsaoRenderer.java} (84%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcLodRenderer.java => renderPass/IDhTerrainRenderer.java} (95%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcTestRenderer.java => renderPass/IDhTestTriangleRenderer.java} (92%) rename core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/{IMcVanillaFadeRenderer.java => renderPass/IDhVanillaFadeRenderer.java} (94%) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 132598e0a..fe779bd18 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -40,8 +40,8 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcVanillaFadeRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcTestRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage; @@ -621,14 +621,14 @@ public class ClientApi } else { - IMcTestRenderer testRenderer = SingletonInjector.INSTANCE.get(IMcTestRenderer.class); + IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class); if (testRenderer != null) { testRenderer.render(); } else { - RATE_LIMITED_LOGGER.warn("Unable to find singleton ["+IMcTestRenderer.class.getSimpleName()+"]"); + RATE_LIMITED_LOGGER.warn("Unable to find singleton ["+ IDhTestTriangleRenderer.class.getSimpleName()+"]"); } } } @@ -666,7 +666,7 @@ public class ClientApi */ public void renderFadeOpaque() { - IMcVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcVanillaFadeRenderer.class); + IDhVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IDhVanillaFadeRenderer.class); if (fadeRenderer == null) { return; @@ -695,7 +695,7 @@ public class ClientApi */ public void renderFadeTransparent() { - IMcVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IMcVanillaFadeRenderer.class); + IDhVanillaFadeRenderer fadeRenderer = SingletonInjector.INSTANCE.get(IDhVanillaFadeRenderer.class); if (fadeRenderer == null) { return; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index d3a15ecc5..60933fd64 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -27,9 +27,9 @@ import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; import org.lwjgl.system.MemoryUtil; import java.nio.ByteBuffer; @@ -215,7 +215,7 @@ public class LodBufferContainer implements AutoCloseable } IVertexBufferWrapper vbo = vbos[vboIndex]; - IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); + IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); ByteBuffer buffer = byteBuffers.get(i); int size = buffer.limit() - buffer.position(); 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 c2c3c112a..4c6b87e44 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 @@ -32,9 +32,8 @@ import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.util.ColorUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcLodRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; -import com.seibel.distanthorizons.coreapi.util.MathUtil; import org.lwjgl.system.MemoryUtil; /** @@ -490,7 +489,7 @@ public class LodQuadBuilder return maxBufferByteSize; } - IMcLodRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); + IDhTerrainRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); /** number of bytes a single quad takes */ int QUADS_BYTE_SIZE = LOD_RENDERER.getVertexByteSize() * 4; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java index fd6c817f2..74675a3b8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/AbstractDhLevel.java @@ -38,7 +38,7 @@ import com.seibel.distanthorizons.core.sql.repo.ChunkHashRepo; import com.seibel.distanthorizons.core.util.KeyedLockContainer; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.core.logging.DhLogger; import org.jetbrains.annotations.Nullable; @@ -118,7 +118,7 @@ public abstract class AbstractDhLevel implements IDhLevel /** handles any setup that needs the repos to be created */ protected void runRepoReliantSetup() { - IMcGenericRenderer genericRenderer = this.getGenericRenderer(); + IDhGenericRenderer genericRenderer = this.getGenericRenderer(); if (genericRenderer != null) { // only client levels can render clouds diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java index 65ee554c0..a163a3f2a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java @@ -31,7 +31,7 @@ import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -53,12 +53,12 @@ public class ClientLevelModule implements Closeable, IDataSourceUpdateListenerFu public final AtomicReference ClientRenderStateRef = new AtomicReference<>(); /** * This is handled outside of the {@link ClientRenderState} to prevent destroying - * the {@link IMcGenericRenderer} when changing render distances or enabling/disabling rendering.

+ * the {@link IDhGenericRenderer} when changing render distances or enabling/disabling rendering.

* - * Destroying the {@link IMcGenericRenderer} would cause any existing bindings to be + * Destroying the {@link IDhGenericRenderer} would cause any existing bindings to be * erroneously removed. */ - public final IMcGenericRenderer genericRenderer = WRAPPER_FACTORY.createGenericRenderer(); + public final IDhGenericRenderer genericRenderer = WRAPPER_FACTORY.createGenericRenderer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java index c6e22e3a4..c39c50fc7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientLevel.java @@ -40,7 +40,7 @@ import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.sql.dto.FullDataSourceV2DTO; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import org.jetbrains.annotations.NotNull; @@ -296,7 +296,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel public ISaveStructure getSaveStructure() { return this.saveStructure; } @Override - public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } + public IDhGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } @Override public RenderBufferHandler getRenderBufferHandler() { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java index ce1c1541c..5dfb921ea 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhClientServerLevel.java @@ -25,7 +25,7 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManager; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import org.jetbrains.annotations.Nullable; @@ -134,7 +134,7 @@ public class DhClientServerLevel extends AbstractDhServerLevel implements IDhCli @Override - public IMcGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } + public IDhGenericRenderer getGenericRenderer() { return this.clientside.genericRenderer; } @Override public RenderBufferHandler getRenderBufferHandler() { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java index 0f6a833d6..c12b735b1 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java @@ -23,7 +23,7 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerStateManager; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.RenderBufferHandler; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import java.io.IOException; @@ -68,7 +68,7 @@ public class DhServerLevel extends AbstractDhServerLevel //=========// @Override - public IMcGenericRenderer getGenericRenderer() + public IDhGenericRenderer getGenericRenderer() { // server-only levels don't support rendering return null; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java index 702269eae..d54e04770 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/IDhLevel.java @@ -30,7 +30,7 @@ import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO; import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,7 +92,7 @@ public interface IDhLevel extends AutoCloseable, GeneratedFullDataSourceProvider * Not supported on the server-side. */ @Nullable - IMcGenericRenderer getGenericRenderer(); + IDhGenericRenderer getGenericRenderer(); /** * Will return null if the renderer isn't set up yet.
* Not supported on the server-side. diff --git a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java index 84a538ccd..2bc9a08bf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java @@ -35,7 +35,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.util.StringUtil; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -202,7 +202,7 @@ public class F3Screen } // Generic rendering - IMcGenericRenderer genericRenderer = level.getGenericRenderer(); + IDhGenericRenderer genericRenderer = level.getGenericRenderer(); if (genericRenderer != null) { messageList.add(genericRenderer.getVboRenderDebugMenuString()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java index 75eb7fe38..44949cd20 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java @@ -44,7 +44,7 @@ import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode; import com.seibel.distanthorizons.core.util.objects.quadTree.QuadTree; import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.coreapi.util.MathUtil; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongIterator; @@ -145,7 +145,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen this.fullDataSourceProvider = fullDataSourceProvider; this.blockRenderDistanceDiameter = viewDiameterInBlocks; - IMcGenericRenderer genericObjectRenderer = this.level.getGenericRenderer(); + IDhGenericRenderer genericObjectRenderer = this.level.getGenericRenderer(); this.beaconRenderHandler = (genericObjectRenderer != null) ? new BeaconRenderHandler(genericObjectRenderer) : null; Config.Common.WorldGenerator.enableDistantGeneration.addListener(this); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java index 98ce8e75f..81ada6cbc 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java @@ -17,7 +17,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftCli import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; /** @@ -40,7 +40,7 @@ public class RenderParams extends DhApiRenderParam public IClientLevelWrapper clientLevelWrapper; public ILightMapWrapper lightmap; public RenderBufferHandler renderBufferHandler; - public IMcGenericRenderer genericRenderer; + public IDhGenericRenderer genericRenderer; public Vec3d exactCameraPosition; /** @see DhRenderState#vanillaFogEnabled */ public boolean vanillaFogEnabled; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java index aef4e9bd1..4acdc5d01 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BeaconRenderHandler.java @@ -37,7 +37,7 @@ import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.core.logging.DhLogger; import org.jetbrains.annotations.NotNull; @@ -80,7 +80,7 @@ public class BeaconRenderHandler //=============// //region - public BeaconRenderHandler(@NotNull IMcGenericRenderer renderer) + public BeaconRenderHandler(@NotNull IDhGenericRenderer renderer) { this.activeBeaconBoxRenderGroup = GENERIC_OBJECT_FACTORY.createAbsolutePositionedGroup(ModInfo.NAME+":Beacons", new ArrayList<>(0)); this.activeBeaconBoxRenderGroup.setBlockLight(LodUtil.MAX_MC_LIGHT); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java index 0e3faa4c9..c3900521b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java @@ -32,7 +32,7 @@ import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.*; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; /** @@ -111,7 +111,7 @@ public class BlazeLodRenderer } RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; - IMcGenericRenderer genericRenderer = renderParams.genericRenderer; + IDhGenericRenderer genericRenderer = renderParams.genericRenderer; @@ -144,10 +144,10 @@ public class BlazeLodRenderer renderBufferHandler.buildRenderList(renderParams); } - IMcLodRenderer lodRenderer = SingletonInjector.INSTANCE.get(IMcLodRenderer.class); - IMcSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IMcSsaoRenderer.class); - IMcFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IMcFogRenderer.class); - IMcFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IMcFarFadeRenderer.class); + IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); + IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class); + IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class); + IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class); AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); @@ -291,7 +291,7 @@ public class BlazeLodRenderer //===============// //region - private void renderLodPass(IMcLodRenderer lodRenderer, RenderBufferHandler lodBufferHandler, RenderParams renderEventParam, boolean opaquePass, IProfilerWrapper profilerWrapper) + private void renderLodPass(IDhTerrainRenderer lodRenderer, RenderBufferHandler lodBufferHandler, RenderParams renderEventParam, boolean opaquePass, IProfilerWrapper profilerWrapper) { //===========// // rendering // diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java index 76e18d55b..e37682b1d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/CloudRenderHandler.java @@ -34,7 +34,7 @@ import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.core.logging.DhLogger; @@ -83,7 +83,7 @@ public class CloudRenderHandler = new IDhApiRenderableBoxGroup[(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1][(CLOUD_INSTANCE_RADIUS_COUNT * 2) + 1]; private final IDhClientLevel level; - private final IMcGenericRenderer renderer; + private final IDhGenericRenderer renderer; /** cached array so we don't need to re-create it each frame for each cloud group */ private final Vec3d[] cullingCorners = new Vec3d[] @@ -105,7 +105,7 @@ public class CloudRenderHandler //=============// //region - public CloudRenderHandler(IDhClientLevel level, IMcGenericRenderer renderer) + public CloudRenderHandler(IDhClientLevel level, IDhGenericRenderer renderer) { this.level = level; this.renderer = renderer; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index 376e99487..b25607dc2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -23,10 +23,10 @@ import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory; import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IGenericObjectVertexBufferContainer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.ILodContainerUniformBufferWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IMcGenericRenderer; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.IVertexBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.IBatchGeneratorEnvironmentWrapper; @@ -110,8 +110,8 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable IVertexBufferWrapper createVboWrapper(String name); ILodContainerUniformBufferWrapper createLodContainerUniformWrapper(); - IGenericObjectVertexBufferContainer createInstancedVboContainer(); + IDhGenericObjectVertexBufferContainer createInstancedVboContainer(); - IMcGenericRenderer createGenericRenderer(); + IDhGenericRenderer createGenericRenderer(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IDhGenericObjectVertexBufferContainer.java similarity index 85% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IDhGenericObjectVertexBufferContainer.java index c68d8d2b2..9a940e7b3 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IGenericObjectVertexBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IDhGenericObjectVertexBufferContainer.java @@ -1,10 +1,10 @@ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.objects; import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; import java.util.List; -public interface IGenericObjectVertexBufferContainer extends AutoCloseable +public interface IDhGenericObjectVertexBufferContainer extends AutoCloseable { void uploadDataToGpu(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/ILodContainerUniformBufferWrapper.java similarity index 99% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/ILodContainerUniformBufferWrapper.java index cda04b44b..b6f0ed0ff 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/ILodContainerUniformBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/ILodContainerUniformBufferWrapper.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.objects; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IUniformBufferWrapper.java similarity index 99% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IUniformBufferWrapper.java index feb41fd72..3553675da 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IUniformBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IUniformBufferWrapper.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.objects; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IVertexBufferWrapper.java similarity index 99% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IVertexBufferWrapper.java index ce2b74a36..b7b65b3e4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IVertexBufferWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/objects/IVertexBufferWrapper.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.objects; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFarFadeRenderer.java similarity index 93% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFarFadeRenderer.java index c3e6fa0ee..7e0b4c23f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFarFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFarFadeRenderer.java @@ -17,12 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcFarFadeRenderer extends IBindable +public interface IDhFarFadeRenderer extends IBindable { void render(RenderParams renderParams); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java similarity index 94% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java index 05a33cde9..ec978c782 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcFogRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java @@ -17,12 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcFogRenderer extends IBindable +public interface IDhFogRenderer extends IBindable { void render(DhApiMat4f modelViewProjectionMatrix, float partialTicks); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java similarity index 94% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java index a38b2ac42..0eb19a59e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcGenericRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java @@ -17,14 +17,14 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcGenericRenderer extends IDhApiCustomRenderRegister, IBindable +public interface IDhGenericRenderer extends IDhApiCustomRenderRegister, IBindable { void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java similarity index 84% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java index a3931299d..8eed4daca 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcSsaoRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java @@ -17,14 +17,12 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; -import com.seibel.distanthorizons.core.util.math.Mat4f; -import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcSsaoRenderer extends IBindable +public interface IDhSsaoRenderer extends IBindable { void render(DhApiMat4f dhProjectionMatrix); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java similarity index 95% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java index 7b02a532c..146b4b477 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.render.RenderParams; @@ -25,7 +25,7 @@ import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcLodRenderer extends IBindable +public interface IDhTerrainRenderer extends IBindable { void render( RenderParams renderEventParam, boolean opaquePass, diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java similarity index 92% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java index fbf101b7a..29eac010e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcTestRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java @@ -17,11 +17,11 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcTestRenderer extends IBindable +public interface IDhTestTriangleRenderer extends IBindable { void render(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java similarity index 94% rename from core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java index 18e49a85b..1e13f0301 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/IMcVanillaFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java @@ -17,13 +17,13 @@ * along with this program. If not, see . */ -package com.seibel.distanthorizons.core.wrapperInterfaces.render; +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IMcVanillaFadeRenderer extends IBindable +public interface IDhVanillaFadeRenderer extends IBindable { void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level); From 10b08ca116fcb41f027727af920811eb055770e8 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 19:14:21 -0500 Subject: [PATCH 34/46] Fix ClientApi profiler adding an incorrect layer --- .../seibel/distanthorizons/core/api/internal/ClientApi.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index fe779bd18..5f39d0084 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -418,7 +418,6 @@ public class ClientApi private void renderLodLayer(boolean renderingDeferredLayer) { IProfilerWrapper profiler = MC_CLIENT.getProfiler(); - profiler.pop(); // get out of "terrain" profiler.push("DH-RenderLevel"); @@ -648,7 +647,6 @@ public class ClientApi profiler.pop(); // end LOD - profiler.push("terrain"); // go back into "terrain" } ///endregion @@ -685,7 +683,6 @@ public class ClientApi && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) { fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); - //VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); } } /** @@ -716,7 +713,6 @@ public class ClientApi if (renderFade) { fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); - //VanillaFadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.partialTickTime, RENDER_STATE.clientLevelWrapper); } } } From f145444fd4d67989bb3e30d030e4ea4940fb0c31 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 20:07:31 -0500 Subject: [PATCH 35/46] fix race condition in SharedApi setup --- .../seibel/distanthorizons/core/api/internal/SharedApi.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java index 4fb7b1718..fca7fb27c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java @@ -57,7 +57,6 @@ public class SharedApi /** will be null on the server-side */ @Nullable private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); - private static final AbstractDebugWireframeRenderer DEBUG_WIREFRAME_RENDERER = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); public static final WorldChunkUpdateManager WORLD_CHUNK_UPDATE_MANAGER = WorldChunkUpdateManager.INSTANCE; // local fariable for quick access @@ -107,7 +106,9 @@ public class SharedApi { ThreadPoolUtil.shutdownThreadPools(); - DEBUG_WIREFRAME_RENDERER.clearRenderables(); + // delayed get because SharedApi will be created before the singleton has been bound + AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + debugWireframeRenderer.clearRenderables(); if (MC_RENDER != null) { From 559bad5676d492b832fa6958e3c1ca57df42f1c8 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 9 Mar 2026 20:12:40 -0500 Subject: [PATCH 36/46] Add rendering API definition --- .../api/enums/config/EDhApiRenderApi.java | 19 ++++++ .../DependencyInjector.java | 5 ++ .../distanthorizons/core/config/Config.java | 12 ++++ .../wrapperInterfaces/IWrapperFactory.java | 2 +- .../render/AbstractDhRenderApiDefinition.java | 64 +++++++++++++++++++ .../render/renderPass/IDhGenericRenderer.java | 3 +- .../assets/distanthorizons/lang/en_us.json | 6 +- 7 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java diff --git a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java new file mode 100644 index 000000000..f9c0b0c3b --- /dev/null +++ b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java @@ -0,0 +1,19 @@ +package com.seibel.distanthorizons.api.enums.config; + +import com.seibel.distanthorizons.coreapi.ModInfo; + +/** + * AUTO,
+ * OPEN_GL,
+ * BLAZE_3D,

+ * + * @since API 6.0.0 + * @version 2024-6-8 + */ +public enum EDhApiRenderApi +{ + AUTO, + OPEN_GL, + BLAZE_3D; + +} diff --git a/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/DependencyInjector.java b/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/DependencyInjector.java index dc9a4e5e6..f21673b96 100644 --- a/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/DependencyInjector.java +++ b/api/src/main/java/com/seibel/distanthorizons/coreapi/DependencyInjection/DependencyInjector.java @@ -74,6 +74,11 @@ public class DependencyInjector implements IDepe throw new IllegalStateException("The dependency [" + dependencyInterface.getSimpleName() + "] has already been bound."); } + if (dependencyImplementation == null) + { + throw new NullPointerException("Can't bind null to ["+dependencyInterface.getSimpleName()+"]"); + } + // make sure the given dependency implements the necessary interfaces boolean implementsInterface = this.checkIfClassImplements(dependencyImplementation.getClass(), dependencyInterface) || 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 0c413a863..cfe1a8f8b 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 @@ -833,6 +833,18 @@ public class Config .addListener(IgnoredDimensionCsvHandler.INSTANCE) .build(); + public static ConfigEntry renderingApi = new ConfigEntry.Builder() + .set(EDhApiRenderApi.AUTO) + .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) // can't be changed while the game is running + .comment("" + + "Options: \n" + + EDhApiRenderApi.AUTO + " \n" + + EDhApiRenderApi.OPEN_GL + " \n" + + EDhApiRenderApi.BLAZE_3D + " \n" + + "") + .build(); + + } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java index b25607dc2..d5daec17d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IWrapperFactory.java @@ -110,7 +110,7 @@ public interface IWrapperFactory extends IDhApiWrapperFactory, IBindable IVertexBufferWrapper createVboWrapper(String name); ILodContainerUniformBufferWrapper createLodContainerUniformWrapper(); - IDhGenericObjectVertexBufferContainer createInstancedVboContainer(); + IDhGenericObjectVertexBufferContainer createGenericObjectVboContainer(); IDhGenericRenderer createGenericRenderer(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java new file mode 100644 index 000000000..97de9cd2f --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java @@ -0,0 +1,64 @@ +package com.seibel.distanthorizons.core.wrapperInterfaces.render; + +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +public abstract class AbstractDhRenderApiDefinition implements IBindable +{ + //============// + // singletons // + //============// + //region + + public abstract IDhTerrainRenderer getTerrainRenderer(); + public abstract IDhSsaoRenderer getSsaoRenderer(); + public abstract IDhFogRenderer getFogRenderer(); + public abstract IDhFarFadeRenderer getFarFadeRenderer(); + public abstract AbstractDebugWireframeRenderer getDebugWireframeRenderer(); + public abstract IDhVanillaFadeRenderer getVanillaFadeRenderer(); + public abstract IDhTestTriangleRenderer getTestTriangleRenderer(); + + public void bindRenderers() + { + SingletonInjector.INSTANCE.bind(AbstractDhRenderApiDefinition.class, this); + + SingletonInjector.INSTANCE.bind(IDhTerrainRenderer.class, this.getTerrainRenderer()); + SingletonInjector.INSTANCE.bind(IDhSsaoRenderer.class, this.getSsaoRenderer()); + SingletonInjector.INSTANCE.bind(IDhFogRenderer.class, this.getFogRenderer()); + SingletonInjector.INSTANCE.bind(IDhFarFadeRenderer.class, this.getFarFadeRenderer()); + SingletonInjector.INSTANCE.bind(AbstractDebugWireframeRenderer.class, this.getDebugWireframeRenderer()); + SingletonInjector.INSTANCE.bind(IDhVanillaFadeRenderer.class, this.getVanillaFadeRenderer()); + SingletonInjector.INSTANCE.bind(IDhTestTriangleRenderer.class, this.getTestTriangleRenderer()); + } + + //endregion + + + + //===========// + // factories // + //===========// + //region + + // these methods are used by WrapperFactory + + /** + * Generic renderers are created for each level they're used in + * so we can't just define a single instance. + */ + public abstract IDhGenericRenderer createGenericRenderer(); + + public abstract IVertexBufferWrapper createVboWrapper(String name); + public abstract ILodContainerUniformBufferWrapper createLodContainerUniformWrapper(); + public abstract IDhGenericObjectVertexBufferContainer createGenericVboContainer(); + + //endregion + + + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java index 0eb19a59e..56f6cc6e5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhGenericRenderer.java @@ -22,9 +22,8 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; -import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; -public interface IDhGenericRenderer extends IDhApiCustomRenderRegister, IBindable +public interface IDhGenericRenderer extends IDhApiCustomRenderRegister { void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao); 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 9ec5075d0..d86891dbe 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -415,7 +415,11 @@ "Ignored Dimension CSV", "distanthorizons.config.client.advanced.graphics.experimental.ignoredDimensionCsv.@tooltip": "A comma separated list of dimension resource locations where DH won't render. Example: \"minecraft:the_nether,minecraft:the_end\" \n\nNote: \nSome DH settings will be disabled and/or changed to improve \nvisuals when DH rendering is disabled.", - + "distanthorizons.config.client.advanced.graphics.experimental.renderingApi": + "Rendering API", + "distanthorizons.config.client.advanced.graphics.experimental.renderingApi.@tooltip": + "", + "distanthorizons.config.client.advanced.autoUpdater": From 1b0f93db07eb071eb74294a58e6e4e6f385acf7d Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 11:40:36 -0500 Subject: [PATCH 37/46] Changes for blaze/gl rendering config --- core/build.gradle | 10 +- .../core/api/internal/ClientApi.java | 28 +- .../distanthorizons/core/config/Config.java | 3 +- .../bufferBuilding/LodBufferContainer.java | 4 +- .../render/bufferBuilding/LodQuadBuilder.java | 19 +- .../core/logging/f3/F3Screen.java | 5 + .../core/render/DhApiRenderProxy.java | 4 +- .../core/render/RenderBufferHandler.java | 4 +- .../core/render/RenderParams.java | 4 +- .../core/render/RenderThreadTaskHandler.java | 2 +- .../renderer/GenericRenderObjectFactory.java | 75 ++++ ...BlazeLodRenderer.java => LodRenderer.java} | 50 +-- .../render/renderer/RenderableBoxGroup.java | 361 ++++++++++++++++++ .../render/AbstractDhRenderApiDefinition.java | 12 + .../render/renderPass/IDhTerrainRenderer.java | 4 +- .../assets/distanthorizons/lang/en_us.json | 15 +- core/src/main/resources/shaders/standard.vert | 2 +- 17 files changed, 535 insertions(+), 67 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericRenderObjectFactory.java rename core/src/main/java/com/seibel/distanthorizons/core/render/renderer/{BlazeLodRenderer.java => LodRenderer.java} (93%) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderableBoxGroup.java diff --git a/core/build.gradle b/core/build.gradle index a2cbb828e..0af80900f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -28,15 +28,17 @@ dependencies { // All of these dependencies are in Vanilla Minecraft, but we nee implementation "org.lwjgl:lwjgl" implementation "org.lwjgl:lwjgl-assimp" implementation "org.lwjgl:lwjgl-glfw" - implementation "org.lwjgl:lwjgl-openal" - implementation "org.lwjgl:lwjgl-opengl" + // OpenGL is removed since DH now handles rendering in the "Common" project + // so we can use OpenGL for old MC versions and Blaze3D (IE Vulkan) for newer ones +// implementation "org.lwjgl:lwjgl-openal" +// implementation "org.lwjgl:lwjgl-opengl" implementation "org.lwjgl:lwjgl-stb" implementation "org.lwjgl:lwjgl-tinyfd" runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives" - runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives" - runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives" +// runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives" +// runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives" runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives" diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 5f39d0084..c21c905e8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -40,6 +40,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; @@ -595,7 +596,7 @@ public class ClientApi boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); if (!renderingCancelled) { - BlazeLodRenderer.INSTANCE.render(renderParams, profiler); + LodRenderer.INSTANCE.render(renderParams, profiler); } if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) @@ -608,7 +609,7 @@ public class ClientApi boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams); if (!renderingCancelled) { - BlazeLodRenderer.INSTANCE.renderDeferred(renderParams, profiler); + LodRenderer.INSTANCE.renderDeferred(renderParams, profiler); } @@ -620,14 +621,23 @@ public class ClientApi } else { - IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class); - if (testRenderer != null) + if (!renderingDeferredLayer) { - testRenderer.render(); - } - else - { - RATE_LIMITED_LOGGER.warn("Unable to find singleton ["+ IDhTestTriangleRenderer.class.getSimpleName()+"]"); + IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); + IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class); + if (testRenderer != null + && lodRenderer != null) + { + lodRenderer.runRenderPassSetup(renderParams); + + testRenderer.render(); + + lodRenderer.runRenderPassCleanup(renderParams); + } + else + { + RATE_LIMITED_LOGGER.warn("Unable to find singleton [" + IDhTestTriangleRenderer.class.getSimpleName() + "]"); + } } } } 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 cfe1a8f8b..f50bbc810 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 @@ -835,8 +835,9 @@ public class Config public static ConfigEntry renderingApi = new ConfigEntry.Builder() .set(EDhApiRenderApi.AUTO) - .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) // can't be changed while the game is running .comment("" + + "Requires a restart to change. \n" + + " \n" + "Options: \n" + EDhApiRenderApi.AUTO + " \n" + EDhApiRenderApi.OPEN_GL + " \n" diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java index 60933fd64..16e397082 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodBufferContainer.java @@ -215,11 +215,9 @@ public class LodBufferContainer implements AutoCloseable } IVertexBufferWrapper vbo = vbos[vboIndex]; - IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); - ByteBuffer buffer = byteBuffers.get(i); int size = buffer.limit() - buffer.position(); - int vertexCount = size / lodRenderer.getVertexByteSize(); + int vertexCount = size / LodQuadBuilder.BYTES_PER_VERTEX; try { 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 4c6b87e44..5735638d3 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 @@ -57,7 +57,8 @@ public class LodQuadBuilder private final EDhApiDebugRendering debugRenderingMode; private final EDhApiGrassSideRendering grassSideRenderingMode; - + /** the number of bytes for */ + public static final int BYTES_PER_VERTEX = 14; public static final int[][][] DIRECTION_VERTEX_IBO_QUAD = new int[][][] ///region @@ -117,6 +118,7 @@ public class LodQuadBuilder //=============// // constructor // //=============// + //region public LodQuadBuilder(boolean doTransparency, IClientLevelWrapper clientLevelWrapper) { @@ -134,6 +136,8 @@ public class LodQuadBuilder } + //endregion + //===========// @@ -482,6 +486,11 @@ public class LodQuadBuilder } private static int maxBufferByteSize = -1; + /** + * The max number of bytes we allow for a single Vertex buffer. + * If an LOD has more data than this it will be split + * up into multiple buffers. + */ public static int getMaxBufferByteSize() { if (maxBufferByteSize != -1) @@ -489,11 +498,9 @@ public class LodQuadBuilder return maxBufferByteSize; } - IDhTerrainRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); - - /** number of bytes a single quad takes */ - int QUADS_BYTE_SIZE = LOD_RENDERER.getVertexByteSize() * 4; - /** how big a single VBO can be in bytes */ + // number of bytes a single quad takes + int QUADS_BYTE_SIZE = BYTES_PER_VERTEX * 4; + // how big a single VBO can be in bytes int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE; int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java index 2bc9a08bf..49d9026ee 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java @@ -35,6 +35,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.util.StringUtil; @@ -83,6 +84,7 @@ public class F3Screen { String r = MinecraftTextFormat.RED; String y = MinecraftTextFormat.YELLOW; + String a = MinecraftTextFormat.AQUA; String cf = MinecraftTextFormat.CLEAR_FORMATTING; @@ -123,6 +125,9 @@ public class F3Screen int posX = DhSectionPos.getX(sectionPos); int posZ = DhSectionPos.getZ(sectionPos); messageList.add("LOD Pos: "+y+detailLevel+"*"+posX+","+posZ+cf); + + AbstractDhRenderApiDefinition renderApiDef = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class); + messageList.add("Rendering API: "+a+renderApiDef.getApiName()+cf); } messageList.add(""); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java index cab5d1a0c..8161540c4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java @@ -85,13 +85,13 @@ public class DhApiRenderProxy implements IDhApiRenderProxy @Override public DhApiResult getDhDepthTextureId() { - int activeTexture = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId(); + int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveDepthTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's depth texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } @Override public DhApiResult getDhColorTextureId() { - int activeTexture = BlazeLodRenderer.INSTANCE.getActiveColorTextureId(); + int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveColorTextureId(); return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index 1206c9e4b..92eaaeae8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree; import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; +import com.seibel.distanthorizons.core.render.renderer.LodRenderer; import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.DhFrustumBounds; import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.NeverCullFrustum; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; @@ -48,7 +48,7 @@ import org.joml.Matrix4fc; import java.util.ArrayList; /** - * This object tells the {@link BlazeLodRenderer} what buffers to render + * This object tells the {@link LodRenderer} what buffers to render */ public class RenderBufferHandler implements AutoCloseable { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java index 81ada6cbc..0f9f60e3b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java @@ -45,7 +45,7 @@ public class RenderParams extends DhApiRenderParam /** @see DhRenderState#vanillaFogEnabled */ public boolean vanillaFogEnabled; - public boolean validationRun = false; + public boolean hasBeenValidated = false; @@ -120,7 +120,7 @@ public class RenderParams extends DhApiRenderParam { // Note: all strings here should be constants to prevent String allocations - this.validationRun = true; + this.hasBeenValidated = true; if (!MC_CLIENT.playerExists()) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java index dc068a552..a93f6a8b9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java @@ -104,7 +104,7 @@ public class RenderThreadTaskHandler { runnable.run(); - // only try running for 4ms (240 FPS) at a time to prevent random lag spikes + // only try running for a limited amount of time to prevent lag spikes long currentTimeMs = System.currentTimeMillis(); long runDuration = currentTimeMs - startTimeMs; if (runDuration > msMaxRunTime) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericRenderObjectFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericRenderObjectFactory.java new file mode 100644 index 000000000..3e503fbb8 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericRenderObjectFactory.java @@ -0,0 +1,75 @@ +/* + * This file is part of the Distant Horizons mod + * licensed under the GNU LGPL 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 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.core.render.renderer; + +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; +import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.logging.DhLogger; + +import java.util.List; +import java.util.*; + +/** + * Handles creating {@link DhApiRenderableBox}. + * + * @see IDhApiCustomRenderRegister + * @see DhApiRenderableBox + */ +public class GenericRenderObjectFactory implements IDhApiCustomRenderObjectFactory +{ + private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + + public static final GenericRenderObjectFactory INSTANCE = new GenericRenderObjectFactory(); + + + + //=============// + // constructor // + //=============// + + private GenericRenderObjectFactory() { } + + + + //================// + // group creation // + //================// + + @Override + public IDhApiRenderableBoxGroup createForSingleBox(String resourceLocation, DhApiRenderableBox box) + { + ArrayList list = new ArrayList<>(); + list.add(box); + return this.createAbsolutePositionedGroup(resourceLocation, list); + } + + @Override + public IDhApiRenderableBoxGroup createRelativePositionedGroup(String resourceLocation, DhApiVec3d originBlockPos, List boxList) + { return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(originBlockPos.x, originBlockPos.y, originBlockPos.z), boxList, true); } + + @Override + public IDhApiRenderableBoxGroup createAbsolutePositionedGroup(String resourceLocation, List boxList) + { return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(0, 0, 0), boxList, false); } + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java similarity index 93% rename from core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java rename to core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index c3900521b..833d7dcc8 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/BlazeLodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -39,7 +39,7 @@ import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; * This is where all the magic happens.
* This is where LODs are draw to the world. */ -public class BlazeLodRenderer +public class LodRenderer { public static final DhLogger LOGGER = new DhLoggerBuilder() .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) @@ -52,19 +52,22 @@ public class BlazeLodRenderer private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - public static final BlazeLodRenderer INSTANCE = new BlazeLodRenderer(); + public static final LodRenderer INSTANCE = new LodRenderer(); - private boolean renderObjectsCreated = false; + private boolean vanillaSettingsOverridden = false; //=============// // constructor // //=============// + //region - private BlazeLodRenderer() { } + private LodRenderer() { } + + //endregion @@ -105,7 +108,7 @@ public class BlazeLodRenderer boolean firstPass = !runningDeferredPass; // RenderParams parameter validation should be done before this - if (!renderParams.validationRun) + if (!renderParams.hasBeenValidated) { throw new IllegalArgumentException("Render parameters validation"); } @@ -113,6 +116,11 @@ public class BlazeLodRenderer RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; IDhGenericRenderer genericRenderer = renderParams.genericRenderer; + IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); + IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class); + IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class); + IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class); + AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); //=================// @@ -122,7 +130,9 @@ public class BlazeLodRenderer ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams); profiler.push("LOD GL setup"); - if (!this.renderObjectsCreated) + lodRenderer.runRenderPassSetup(renderParams); + + if (!this.vanillaSettingsOverridden) { // only do this once, that way they can still be reverted if desired if (Config.Client.Advanced.Graphics.overrideVanillaGraphicsSettings.get()) @@ -134,7 +144,7 @@ public class BlazeLodRenderer MC.disableFabulousTransparency(); } - this.renderObjectsCreated = true; + this.vanillaSettingsOverridden = true; } if (firstPass) @@ -144,12 +154,6 @@ public class BlazeLodRenderer renderBufferHandler.buildRenderList(renderParams); } - IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); - IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class); - IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class); - IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class); - AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); - //===========// @@ -274,6 +278,8 @@ public class BlazeLodRenderer profiler.popPush("LOD cleanup"); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams); + lodRenderer.runRenderPassCleanup(renderParams); + // end of internal LOD profiling @@ -310,22 +316,4 @@ public class BlazeLodRenderer - //===============// - // API functions // - //===============// - //region - - /** @return -1 if no frame buffer has been bound yet */ - public int getActiveFramebufferId() { return -1; } - - /** @return -1 if no texture has been bound yet */ - public int getActiveColorTextureId() { return -1; } - - /** @return -1 if no texture has been bound yet */ - public int getActiveDepthTextureId() { return -1; } - - //endregion - - - } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderableBoxGroup.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderableBoxGroup.java new file mode 100644 index 000000000..d935949cc --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/RenderableBoxGroup.java @@ -0,0 +1,361 @@ +package com.seibel.distanthorizons.core.render.renderer; + +import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup; +import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; +import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; +import com.seibel.distanthorizons.core.logging.DhLogger; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; +import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; +import com.seibel.distanthorizons.core.util.LodUtil; +import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; +import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; +import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; +import org.jetbrains.annotations.Nullable; + +import java.io.Closeable; +import java.util.*; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Stream; + +public class RenderableBoxGroup + extends AbstractList + implements IDhApiRenderableBoxGroup, Closeable +{ + private static final DhLogger LOGGER = new DhLoggerBuilder().build(); + + private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); + + public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0); + + + + public final long id; + + public final String resourceLocationNamespace; + public final String resourceLocationPath; + + /** If false the boxes will be positioned relative to the level's origin */ + public final boolean positionBoxesRelativeToGroupOrigin; + + private final List boxList; + /** backup list which allows for uploading the boxes even it the main list is being modified on a different thread. */ + private final List uploadBoxList; + private final DhApiVec3d originBlockPos; + + + public boolean active = true; + public boolean ssaoEnabled = true; + private boolean vertexDataDirty = true; + + public byte skyLight = LodUtil.MAX_MC_LIGHT; + public byte blockLight = LodUtil.MIN_MC_LIGHT; + public DhApiRenderableBoxGroupShading shading = DhApiRenderableBoxGroupShading.getDefaultShaded(); + + @Nullable + public Consumer beforeRenderFunc; + public Consumer afterRenderFunc; + + // instance data + public IDhGenericObjectVertexBufferContainer vertexBufferContainer = WRAPPER_FACTORY.createGenericObjectVboContainer(); + /** double buffering for thread safety and to prevent locking the render thread during update */ + private IDhGenericObjectVertexBufferContainer altVertexBufferContainer = WRAPPER_FACTORY.createGenericObjectVboContainer(); + + + + //=================// + // getters/setters // + //=================// + //region + + @Override + public long getId() { return this.id; } + + @Override + public String getResourceLocationNamespace() { return this.resourceLocationNamespace; } + @Override + public String getResourceLocationPath() { return this.resourceLocationPath; } + + @Override + public void setOriginBlockPos(DhApiVec3d pos) + { + this.originBlockPos.x = pos.x; + this.originBlockPos.y = pos.y; + this.originBlockPos.z = pos.z; + } + + @Override + public DhApiVec3d getOriginBlockPos() { return new DhApiVec3d(this.originBlockPos.x, this.originBlockPos.y, this.originBlockPos.z); } + + + @Override + public void setSkyLight(int skyLight) + { + if (skyLight < LodUtil.MIN_MC_LIGHT + || skyLight > LodUtil.MAX_MC_LIGHT) + { + throw new IllegalArgumentException("Sky light ["+skyLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive)."); + } + this.skyLight = (byte)skyLight; + } + @Override + public int getSkyLight() { return this.skyLight; } + + @Override + public void setBlockLight(int blockLight) + { + if (blockLight < LodUtil.MIN_MC_LIGHT + || blockLight > LodUtil.MAX_MC_LIGHT) + { + throw new IllegalArgumentException("Block light ["+blockLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive)."); + } + this.blockLight = (byte)blockLight; + } + @Override + public int getBlockLight() { return this.blockLight; } + + @Override + public void setPreRenderFunc(Consumer func) { this.beforeRenderFunc = func; } + + @Override + public void setPostRenderFunc(Consumer func) { this.afterRenderFunc = func; } + + @Override + public void setActive(boolean active) { this.active = active; } + @Override + public boolean isActive() { return this.active; } + + @Override + public void setSsaoEnabled(boolean ssaoEnabled) { this.ssaoEnabled = ssaoEnabled; } + @Override + public boolean isSsaoEnabled() { return this.ssaoEnabled; } + + @Override + public void setShading(DhApiRenderableBoxGroupShading shading) { this.shading = shading; } + @Override + public DhApiRenderableBoxGroupShading getShading() { return this.shading; } + + //endregion + + + + //=============// + // constructor // + //=============// + //region + + public RenderableBoxGroup( + String resourceLocation, + DhApiVec3d originBlockPos, List boxList, + boolean positionBoxesRelativeToGroupOrigin) throws IllegalArgumentException + { + String[] splitResourceLocation = resourceLocation.split(":"); + if (splitResourceLocation.length != 2) + { + throw new IllegalArgumentException("Resource Location must be a string that's separated by a single colon, for example: [DistantHorizons:Beacons], your namespace ["+resourceLocation+"], contains ["+(splitResourceLocation.length-1)+"] colons."); + } + + this.resourceLocationNamespace = splitResourceLocation[0]; + this.resourceLocationPath = splitResourceLocation[1]; + + this.id = NEXT_ID_ATOMIC_INT.getAndIncrement(); + this.boxList = Collections.synchronizedList(new ArrayList<>(boxList)); + this.uploadBoxList = Collections.synchronizedList(new ArrayList<>(boxList)); + + this.originBlockPos = originBlockPos; + this.positionBoxesRelativeToGroupOrigin = positionBoxesRelativeToGroupOrigin; + } + + //endregion + + + + //=================// + // render building // + //=================// + //region + + @Override + public void triggerBoxChange() { this.vertexDataDirty = true; } + + /** + * Does nothing if the vertex data is already up-to-date + * and is meaningless if using direct rendering. + */ + public void tryUpdateInstancedDataAsync() + { + // if the alt container is done, swap it in + if (this.altVertexBufferContainer.getState() == IDhGenericObjectVertexBufferContainer.EState.READY_TO_UPLOAD) + { + this.altVertexBufferContainer.uploadDataToGpu(); + + // swap VBO references for rendering + IDhGenericObjectVertexBufferContainer temp = this.vertexBufferContainer; + this.vertexBufferContainer = this.altVertexBufferContainer; + this.altVertexBufferContainer = temp; + + this.vertexDataDirty = false; + + return; + } + + + + // if the vertex data is already up to date, do nothing + if (!this.vertexDataDirty) + { + return; + } + + PriorityTaskPicker.Executor executor = ThreadPoolUtil.getRenderLoadingExecutor(); + if (executor == null || executor.isTerminated()) + { + return; + } + + // if the alternate container is already updating, don't double-queue it + if (this.altVertexBufferContainer.getState() == IDhGenericObjectVertexBufferContainer.EState.UPDATING_DATA) + { + return; + } + this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.UPDATING_DATA); + + + + //this.altInstancedVbos.tryRunRenderThreadSetup(); + + // copy over the box list so we can upload without concurrent modification issues + this.uploadBoxList.clear(); + synchronized (this.uploadBoxList) + { + this.uploadBoxList.addAll(this.boxList); + } + + try + { + executor.runTask(() -> + { + try + { + this.altVertexBufferContainer.updateVertexData(this.uploadBoxList); + } + catch (Exception e) + { + LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e); + this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.ERROR); + } + }); + } + catch (RejectedExecutionException ignore) + { + // the executor was shut down, it should be back up shortly and able to accept new jobs + this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.NEW); + } + } + + //endregion + + + + //===============// + // render events // + //===============// + //region + + /** + * This is called before every frame, even if {@link this#isActive()} returns false.
+ * {@link this#isActive()} can be changed at this point before the object is rendered to the frame. + */ + public void preRender(DhApiRenderParam renderEventParam) + { + if (this.beforeRenderFunc != null) + { + this.beforeRenderFunc.accept(renderEventParam); + } + } + /** + * Called after rendering is completed.
+ * Can be used to handle any necessary cleanup. + */ + public void postRender(DhApiRenderParam renderEventParam) + { + if (this.afterRenderFunc != null) + { + this.afterRenderFunc.accept(renderEventParam); + } + } + + //endregion + + + + //================// + // List Overrides // + //================// + //region + + @Override + public boolean add(DhApiRenderableBox box) { return this.boxList.add(box); } + @Override + public DhApiRenderableBox get(int index) { return this.boxList.get(index); } + @Override + public int size() { return this.boxList.size(); } + @Override + public boolean removeIf(Predicate filter) { return this.boxList.removeIf(filter); } + @Override + public boolean remove(Object obj) { return this.boxList.remove(obj); } + @Override + public DhApiRenderableBox remove(int index) { return this.boxList.remove(index); } + @Override + public void replaceAll(UnaryOperator operator) { this.boxList.replaceAll(operator); } + @Override + public void sort(Comparator comparator) { this.boxList.sort(comparator); } + @Override + public void forEach(Consumer action) { this.boxList.forEach(action); } + @Override + public Spliterator spliterator() { return this.boxList.spliterator(); } + @Override + public Stream stream() { return this.boxList.stream(); } + @Override + public Stream parallelStream() { return this.boxList.parallelStream(); } + @Override + public void clear() { this.boxList.clear(); } + + //endregion + + + + //================// + // base overrides // + //================// + //region + + @Override + public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:[("+this.originBlockPos.x+", "+this.originBlockPos.y+", "+this.originBlockPos.z+")], size:["+this.size()+"], active:["+this.active+"]"; } + + @Override + public void close() + { + RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() -> + { + this.vertexBufferContainer.close(); + this.altVertexBufferContainer.close(); + }); + } + + //endregion + + + +} + \ No newline at end of file diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java index 97de9cd2f..13f573fa6 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java @@ -10,6 +10,18 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab public abstract class AbstractDhRenderApiDefinition implements IBindable { + //=========// + // getters // + //=========// + //region + + /** Used for debugging */ + public abstract String getApiName(); + + //endregion + + + //============// // singletons // //============// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java index 146b4b477..ec5cb9119 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java @@ -32,10 +32,10 @@ public interface IDhTerrainRenderer extends IBindable SortedArraySet bufferContainers, IProfilerWrapper profiler); - @Deprecated // TODO put somewhere else - int getVertexByteSize(); // TODO should these go somewhere else? + void runRenderPassSetup(RenderParams renderParams); + void runRenderPassCleanup(RenderParams renderParams); void applyToMcTexture(); void clearDepth(); void clearColor(); 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 d86891dbe..4a885828b 100644 --- a/core/src/main/resources/assets/distanthorizons/lang/en_us.json +++ b/core/src/main/resources/assets/distanthorizons/lang/en_us.json @@ -418,7 +418,7 @@ "distanthorizons.config.client.advanced.graphics.experimental.renderingApi": "Rendering API", "distanthorizons.config.client.advanced.graphics.experimental.renderingApi.@tooltip": - "", + "Requires a restart to change.", @@ -1044,7 +1044,7 @@ "distanthorizons.config.enum.EDhApiRendererMode.DEFAULT": "Default", "distanthorizons.config.enum.EDhApiRendererMode.DEBUG": - "Debug", + "Debug Triangle", "distanthorizons.config.enum.EDhApiRendererMode.DISABLED": "Disabled", @@ -1121,6 +1121,15 @@ "distanthorizons.config.enum.EDhApiGrassSideRendering.FADE_TO_DIRT": "Fade To Dirt", "distanthorizons.config.enum.EDhApiGrassSideRendering.AS_DIRT": - "As Dirt" + "As Dirt", + + "distanthorizons.config.enum.EDhApiRenderApi.AUTO": + "Auto", + "distanthorizons.config.enum.EDhApiRenderApi.OPEN_GL": + "OpenGL", + "distanthorizons.config.enum.EDhApiRenderApi.BLAZE_3D": + "Blaze3D" + + } diff --git a/core/src/main/resources/shaders/standard.vert b/core/src/main/resources/shaders/standard.vert index 86393a15e..1117af78e 100644 --- a/core/src/main/resources/shaders/standard.vert +++ b/core/src/main/resources/shaders/standard.vert @@ -68,7 +68,7 @@ void main() uint lights = meta & 0xFFu; float skyLight = (float(lights/16u)+0.5) / 16.0; float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0; - vertexColor = vec4(1.0); //vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); + vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0); if (!uIsWhiteWorld) { From 0362d89173523c21bf198e6a7481a8bb75d23290 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 14:50:53 -0500 Subject: [PATCH 38/46] Separate out some rendering logic --- .../core/api/internal/ClientApi.java | 11 ++- .../core/render/renderer/LodRenderer.java | 81 +++++++++++++------ .../render/AbstractDhRenderApiDefinition.java | 2 + .../render/renderPass/IDhMetaRenderer.java | 17 ++++ .../render/renderPass/IDhTerrainRenderer.java | 8 -- 5 files changed, 84 insertions(+), 35 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index c21c905e8..de413fa23 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -40,6 +40,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair; import com.seibel.distanthorizons.core.util.objects.RollingAverage; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer; @@ -623,16 +624,18 @@ public class ClientApi { if (!renderingDeferredLayer) { - IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); + IDhMetaRenderer metaRenderer = SingletonInjector.INSTANCE.get(IDhMetaRenderer.class); IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class); if (testRenderer != null - && lodRenderer != null) + && metaRenderer != null) { - lodRenderer.runRenderPassSetup(renderParams); + // meta renderer needed for render state/texture + // for setup on some APIs (IE openGL) + metaRenderer.runRenderPassSetup(renderParams); testRenderer.render(); - lodRenderer.runRenderPassCleanup(renderParams); + metaRenderer.runRenderPassCleanup(renderParams); } else { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 833d7dcc8..158c56447 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -55,8 +55,15 @@ public class LodRenderer public static final LodRenderer INSTANCE = new LodRenderer(); - private boolean vanillaSettingsOverridden = false; + private boolean renderersBound = false; + + private IDhMetaRenderer metaRenderer; + private IDhTerrainRenderer terrainRenderer; + private IDhSsaoRenderer ssaoRenderer; + private IDhFogRenderer fogRenderer; + private IDhFarFadeRenderer farFadeRenderer; + private AbstractDebugWireframeRenderer debugWireframeRenderer; @@ -67,6 +74,16 @@ public class LodRenderer private LodRenderer() { } + private void bindRenderers() + { + this.metaRenderer = SingletonInjector.INSTANCE.get(IDhMetaRenderer.class); + this.terrainRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); + this.ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class); + this.fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class); + this.farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class); + this.debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); + } + //endregion @@ -98,6 +115,7 @@ public class LodRenderer //====================// // validate rendering // //====================// + //region boolean deferTransparentRendering = DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); if (runningDeferredPass @@ -113,24 +131,29 @@ public class LodRenderer throw new IllegalArgumentException("Render parameters validation"); } - RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; - IDhGenericRenderer genericRenderer = renderParams.genericRenderer; + //endregion - IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class); - IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class); - IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class); - IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class); - AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class); //=================// // rendering setup // //=================// + //region ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams); profiler.push("LOD GL setup"); - lodRenderer.runRenderPassSetup(renderParams); + if (!this.renderersBound) + { + this.bindRenderers(); + this.renderersBound = true; + } + + RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler; + IDhGenericRenderer genericRenderer = renderParams.genericRenderer; + + + this.metaRenderer.runRenderPassSetup(renderParams); if (!this.vanillaSettingsOverridden) { @@ -149,11 +172,13 @@ public class LodRenderer if (firstPass) { - // we only need to sort/cull the LODs during the first frame + // we only need to sort/cull the LODs at the start of the frame profiler.popPush("LOD build render list"); renderBufferHandler.buildRenderList(renderParams); } + //endregion + //===========// @@ -162,8 +187,8 @@ public class LodRenderer if (!runningDeferredPass) { - lodRenderer.clearColor(); - lodRenderer.clearDepth(); + this.metaRenderer.clearDhDepthAndColorTextures(renderParams); + //=========================// @@ -174,7 +199,7 @@ public class LodRenderer // opaque LODs profiler.popPush("LOD Opaque"); - this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ true, profiler); + this.renderLodPass(this.terrainRenderer, renderBufferHandler, renderParams, /*opaquePass*/ true, profiler); // custom objects with SSAO if (Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.get()) @@ -187,7 +212,7 @@ public class LodRenderer if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get()) { profiler.popPush("LOD SSAO"); - ssaoRenderer.render(renderParams.dhProjectionMatrix); + this.ssaoRenderer.render(renderParams.dhProjectionMatrix); } // custom objects without SSAO @@ -202,14 +227,14 @@ public class LodRenderer && Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) { profiler.popPush("LOD Transparent"); - this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); + this.renderLodPass(this.terrainRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); } // far plane clip fading if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get()) { profiler.popPush("Fade Far Clip Fade"); - farFadeRenderer.render(renderParams); + this.farFadeRenderer.render(renderParams); } // fog @@ -222,7 +247,7 @@ public class LodRenderer Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); combinedMatrix.multiply(renderParams.dhModelViewMatrix); - fogRenderer.render(combinedMatrix, renderParams.partialTicks); + this.fogRenderer.render(combinedMatrix, renderParams.partialTicks); } @@ -236,11 +261,21 @@ public class LodRenderer profiler.popPush("Debug wireframes"); // Note: this can be very slow if a lot of boxes are being rendered - debugWireframeRenderer.renderPass(renderParams); + this.debugWireframeRenderer.renderPass(renderParams); } - profiler.popPush("Apply to MC"); - lodRenderer.applyToMcTexture(); + + + //=============================// + // Apply to the MC Framebuffer // + //=============================// + + boolean cancelApplyShader = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeApplyShaderRenderEvent.class, renderParams); + if (!cancelApplyShader) + { + profiler.popPush("Apply to MC"); + this.metaRenderer.applyToMcTexture(); + } } else @@ -252,7 +287,7 @@ public class LodRenderer if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled) { profiler.popPush("LOD Transparent"); - this.renderLodPass(lodRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); + this.renderLodPass(this.terrainRenderer, renderBufferHandler, renderParams, /*opaquePass*/ false, profiler); if (Config.Client.Advanced.Graphics.Fog.enableDhFog.get() @@ -264,7 +299,7 @@ public class LodRenderer Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); combinedMatrix.multiply(renderParams.dhModelViewMatrix); - fogRenderer.render(combinedMatrix, renderParams.partialTicks); + this.fogRenderer.render(combinedMatrix, renderParams.partialTicks); } } } @@ -278,7 +313,7 @@ public class LodRenderer profiler.popPush("LOD cleanup"); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams); - lodRenderer.runRenderPassCleanup(renderParams); + this.metaRenderer.runRenderPassCleanup(renderParams); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java index 13f573fa6..1d77eb5dd 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/AbstractDhRenderApiDefinition.java @@ -27,6 +27,7 @@ public abstract class AbstractDhRenderApiDefinition implements IBindable //============// //region + public abstract IDhMetaRenderer getMetaRenderer(); public abstract IDhTerrainRenderer getTerrainRenderer(); public abstract IDhSsaoRenderer getSsaoRenderer(); public abstract IDhFogRenderer getFogRenderer(); @@ -39,6 +40,7 @@ public abstract class AbstractDhRenderApiDefinition implements IBindable { SingletonInjector.INSTANCE.bind(AbstractDhRenderApiDefinition.class, this); + SingletonInjector.INSTANCE.bind(IDhMetaRenderer.class, this.getMetaRenderer()); SingletonInjector.INSTANCE.bind(IDhTerrainRenderer.class, this.getTerrainRenderer()); SingletonInjector.INSTANCE.bind(IDhSsaoRenderer.class, this.getSsaoRenderer()); SingletonInjector.INSTANCE.bind(IDhFogRenderer.class, this.getFogRenderer()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java new file mode 100644 index 000000000..fd471a312 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java @@ -0,0 +1,17 @@ +package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; + +import com.seibel.distanthorizons.core.render.RenderParams; +import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; + +/** + * Contains anything that's shared between + * render passes or doesn't cleanly fit into another render pass interface. + */ +public interface IDhMetaRenderer extends IBindable +{ + void runRenderPassSetup(RenderParams renderParams); + void runRenderPassCleanup(RenderParams renderParams); + void applyToMcTexture(); + void clearDhDepthAndColorTextures(RenderParams renderParams); + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java index ec5cb9119..e9b257f4e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTerrainRenderer.java @@ -32,12 +32,4 @@ public interface IDhTerrainRenderer extends IBindable SortedArraySet bufferContainers, IProfilerWrapper profiler); - - // TODO should these go somewhere else? - void runRenderPassSetup(RenderParams renderParams); - void runRenderPassCleanup(RenderParams renderParams); - void applyToMcTexture(); - void clearDepth(); - void clearColor(); - } From 5b0bf59f00d52b72a65e09459a2d6c31242fbc42 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 16:44:32 -0500 Subject: [PATCH 39/46] fix iris rendering --- .../distanthorizons/api/enums/config/EDhApiRenderApi.java | 2 +- .../distanthorizons/core/render/DhApiRenderProxy.java | 8 +++++--- .../distanthorizons/core/render/renderer/LodRenderer.java | 8 +++++--- .../core/wrapperInterfaces/IVersionConstants.java | 3 +++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java index f9c0b0c3b..9f1de8bca 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiRenderApi.java @@ -8,7 +8,7 @@ import com.seibel.distanthorizons.coreapi.ModInfo; * BLAZE_3D,

* * @since API 6.0.0 - * @version 2024-6-8 + * @version 2026-3-10 */ public enum EDhApiRenderApi { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java index 8161540c4..a76c1e253 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/DhApiRenderProxy.java @@ -25,7 +25,6 @@ import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.level.IDhClientLevel; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.world.AbstractDhWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; @@ -82,16 +81,19 @@ public class DhApiRenderProxy implements IDhApiRenderProxy } + public static int activeOpenGlDhDepthTextureId = -1; @Override public DhApiResult getDhDepthTextureId() { - int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveDepthTextureId(); + int activeTexture = activeOpenGlDhDepthTextureId; return (activeTexture == -1) ? DhApiResult.createFail("DH's depth texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } + + public static int activeOpenGlDhColorTextureId = -1; @Override public DhApiResult getDhColorTextureId() { - int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveColorTextureId(); + int activeTexture = activeOpenGlDhColorTextureId; return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 158c56447..750c3a0ad 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.render.renderer; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; +import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; @@ -32,6 +33,7 @@ import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; @@ -51,6 +53,7 @@ public class LodRenderer .build(); private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); public static final LodRenderer INSTANCE = new LodRenderer(); @@ -231,7 +234,8 @@ public class LodRenderer } // far plane clip fading - if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get()) + if (Config.Client.Advanced.Graphics.Quality.dhFadeFarClipPlane.get() + && IRIS_ACCESSOR == null) { profiler.popPush("Fade Far Clip Fade"); this.farFadeRenderer.render(renderParams); @@ -325,8 +329,6 @@ public class LodRenderer - - //===============// // LOD rendering // //===============// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java index 37ebd5910..d2e24edd2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces; +import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; /** @@ -33,4 +34,6 @@ public interface IVersionConstants extends IBindable { String getMinecraftVersion(); + EDhApiRenderApi getDefaultRenderer(); + } From 9e7d0a15386986c3cb172ecdb3f2c9aef98ecc04 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 16:58:57 -0500 Subject: [PATCH 40/46] method rename --- .../core/wrapperInterfaces/IVersionConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java index d2e24edd2..9c71c8071 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/IVersionConstants.java @@ -34,6 +34,6 @@ public interface IVersionConstants extends IBindable { String getMinecraftVersion(); - EDhApiRenderApi getDefaultRenderer(); + EDhApiRenderApi getDefaultRenderingApi(); } From b51ab3d9cd5bfeb2b81beb884a6b9b25935444ce Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 17:03:13 -0500 Subject: [PATCH 41/46] clear up render task logging --- .../distanthorizons/core/render/RenderThreadTaskHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java index a93f6a8b9..4e96ef586 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderThreadTaskHandler.java @@ -14,8 +14,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; public class RenderThreadTaskHandler { public static final DhLogger LOGGER = new DhLoggerBuilder() - .fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile) - .chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat) + .fileLevelConfig(Config.Common.Logging.logRendererEventToFile) .build(); private static final ConcurrentLinkedQueue RENDER_THREAD_RUNNABLE_QUEUE = new ConcurrentLinkedQueue<>(); From 4e908b5b156e338f18589d20574ddc654d1bea97 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 17:20:19 -0500 Subject: [PATCH 42/46] Make render interfaces consistent --- .../core/api/internal/ClientApi.java | 8 +++++--- .../core/render/renderer/LodRenderer.java | 14 ++++---------- .../render/renderPass/IDhFogRenderer.java | 4 ++-- .../render/renderPass/IDhMetaRenderer.java | 2 +- .../render/renderPass/IDhSsaoRenderer.java | 3 ++- .../render/renderPass/IDhTestTriangleRenderer.java | 3 ++- .../render/renderPass/IDhVanillaFadeRenderer.java | 3 ++- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index de413fa23..4d2be380d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -633,7 +633,7 @@ public class ClientApi // for setup on some APIs (IE openGL) metaRenderer.runRenderPassSetup(renderParams); - testRenderer.render(); + testRenderer.render(renderParams); metaRenderer.runRenderPassCleanup(renderParams); } @@ -695,7 +695,8 @@ public class ClientApi // don't fade when Iris shaders are active, otherwise the rendering can get weird && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) { - fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); + RenderParams renderParams = new RenderParams(EDhApiRenderPass.OPAQUE, RENDER_STATE); + fadeRenderer.render(renderParams); } } /** @@ -725,7 +726,8 @@ public class ClientApi && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); if (renderFade) { - fadeRenderer.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.clientLevelWrapper); + RenderParams renderParams = new RenderParams(EDhApiRenderPass.TRANSPARENT, RENDER_STATE); + fadeRenderer.render(renderParams); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 750c3a0ad..63c7e5675 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -215,7 +215,7 @@ public class LodRenderer if (Config.Client.Advanced.Graphics.Ssao.enableSsao.get()) { profiler.popPush("LOD SSAO"); - this.ssaoRenderer.render(renderParams.dhProjectionMatrix); + this.ssaoRenderer.render(renderParams); } // custom objects without SSAO @@ -248,10 +248,7 @@ public class LodRenderer { profiler.popPush("LOD Fog"); - Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - this.fogRenderer.render(combinedMatrix, renderParams.partialTicks); + this.fogRenderer.render(renderParams); } @@ -278,7 +275,7 @@ public class LodRenderer if (!cancelApplyShader) { profiler.popPush("Apply to MC"); - this.metaRenderer.applyToMcTexture(); + this.metaRenderer.applyToMcTexture(renderParams); } } @@ -300,10 +297,7 @@ public class LodRenderer { profiler.popPush("LOD Fog"); - Mat4f combinedMatrix = new Mat4f(renderParams.dhProjectionMatrix); - combinedMatrix.multiply(renderParams.dhModelViewMatrix); - - this.fogRenderer.render(combinedMatrix, renderParams.partialTicks); + this.fogRenderer.render(renderParams); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java index ec978c782..f3420ab9a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhFogRenderer.java @@ -19,12 +19,12 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; -import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IDhFogRenderer extends IBindable { - void render(DhApiMat4f modelViewProjectionMatrix, float partialTicks); + void render(RenderParams renderParams); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java index fd471a312..9bae6f931 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhMetaRenderer.java @@ -11,7 +11,7 @@ public interface IDhMetaRenderer extends IBindable { void runRenderPassSetup(RenderParams renderParams); void runRenderPassCleanup(RenderParams renderParams); - void applyToMcTexture(); + void applyToMcTexture(RenderParams renderParams); void clearDhDepthAndColorTextures(RenderParams renderParams); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java index 8eed4daca..f51e0e5ee 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhSsaoRenderer.java @@ -20,11 +20,12 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IDhSsaoRenderer extends IBindable { - void render(DhApiMat4f dhProjectionMatrix); + void render(RenderParams renderParams); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java index 29eac010e..ea2392432 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhTestTriangleRenderer.java @@ -19,11 +19,12 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; public interface IDhTestTriangleRenderer extends IBindable { - void render(); + void render(RenderParams renderParams); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java index 1e13f0301..7bb325a0c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/render/renderPass/IDhVanillaFadeRenderer.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass; +import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable; @@ -26,6 +27,6 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab public interface IDhVanillaFadeRenderer extends IBindable { - void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, IClientLevelWrapper level); + void render(RenderParams renderParams); } From e426fc238022d8f4c584e6ff6d505a62564ebcab Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 17:33:55 -0500 Subject: [PATCH 43/46] Move lightmap wrapper methods into common --- .../core/wrapperInterfaces/misc/ILightMapWrapper.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java index b270d1b0e..06e237741 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/misc/ILightMapWrapper.java @@ -27,7 +27,5 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab */ public interface ILightMapWrapper extends IBindable { - void bind(); - void unbind(); } From 1bbe41c0685546fa91c95ddd265fac78949ff43b Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 17:56:05 -0500 Subject: [PATCH 44/46] move GL shaders into the correct folder --- .../shaders/debug/gl}/frag.frag | 0 .../shaders/debug/gl}/vert.vert | 0 .../shaders/fade/gl}/apply.frag | 0 .../shaders/fade/gl}/dhFade.frag | 0 .../shaders/fade/gl}/vanillaFade.frag | 0 .../shaders/fog/gl}/apply.frag | 0 .../distanthorizons/shaders/fog/gl}/fog.frag | 0 .../shaders/generic/gl}/direct/frag.frag | 0 .../shaders/generic/gl}/direct/vert.vert | 0 .../shaders/generic/gl}/instanced/frag.frag | 0 .../shaders/generic/gl}/instanced/vert.vert | 0 .../shaders/shared/gl}/apply.frag | 0 .../shaders/shared/gl}/flat_shaded.frag | 0 .../shaders/shared/gl}/quadApply.vert | 0 .../shaders/shared/gl}/standard.vert | 0 .../distanthorizons/shaders/ssao/gl}/ao.frag | 0 .../shaders/ssao/gl}/apply.frag | 0 .../shaders/test/gl}/frag.frag | 0 .../shaders/test/gl}/vert.vert | 0 .../main/resources/shaders/noise/noise.frag | 74 ------------------- .../src/main/resources/shaders/test/dark.frag | 9 --- 21 files changed, 83 deletions(-) rename core/src/main/resources/{shaders/debug => assets/distanthorizons/shaders/debug/gl}/frag.frag (100%) rename core/src/main/resources/{shaders/debug => assets/distanthorizons/shaders/debug/gl}/vert.vert (100%) rename core/src/main/resources/{shaders/fade => assets/distanthorizons/shaders/fade/gl}/apply.frag (100%) rename core/src/main/resources/{shaders/fade => assets/distanthorizons/shaders/fade/gl}/dhFade.frag (100%) rename core/src/main/resources/{shaders/fade => assets/distanthorizons/shaders/fade/gl}/vanillaFade.frag (100%) rename core/src/main/resources/{shaders/fog => assets/distanthorizons/shaders/fog/gl}/apply.frag (100%) rename core/src/main/resources/{shaders/fog => assets/distanthorizons/shaders/fog/gl}/fog.frag (100%) rename core/src/main/resources/{shaders/genericObject => assets/distanthorizons/shaders/generic/gl}/direct/frag.frag (100%) rename core/src/main/resources/{shaders/genericObject => assets/distanthorizons/shaders/generic/gl}/direct/vert.vert (100%) rename core/src/main/resources/{shaders/genericObject => assets/distanthorizons/shaders/generic/gl}/instanced/frag.frag (100%) rename core/src/main/resources/{shaders/genericObject => assets/distanthorizons/shaders/generic/gl}/instanced/vert.vert (100%) rename core/src/main/resources/{shaders => assets/distanthorizons/shaders/shared/gl}/apply.frag (100%) rename core/src/main/resources/{shaders => assets/distanthorizons/shaders/shared/gl}/flat_shaded.frag (100%) rename core/src/main/resources/{shaders => assets/distanthorizons/shaders/shared/gl}/quadApply.vert (100%) rename core/src/main/resources/{shaders => assets/distanthorizons/shaders/shared/gl}/standard.vert (100%) rename core/src/main/resources/{shaders/ssao => assets/distanthorizons/shaders/ssao/gl}/ao.frag (100%) rename core/src/main/resources/{shaders/ssao => assets/distanthorizons/shaders/ssao/gl}/apply.frag (100%) rename core/src/main/resources/{shaders/test => assets/distanthorizons/shaders/test/gl}/frag.frag (100%) rename core/src/main/resources/{shaders/test => assets/distanthorizons/shaders/test/gl}/vert.vert (100%) delete mode 100644 core/src/main/resources/shaders/noise/noise.frag delete mode 100644 core/src/main/resources/shaders/test/dark.frag diff --git a/core/src/main/resources/shaders/debug/frag.frag b/core/src/main/resources/assets/distanthorizons/shaders/debug/gl/frag.frag similarity index 100% rename from core/src/main/resources/shaders/debug/frag.frag rename to core/src/main/resources/assets/distanthorizons/shaders/debug/gl/frag.frag diff --git a/core/src/main/resources/shaders/debug/vert.vert b/core/src/main/resources/assets/distanthorizons/shaders/debug/gl/vert.vert similarity index 100% rename from core/src/main/resources/shaders/debug/vert.vert rename to core/src/main/resources/assets/distanthorizons/shaders/debug/gl/vert.vert diff --git a/core/src/main/resources/shaders/fade/apply.frag b/core/src/main/resources/assets/distanthorizons/shaders/fade/gl/apply.frag similarity index 100% rename from core/src/main/resources/shaders/fade/apply.frag rename to core/src/main/resources/assets/distanthorizons/shaders/fade/gl/apply.frag diff --git a/core/src/main/resources/shaders/fade/dhFade.frag b/core/src/main/resources/assets/distanthorizons/shaders/fade/gl/dhFade.frag similarity index 100% rename from core/src/main/resources/shaders/fade/dhFade.frag rename to core/src/main/resources/assets/distanthorizons/shaders/fade/gl/dhFade.frag diff --git a/core/src/main/resources/shaders/fade/vanillaFade.frag b/core/src/main/resources/assets/distanthorizons/shaders/fade/gl/vanillaFade.frag similarity index 100% rename from core/src/main/resources/shaders/fade/vanillaFade.frag rename to core/src/main/resources/assets/distanthorizons/shaders/fade/gl/vanillaFade.frag diff --git a/core/src/main/resources/shaders/fog/apply.frag b/core/src/main/resources/assets/distanthorizons/shaders/fog/gl/apply.frag similarity index 100% rename from core/src/main/resources/shaders/fog/apply.frag rename to core/src/main/resources/assets/distanthorizons/shaders/fog/gl/apply.frag diff --git a/core/src/main/resources/shaders/fog/fog.frag b/core/src/main/resources/assets/distanthorizons/shaders/fog/gl/fog.frag similarity index 100% rename from core/src/main/resources/shaders/fog/fog.frag rename to core/src/main/resources/assets/distanthorizons/shaders/fog/gl/fog.frag diff --git a/core/src/main/resources/shaders/genericObject/direct/frag.frag b/core/src/main/resources/assets/distanthorizons/shaders/generic/gl/direct/frag.frag similarity index 100% rename from core/src/main/resources/shaders/genericObject/direct/frag.frag rename to core/src/main/resources/assets/distanthorizons/shaders/generic/gl/direct/frag.frag diff --git a/core/src/main/resources/shaders/genericObject/direct/vert.vert b/core/src/main/resources/assets/distanthorizons/shaders/generic/gl/direct/vert.vert similarity index 100% rename from core/src/main/resources/shaders/genericObject/direct/vert.vert rename to core/src/main/resources/assets/distanthorizons/shaders/generic/gl/direct/vert.vert diff --git a/core/src/main/resources/shaders/genericObject/instanced/frag.frag b/core/src/main/resources/assets/distanthorizons/shaders/generic/gl/instanced/frag.frag similarity index 100% rename from core/src/main/resources/shaders/genericObject/instanced/frag.frag rename to core/src/main/resources/assets/distanthorizons/shaders/generic/gl/instanced/frag.frag diff --git a/core/src/main/resources/shaders/genericObject/instanced/vert.vert b/core/src/main/resources/assets/distanthorizons/shaders/generic/gl/instanced/vert.vert similarity index 100% rename from core/src/main/resources/shaders/genericObject/instanced/vert.vert rename to core/src/main/resources/assets/distanthorizons/shaders/generic/gl/instanced/vert.vert diff --git a/core/src/main/resources/shaders/apply.frag b/core/src/main/resources/assets/distanthorizons/shaders/shared/gl/apply.frag similarity index 100% rename from core/src/main/resources/shaders/apply.frag rename to core/src/main/resources/assets/distanthorizons/shaders/shared/gl/apply.frag diff --git a/core/src/main/resources/shaders/flat_shaded.frag b/core/src/main/resources/assets/distanthorizons/shaders/shared/gl/flat_shaded.frag similarity index 100% rename from core/src/main/resources/shaders/flat_shaded.frag rename to core/src/main/resources/assets/distanthorizons/shaders/shared/gl/flat_shaded.frag diff --git a/core/src/main/resources/shaders/quadApply.vert b/core/src/main/resources/assets/distanthorizons/shaders/shared/gl/quadApply.vert similarity index 100% rename from core/src/main/resources/shaders/quadApply.vert rename to core/src/main/resources/assets/distanthorizons/shaders/shared/gl/quadApply.vert diff --git a/core/src/main/resources/shaders/standard.vert b/core/src/main/resources/assets/distanthorizons/shaders/shared/gl/standard.vert similarity index 100% rename from core/src/main/resources/shaders/standard.vert rename to core/src/main/resources/assets/distanthorizons/shaders/shared/gl/standard.vert diff --git a/core/src/main/resources/shaders/ssao/ao.frag b/core/src/main/resources/assets/distanthorizons/shaders/ssao/gl/ao.frag similarity index 100% rename from core/src/main/resources/shaders/ssao/ao.frag rename to core/src/main/resources/assets/distanthorizons/shaders/ssao/gl/ao.frag diff --git a/core/src/main/resources/shaders/ssao/apply.frag b/core/src/main/resources/assets/distanthorizons/shaders/ssao/gl/apply.frag similarity index 100% rename from core/src/main/resources/shaders/ssao/apply.frag rename to core/src/main/resources/assets/distanthorizons/shaders/ssao/gl/apply.frag diff --git a/core/src/main/resources/shaders/test/frag.frag b/core/src/main/resources/assets/distanthorizons/shaders/test/gl/frag.frag similarity index 100% rename from core/src/main/resources/shaders/test/frag.frag rename to core/src/main/resources/assets/distanthorizons/shaders/test/gl/frag.frag diff --git a/core/src/main/resources/shaders/test/vert.vert b/core/src/main/resources/assets/distanthorizons/shaders/test/gl/vert.vert similarity index 100% rename from core/src/main/resources/shaders/test/vert.vert rename to core/src/main/resources/assets/distanthorizons/shaders/test/gl/vert.vert diff --git a/core/src/main/resources/shaders/noise/noise.frag b/core/src/main/resources/shaders/noise/noise.frag deleted file mode 100644 index 6d39b6253..000000000 --- a/core/src/main/resources/shaders/noise/noise.frag +++ /dev/null @@ -1,74 +0,0 @@ -#version 150 core - -in vec4 vertexColor; -in vec4 vPos; -in vec3 vertexWorldPos; -out vec4 fragColor; - -uniform float distanceScale; - -uniform int uNoiseSteps; -uniform float uNoiseIntensity; -uniform float uNoiseDropoff; - - - -// The random functions for diffrent dimentions -float rand(float co) { return fract(sin(co*(91.3458)) * 47453.5453); } -float rand(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } -float rand(vec3 co){ return rand(co.xy+rand(co.z)); } - -// Puts steps in a float -// EG. setting stepSize to 4 then this would be the result of this function -// In: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, ..., 1.1, 1.2, 1.3 -// Out: 0.0, 0.0, 0.0, 0.25, 0.25, 0.5, 0.5, ..., 1.0, 1.0, 1.25 -float quantize(float val, int stepSize) { - return floor(val*stepSize)/stepSize; -} - -vec3 quantize(vec3 val, int stepSize) { - return floor(val*stepSize)/stepSize; -} - - -/** - * Fragment shader for adding noise to lods. - * This should be passed close to first as it affects the base color of the lod - * - * version: 2023-6-21 - */ -void main() { - // This bit of code is required to fix the vertex position problem cus of floats in the verted world position varuable - vec3 vertexNormal = normalize(cross(dFdx(vPos.xyz), dFdy(vPos.xyz))); - vec3 fixedVPos = vPos.xyz - vertexNormal * 0.001; - - - float noiseAmplification = uNoiseIntensity; - noiseAmplification = (-1 * pow(2*((vertexColor.x + vertexColor.y + vertexColor.z) / 3) - 1, 2) + 1) * noiseAmplification; // Lessen the effect on depending on how dark the object is, equasion for this is -(2x-1)^{2}+1 - noiseAmplification *= vertexColor.w; // The effect would lessen on transparent objects - - // Random value for each position - float randomValue = rand(quantize(fixedVPos.xyz, uNoiseSteps)) - * 2.0 * noiseAmplification - noiseAmplification; - - - // Modifies the color - // A value of 0 on the randomValue will result in the original color, while a value of 1 will result in a fully bright color - vec3 newCol = (1.0 - vertexColor.rgb) * randomValue; - - // Clamps it and turns it back into a vec4 - float distA = length(vertexWorldPos) * distanceScale * uNoiseDropoff; - fragColor = clamp(vec4(newCol.rgb, distA), 0.0, 1.0); // The further away it gets, the less noise gets applied - - // The further away it gets, the less noise gets applied - fragColor = vec4(0.0, 0.0, 0.0, randomValue); - - // For testing -// if (vertexColor.r != 69420.) { -// fragColor = vec4( -// mod(fixedVPos.x, 1), -// mod(fixedVPos.y, 1), -// mod(fixedVPos.z, 1), -// 1f); -// } -} \ No newline at end of file diff --git a/core/src/main/resources/shaders/test/dark.frag b/core/src/main/resources/shaders/test/dark.frag deleted file mode 100644 index ab99d05ce..000000000 --- a/core/src/main/resources/shaders/test/dark.frag +++ /dev/null @@ -1,9 +0,0 @@ -#version 150 core - -out vec4 fragColor; - -// A test shader that makes everything darker -void main() -{ - fragColor = vec4(0., 0., 1., 0.5); -} \ No newline at end of file From d75b65e6e72716f43c2879b67c4732536fbd411c Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 18:44:48 -0500 Subject: [PATCH 45/46] hide render API config from UI --- .../com/seibel/distanthorizons/core/config/Config.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 f50bbc810..258199eaa 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 @@ -835,13 +835,14 @@ public class Config public static ConfigEntry renderingApi = new ConfigEntry.Builder() .set(EDhApiRenderApi.AUTO) + .setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) // very experimental option and only supported .comment("" + "Requires a restart to change. \n" + " \n" + "Options: \n" - + EDhApiRenderApi.AUTO + " \n" - + EDhApiRenderApi.OPEN_GL + " \n" - + EDhApiRenderApi.BLAZE_3D + " \n" + + EDhApiRenderApi.AUTO + " - changes based on the most likely API for that MC version \n" + + EDhApiRenderApi.OPEN_GL + " - Default \n" + + EDhApiRenderApi.BLAZE_3D + " - Only supported on MC 1.21.11 \n" + "") .build(); From 31b6d2dd05e5b4b4368aa982a01e653ad24ab5c8 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 10 Mar 2026 19:06:02 -0500 Subject: [PATCH 46/46] Fix debug wireframes not rendering --- .../V2/FullDataUpdatePropagatorV2.java | 2 +- .../file/fullDatafile/V2/FullDataUpdaterV2.java | 4 ++-- .../core/generation/WorldGenerationQueue.java | 4 ++-- .../AbstractFullDataNetworkRequestQueue.java | 2 +- .../core/render/QuadTree/LodQuadTree.java | 2 +- .../core/render/QuadTree/LodRenderSection.java | 2 +- .../renderer/AbstractDebugWireframeRenderer.java | 15 ++++++++++++--- .../core/render/renderer/LodRenderer.java | 3 +-- 8 files changed, 21 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java index 69b01734d..e3be23690 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdatePropagatorV2.java @@ -391,7 +391,7 @@ public class FullDataUpdatePropagatorV2 implements IDebugRenderable, AutoCloseab public void debugRender(AbstractDebugWireframeRenderer renderer) { this.updatingPosSet - .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); + .forEach((pos) -> { renderer.renderBox(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f, 0.20f, Color.MAGENTA)); }); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java index 3e249d80f..75c0384d0 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/V2/FullDataUpdaterV2.java @@ -228,10 +228,10 @@ public class FullDataUpdaterV2 implements IDebugRenderable, AutoCloseable public void debugRender(AbstractDebugWireframeRenderer renderer) { this.lockedPosSet - .forEach((pos) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); + .forEach((pos) -> { renderer.renderBox(new AbstractDebugWireframeRenderer.Box(pos, -32f, 74f, 0.15f, Color.PINK)); }); this.queuedUpdateCountsByPos - .forEach((pos, updateCountRef) -> { renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); + .forEach((pos, updateCountRef) -> { renderer.renderBox(new AbstractDebugWireframeRenderer.Box(pos, -32f, 80f + (updateCountRef.get() * 16f), 0.20f, Color.WHITE)); }); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java index a05af17f8..08326a210 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java @@ -638,7 +638,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // blue - queued this.waitingTasks.keySet().forEach((Long pos) -> { - renderer.render( + renderer.renderBox( new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.blue) ); }); @@ -646,7 +646,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb // red - in progress this.inProgressGenTasksByLodPos.forEach((Long pos, DataSourceRetrievalTask task) -> { - renderer.render( + renderer.renderBox( new AbstractDebugWireframeRenderer.Box(pos, levelMinY, maxY, 0.05f, Color.red) ); }); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java index 6a76ace30..a85d28616 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java @@ -426,7 +426,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende } } - renderer.render(new AbstractDebugWireframeRenderer.Box(pos, -32f, 64f, 0.05f, color)); + renderer.renderBox(new AbstractDebugWireframeRenderer.Box(pos, -32f, 64f, 0.05f, color)); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java index 44949cd20..663df4b57 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodQuadTree.java @@ -1016,7 +1016,7 @@ public class LodQuadTree extends QuadTree implements IDebugRen int levelHeightRange = (levelMaxY - levelMinY); int maxY = levelMaxY - (levelHeightRange / 2); - debugRenderer.render(new AbstractDebugWireframeRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color)); + debugRenderer.renderBox(new AbstractDebugWireframeRenderer.Box(renderSection.pos, levelMinY, maxY, 0.05f, color)); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java index 203291073..cf138c89d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/QuadTree/LodRenderSection.java @@ -532,7 +532,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable int levelHeightRange = (levelMaxY - levelMinY); int maxY = levelMaxY - (levelHeightRange / 2); - debugRenderer.render(new AbstractDebugWireframeRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color)); + debugRenderer.renderBox(new AbstractDebugWireframeRenderer.Box(this.pos, levelMinY, maxY, 0.01f, color)); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java index 8bd7aa51f..3604c050e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/AbstractDebugWireframeRenderer.java @@ -45,7 +45,7 @@ public abstract class AbstractDebugWireframeRenderer implements IBindable //===========// //region - public void renderPass(RenderParams renderParams) + public void render(RenderParams renderParams) { this.dhMvmProjMatrixThisFrame = new Mat4f(renderParams.dhMvmProjMatrix); Vec3d camPos = MC_RENDER.getCameraExactPosition(); @@ -55,7 +55,7 @@ public abstract class AbstractDebugWireframeRenderer implements IBindable this.rendererLists.render(this); - // particle rendering + // particle cleanup BoxParticle head = null; while ((head = this.particles.poll()) != null && head.isDead()) { /* remove dead particles */ } @@ -64,9 +64,18 @@ public abstract class AbstractDebugWireframeRenderer implements IBindable // re-add the popped off head this.particles.add(head); } + + + // particle rendering + for (BoxParticle particle : this.particles) + { + // a new box is created each time since the height will be different based on the time it's lived + this.renderBox(particle.createNewRenderBox()); + } + } - public abstract void render(Box box); + public abstract void renderBox(Box box); //endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 63c7e5675..44fb46f77 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -29,7 +29,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.DhApiRenderProxy; import com.seibel.distanthorizons.core.render.RenderBufferHandler; import com.seibel.distanthorizons.core.render.RenderParams; -import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; @@ -262,7 +261,7 @@ public class LodRenderer profiler.popPush("Debug wireframes"); // Note: this can be very slow if a lot of boxes are being rendered - this.debugWireframeRenderer.renderPass(renderParams); + this.debugWireframeRenderer.render(renderParams); }