From 531f769bde603027ed5b31f559e4901495ac8d21 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Thu, 19 Sep 2024 23:08:26 +0800 Subject: [PATCH 1/6] fix #1504 and #1553 --- .../neoforge/client/ClientHooks.java | 7 +---- .../neoforge/client/gui/GuiLayerManager.java | 27 +++++++++++++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index 8bc74f258c..c0e4614f85 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -180,7 +180,6 @@ import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; import net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions; import net.neoforged.neoforge.client.gui.ClientTooltipComponentManager; -import net.neoforged.neoforge.client.gui.GuiLayerManager; import net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.common.NeoForge; @@ -247,12 +246,8 @@ public static void popGuiLayer(Minecraft minecraft) { } public static float getGuiFarPlane() { - // 11000 units for the overlay background and 10000 units for each layered Screen or 200 units for each HUD layer, whichever ends up higher - + // 11000 units for the overlay background and 10000 units for each layered Scree float depth = 10_000F * (1 + guiLayers.size()); - if (Minecraft.getInstance().level != null) { - depth = Math.max(depth, GuiLayerManager.Z_SEPARATION * Minecraft.getInstance().gui.getLayerCount()); - } return 11_000F + depth; } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java index 8d39152000..fb82138107 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java @@ -5,6 +5,8 @@ package net.neoforged.neoforge.client.gui; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.VertexFormat; import java.util.ArrayList; import java.util.List; import java.util.function.BooleanSupplier; @@ -12,6 +14,8 @@ import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.LayeredDraw; +import net.minecraft.client.renderer.RenderStateShard; +import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; @@ -69,8 +73,10 @@ private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { layer.layer().render(guiGraphics, partialTick); NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Post(guiGraphics, partialTick, layer.name(), layer.layer())); } - - guiGraphics.pose().translate(0.0F, 0.0F, Z_SEPARATION); + // clear depth values to keep hud rendered at the same depth + guiGraphics.pose().translate(0, 0, -1000); + guiGraphics.fill(LayerRenderType.GUI, 0, 0, guiGraphics.guiWidth(), guiGraphics.guiHeight(), -1); + guiGraphics.pose().translate(0, 0, 1000); } guiGraphics.pose().popPose(); @@ -87,4 +93,21 @@ public void initModdedLayers() { public int getLayerCount() { return this.layers.size(); } + + private static class LayerRenderType extends RenderType { + public static final RenderType GUI = create( + "reverse_gui", + DefaultVertexFormat.POSITION_COLOR, + VertexFormat.Mode.QUADS, + 786432, + RenderType.CompositeState.builder() + .setShaderState(RENDERTYPE_GUI_SHADER) + .setWriteMaskState(RenderStateShard.DEPTH_WRITE) + .setDepthTestState(GREATER_DEPTH_TEST) + .createCompositeState(false)); + + public LayerRenderType(String name, VertexFormat format, VertexFormat.Mode mode, int bufferSize, boolean affectsCrumbling, boolean sortOnUpload, Runnable setupState, Runnable clearState) { + super(name, format, mode, bufferSize, affectsCrumbling, sortOnUpload, setupState, clearState); + } + } } From 20614650854a899f4dea6285010a307b737f9ce1 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Sat, 28 Sep 2024 19:36:02 +0800 Subject: [PATCH 2/6] make depth clearing opt-in --- .../net/minecraft/client/gui/Gui.java.patch | 14 +++++++-- .../client/gui/LayeredDraw.java.patch | 13 +++++++++ .../neoforge/client/gui/GuiLayerManager.java | 29 +++++++++++++++---- 3 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 patches/net/minecraft/client/gui/LayeredDraw.java.patch diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index dc1055a582..a4a15d21c0 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -152,7 +152,7 @@ TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.get(holder); int l1 = i; int i1 = j; -@@ -488,29 +_,59 @@ +@@ -488,29 +_,61 @@ } } @@ -168,6 +168,8 @@ + } + + private void renderHotbar(GuiGraphics p_316628_, DeltaTracker p_348543_) { ++ // Neo: Fix bugs caused by rendering ItemStack at high z offset ++ clearDepth(p_316628_); if (this.minecraft.gameMode.getPlayerMode() == GameType.SPECTATOR) { this.spectatorGui.renderHotbar(p_316628_); } else { @@ -390,7 +392,7 @@ this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get()); } else if (this.toolHighlightTimer > 0) { this.toolHighlightTimer--; -@@ -1292,8 +_,17 @@ +@@ -1292,8 +_,25 @@ } } @@ -402,6 +404,14 @@ + public int getLayerCount() { + return this.layerManager.getLayerCount(); + } ++ ++ /** ++ * Must call this at the beginning of overlays that could render ItemStack, ++ * to prevent visual bugs when rendering ItemStack at high z offset ++ */ ++ public void clearDepth(GuiGraphics guiGraphics) { ++ this.layerManager.clearDepth(guiGraphics); ++ } + @OnlyIn(Dist.CLIENT) - public static enum HeartType { diff --git a/patches/net/minecraft/client/gui/LayeredDraw.java.patch b/patches/net/minecraft/client/gui/LayeredDraw.java.patch new file mode 100644 index 0000000000..bbf5049d13 --- /dev/null +++ b/patches/net/minecraft/client/gui/LayeredDraw.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/client/gui/LayeredDraw.java ++++ b/net/minecraft/client/gui/LayeredDraw.java +@@ -38,6 +_,10 @@ + } + } + ++ /** ++ * If this overlay could render ItemStack, it should call {@link Gui#clearDepth} at the beginning.
++ * See usage in {@link Gui#renderHotbar} ++ */ + @OnlyIn(Dist.CLIENT) + public interface Layer { + void render(GuiGraphics p_316811_, DeltaTracker p_348559_); diff --git a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java index fb82138107..b1bf9d151c 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java @@ -35,6 +35,7 @@ public class GuiLayerManager { public static final float Z_SEPARATION = LayeredDraw.Z_SEPARATION; private final List layers = new ArrayList<>(); private boolean initialized = false; + private int drawnLayerCount = -1; public record NamedLayer(ResourceLocation name, LayeredDraw.Layer layer) {} @@ -65,21 +66,37 @@ public void render(GuiGraphics guiGraphics, DeltaTracker partialTick) { NeoForge.EVENT_BUS.post(new RenderGuiEvent.Post(guiGraphics, partialTick)); } - private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { + /** + * Reset z offset to prevent visual bugs caused by high z offset. + * Only effective when called inside {@link GuiLayerManager#renderInner} + */ + public void clearDepth(GuiGraphics guiGraphics) { + // prevent unnecessary calls + if (drawnLayerCount <= 0) return; + drawnLayerCount = 0; + // clear depth values to keep hud rendered at the same depth + guiGraphics.pose().popPose(); guiGraphics.pose().pushPose(); + guiGraphics.pose().translate(0, 0, -1000); + guiGraphics.fill(LayerRenderType.GUI, 0, 0, guiGraphics.guiWidth(), guiGraphics.guiHeight(), -1); + guiGraphics.pose().translate(0, 0, 1000); + } + private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { + guiGraphics.pose().pushPose(); + drawnLayerCount = 0; // enable clearDepth for (var layer : this.layers) { if (!NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Pre(guiGraphics, partialTick, layer.name(), layer.layer())).isCanceled()) { layer.layer().render(guiGraphics, partialTick); NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Post(guiGraphics, partialTick, layer.name(), layer.layer())); + drawnLayerCount++; } - // clear depth values to keep hud rendered at the same depth - guiGraphics.pose().translate(0, 0, -1000); - guiGraphics.fill(LayerRenderType.GUI, 0, 0, guiGraphics.guiWidth(), guiGraphics.guiHeight(), -1); - guiGraphics.pose().translate(0, 0, 1000); + guiGraphics.pose().translate(0, 0, Z_SEPARATION); } - + // reset depth to fix screen render bug + clearDepth(guiGraphics); guiGraphics.pose().popPose(); + drawnLayerCount = -1; // disable clearDepth } public void initModdedLayers() { From 77759df9ffdb7f5df1dd2ecf4d7d4348b497ba83 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Mon, 30 Sep 2024 08:43:12 +0800 Subject: [PATCH 3/6] make `clearDepth` not called by default --- patches/net/minecraft/client/gui/Gui.java.patch | 4 +--- .../net/minecraft/client/gui/LayeredDraw.java.patch | 13 ------------- .../minecraft/client/gui/screens/Screen.java.patch | 7 ++++++- .../neoforge/client/gui/GuiLayerManager.java | 8 +++----- 4 files changed, 10 insertions(+), 22 deletions(-) delete mode 100644 patches/net/minecraft/client/gui/LayeredDraw.java.patch diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index a4a15d21c0..d0ce21a1f9 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -152,7 +152,7 @@ TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.get(holder); int l1 = i; int i1 = j; -@@ -488,29 +_,61 @@ +@@ -488,29 +_,59 @@ } } @@ -168,8 +168,6 @@ + } + + private void renderHotbar(GuiGraphics p_316628_, DeltaTracker p_348543_) { -+ // Neo: Fix bugs caused by rendering ItemStack at high z offset -+ clearDepth(p_316628_); if (this.minecraft.gameMode.getPlayerMode() == GameType.SPECTATOR) { this.spectatorGui.renderHotbar(p_316628_); } else { diff --git a/patches/net/minecraft/client/gui/LayeredDraw.java.patch b/patches/net/minecraft/client/gui/LayeredDraw.java.patch deleted file mode 100644 index bbf5049d13..0000000000 --- a/patches/net/minecraft/client/gui/LayeredDraw.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/client/gui/LayeredDraw.java -+++ b/net/minecraft/client/gui/LayeredDraw.java -@@ -38,6 +_,10 @@ - } - } - -+ /** -+ * If this overlay could render ItemStack, it should call {@link Gui#clearDepth} at the beginning.
-+ * See usage in {@link Gui#renderHotbar} -+ */ - @OnlyIn(Dist.CLIENT) - public interface Layer { - void render(GuiGraphics p_316811_, DeltaTracker p_348559_); diff --git a/patches/net/minecraft/client/gui/screens/Screen.java.patch b/patches/net/minecraft/client/gui/screens/Screen.java.patch index cc93b39e1c..b8d7cd2d5e 100644 --- a/patches/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/net/minecraft/client/gui/screens/Screen.java.patch @@ -50,7 +50,7 @@ } @Override -@@ -354,6 +_,7 @@ +@@ -354,9 +_,12 @@ this.renderBlurredBackground(p_294317_); this.renderMenuBackground(p_283688_); @@ -58,6 +58,11 @@ } protected void renderBlurredBackground(float p_330683_) { ++ // Neo: Fix screen not rendering when having too many overlays ++ RenderSystem.disableDepthTest(); + this.minecraft.gameRenderer.processBlurEffect(p_330683_); + this.minecraft.getMainRenderTarget().bindWrite(false); + } @@ -467,6 +_,10 @@ public void onFilesDrop(List p_96591_) { } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java index b1bf9d151c..4b73d8bdd2 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java @@ -61,14 +61,16 @@ public void render(GuiGraphics guiGraphics, DeltaTracker partialTick) { return; } + drawnLayerCount = 0; // enable clearDepth renderInner(guiGraphics, partialTick); NeoForge.EVENT_BUS.post(new RenderGuiEvent.Post(guiGraphics, partialTick)); + drawnLayerCount = -1; // disable clearDepth } /** * Reset z offset to prevent visual bugs caused by high z offset. - * Only effective when called inside {@link GuiLayerManager#renderInner} + * Only effective when called inside {@link GuiLayerManager#render} */ public void clearDepth(GuiGraphics guiGraphics) { // prevent unnecessary calls @@ -84,7 +86,6 @@ public void clearDepth(GuiGraphics guiGraphics) { private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { guiGraphics.pose().pushPose(); - drawnLayerCount = 0; // enable clearDepth for (var layer : this.layers) { if (!NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Pre(guiGraphics, partialTick, layer.name(), layer.layer())).isCanceled()) { layer.layer().render(guiGraphics, partialTick); @@ -93,10 +94,7 @@ private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { } guiGraphics.pose().translate(0, 0, Z_SEPARATION); } - // reset depth to fix screen render bug - clearDepth(guiGraphics); guiGraphics.pose().popPose(); - drawnLayerCount = -1; // disable clearDepth } public void initModdedLayers() { From 1a26a2a89582a10a5f6e94844c3e07006af31468 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Mon, 30 Sep 2024 08:47:53 +0800 Subject: [PATCH 4/6] revert client hook changes --- .../java/net/neoforged/neoforge/client/ClientHooks.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index c0e4614f85..8bc74f258c 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -180,6 +180,7 @@ import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; import net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions; import net.neoforged.neoforge.client.gui.ClientTooltipComponentManager; +import net.neoforged.neoforge.client.gui.GuiLayerManager; import net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.common.NeoForge; @@ -246,8 +247,12 @@ public static void popGuiLayer(Minecraft minecraft) { } public static float getGuiFarPlane() { - // 11000 units for the overlay background and 10000 units for each layered Scree + // 11000 units for the overlay background and 10000 units for each layered Screen or 200 units for each HUD layer, whichever ends up higher + float depth = 10_000F * (1 + guiLayers.size()); + if (Minecraft.getInstance().level != null) { + depth = Math.max(depth, GuiLayerManager.Z_SEPARATION * Minecraft.getInstance().gui.getLayerCount()); + } return 11_000F + depth; } From 34641386d2e288077adc176ce1536502bb7f7900 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Mon, 30 Sep 2024 08:49:00 +0800 Subject: [PATCH 5/6] fix unnecessary diff --- .../java/net/neoforged/neoforge/client/gui/GuiLayerManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java index 4b73d8bdd2..f32215e4cf 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java @@ -92,7 +92,7 @@ private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Post(guiGraphics, partialTick, layer.name(), layer.layer())); drawnLayerCount++; } - guiGraphics.pose().translate(0, 0, Z_SEPARATION); + guiGraphics.pose().translate(0.0F, 0.0F, Z_SEPARATION); } guiGraphics.pose().popPose(); } From cf1f081e4d182e687c6efcfb300b9dc2b9d4b44a Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Mon, 30 Sep 2024 08:51:40 +0800 Subject: [PATCH 6/6] remove empty line diff --- .../java/net/neoforged/neoforge/client/gui/GuiLayerManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java index f32215e4cf..8166617e74 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/GuiLayerManager.java @@ -92,8 +92,10 @@ private void renderInner(GuiGraphics guiGraphics, DeltaTracker partialTick) { NeoForge.EVENT_BUS.post(new RenderGuiLayerEvent.Post(guiGraphics, partialTick, layer.name(), layer.layer())); drawnLayerCount++; } + guiGraphics.pose().translate(0.0F, 0.0F, Z_SEPARATION); } + guiGraphics.pose().popPose(); }