diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index dc1055a582..d0ce21a1f9 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -390,7 +390,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 +402,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/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 8d39152000..8166617e74 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; @@ -31,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) {} @@ -56,18 +61,36 @@ 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 } - 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#render} + */ + 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(); 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++; } guiGraphics.pose().translate(0.0F, 0.0F, Z_SEPARATION); @@ -87,4 +110,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); + } + } }