From 9724bae3894dd04552877e8fb26581d802fac834 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Mon, 23 Sep 2024 14:37:42 -0400
Subject: [PATCH 01/11] Add HudRenderEvents
---
.../client/rendering/v1/HudRenderEvents.java | 74 +++++++++++++++++++
.../client/rendering/InGameHudMixin.java | 37 ++++++++++
2 files changed, 111 insertions(+)
create mode 100644 fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
new file mode 100644
index 0000000000..dd7b38f6b4
--- /dev/null
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.client.rendering.v1;
+
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.render.RenderTickCounter;
+
+import net.fabricmc.fabric.api.event.Event;
+import net.fabricmc.fabric.api.event.EventFactory;
+
+/**
+ * Events for rendering elements on the HUD.
+ *
+ * These events will not be called if the HUD is hidden with F1.
+ */
+public class HudRenderEvents {
+ /**
+ * Called at the start of HUD rendering, right before anything is rendered.
+ */
+ public static final Event START = createEventForStage();
+
+ /**
+ * Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
+ */
+ public static final Event AFTER_MISC_OVERLAYS = createEventForStage();
+
+ /**
+ * Called after the hotbar, status bars, and experience bar have been rendered, and before the status effects overlays are rendered.
+ */
+ public static final Event AFTER_MAIN_HUD = createEventForStage();
+
+ /**
+ * Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
+ */
+ public static final Event BEFORE_CHAT = createEventForStage();
+
+ /**
+ * Called after the entire HUD is rendered.
+ */
+ public static final Event LAST = createEventForStage();
+
+ private static Event createEventForStage() {
+ return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (context, tickDelta) -> {
+ for (HudRenderStage listener : listeners) {
+ listener.onRender(context, tickDelta);
+ }
+ });
+ }
+
+ @FunctionalInterface
+ public interface HudRenderStage {
+ /**
+ * Called sometime during a specific HUD render stage.
+ *
+ * @param context The {@link DrawContext} instance
+ * @param tickCounter The {@link RenderTickCounter} instance
+ */
+ void onRender(DrawContext context, RenderTickCounter tickCounter);
+ }
+}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index 61f48b3ca2..a21427554b 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -19,16 +19,53 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.render.RenderTickCounter;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
+import net.fabricmc.fabric.api.client.rendering.v1.HudRenderEvents;
@Mixin(InGameHud.class)
public class InGameHudMixin {
+ @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
+ private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
+ return (context, tickCounter) -> {
+ HudRenderEvents.START.invoker().onRender(context, tickCounter);
+ miscOverlaysLayer.render(context, tickCounter);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onRender(context, tickCounter);
+ };
+ }
+
+ @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 3))
+ private LayeredDrawer.Layer fabric$afterMainHud(LayeredDrawer.Layer mainHudLayer) {
+ return (context, tickCounter) -> {
+ mainHudLayer.render(context, tickCounter);
+ HudRenderEvents.AFTER_MAIN_HUD.invoker().onRender(context, tickCounter);
+ };
+ }
+
+ @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
+ private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
+ return (context, tickCounter) -> {
+ HudRenderEvents.BEFORE_CHAT.invoker().onRender(context, tickCounter);
+ beforeChatLayer.render(context, tickCounter);
+ };
+ }
+
+ @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 7))
+ private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
+ return (context, tickCounter) -> {
+ subtitlesHudLayer.render(context, tickCounter);
+ HudRenderEvents.LAST.invoker().onRender(context, tickCounter);
+ };
+ }
+
@Inject(method = "render", at = @At(value = "TAIL"))
public void render(DrawContext drawContext, RenderTickCounter tickCounter, CallbackInfo callbackInfo) {
HudRenderCallback.EVENT.invoker().onHudRender(drawContext, tickCounter);
From 584d9e862563ef1bbc0c6aa022a99ecce91b0328 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Tue, 24 Sep 2024 23:33:01 -0400
Subject: [PATCH 02/11] Add HudRenderEventsTests and deprecate
HudRenderCallback
---
.../rendering/v1/HudRenderCallback.java | 8 +++--
.../client/rendering/v1/HudRenderEvents.java | 4 +--
.../client/rendering/InGameHudMixin.java | 5 +--
.../src/testmod/resources/fabric.mod.json | 1 +
.../client/HudRenderEventsTests.java | 35 +++++++++++++++++++
5 files changed, 47 insertions(+), 6 deletions(-)
create mode 100644 fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderCallback.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderCallback.java
index 4890d53ed6..f73909b6e4 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderCallback.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderCallback.java
@@ -22,10 +22,14 @@
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
+/**
+ * @deprecated Use {@link HudRenderEvents} instead. For the closest equivalent, use {@link HudRenderEvents#LAST}.
+ */
+@Deprecated
public interface HudRenderCallback {
- Event EVENT = EventFactory.createArrayBacked(HudRenderCallback.class, (listeners) -> (matrixStack, delta) -> {
+ Event EVENT = EventFactory.createArrayBacked(HudRenderCallback.class, (listeners) -> (context, tickCounter) -> {
for (HudRenderCallback event : listeners) {
- event.onHudRender(matrixStack, delta);
+ event.onHudRender(context, tickCounter);
}
});
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index dd7b38f6b4..c742d1c150 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -24,8 +24,8 @@
/**
* Events for rendering elements on the HUD.
- *
- * These events will not be called if the HUD is hidden with F1.
+ *
+ *
These events will not be called if the HUD is hidden with F1.
*/
public class HudRenderEvents {
/**
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index a21427554b..f4e134e33c 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -43,9 +43,9 @@ public class InGameHudMixin {
}
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 3))
- private LayeredDrawer.Layer fabric$afterMainHud(LayeredDrawer.Layer mainHudLayer) {
+ private LayeredDrawer.Layer fabric$afterMainHudAndExperienceLevel(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
- mainHudLayer.render(context, tickCounter);
+ experienceLevelLayer.render(context, tickCounter);
HudRenderEvents.AFTER_MAIN_HUD.invoker().onRender(context, tickCounter);
};
}
@@ -66,6 +66,7 @@ public class InGameHudMixin {
};
}
+ @Deprecated
@Inject(method = "render", at = @At(value = "TAIL"))
public void render(DrawContext drawContext, RenderTickCounter tickCounter, CallbackInfo callbackInfo) {
HudRenderCallback.EVENT.invoker().onHudRender(drawContext, tickCounter);
diff --git a/fabric-rendering-v1/src/testmod/resources/fabric.mod.json b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json
index 57107b39f9..a24fc8630b 100644
--- a/fabric-rendering-v1/src/testmod/resources/fabric.mod.json
+++ b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json
@@ -18,6 +18,7 @@
"net.fabricmc.fabric.test.rendering.client.DimensionalRenderingTest",
"net.fabricmc.fabric.test.rendering.client.FeatureRendererTest",
"net.fabricmc.fabric.test.rendering.client.HudAndShaderTest",
+ "net.fabricmc.fabric.test.rendering.client.HudRenderEventsTests",
"net.fabricmc.fabric.test.rendering.client.TooltipComponentTests",
"net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests"
]
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
new file mode 100644
index 0000000000..0305befa24
--- /dev/null
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.test.rendering.client;
+
+import net.fabricmc.api.ClientModInitializer;
+import net.fabricmc.fabric.api.client.rendering.v1.HudRenderEvents;
+
+public class HudRenderEventsTests implements ClientModInitializer {
+ @Override
+ public void onInitializeClient() {
+ HudRenderEvents.START.register((context, tickCounter) -> { });
+ // Render a red square in the center of the screen underneath the crosshair
+ HudRenderEvents.AFTER_MISC_OVERLAYS.register((context, tickCounter) -> context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, 0xFFFF0000));
+ // Render a green rectangle at the bottom of the screen, and it should block the hotbar and status bars
+ HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() - 50, context.getScaledWindowHeight() - 10, 0xFF00FF00));
+ // Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
+ HudRenderEvents.BEFORE_CHAT.register((context, tickCounter) -> context.fill(0, context.getScaledWindowHeight() / 2, 100, context.getScaledWindowHeight() - 10, 0xFF0000FF));
+ // Render a yellow rectangle at the top of the screen, and it should block the player list
+ HudRenderEvents.LAST.register((context, tickCounter) -> context.fill(0, 0, context.getScaledWindowWidth(), 100, 0xFFFFFF00));
+ }
+}
From a7ac0f110ea478aa25f8f1f3bdec12b48bb05ce1 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Wed, 25 Sep 2024 00:37:36 -0400
Subject: [PATCH 03/11] Update tests
---
.../client/HudRenderEventsTests.java | 29 +++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
index 0305befa24..3ba1c8604c 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -16,20 +16,39 @@
package net.fabricmc.fabric.test.rendering.client;
+import net.minecraft.client.MinecraftClient;
+
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderEvents;
public class HudRenderEventsTests implements ClientModInitializer {
@Override
public void onInitializeClient() {
- HudRenderEvents.START.register((context, tickCounter) -> { });
+ // Render a blue rectangle at the top right of the screen, and it should be blocked by misc overlays such as vignette, spyglass, and powder snow
+ HudRenderEvents.START.register((context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() - 200, 0, context.getScaledWindowWidth(), 30, 0xFF0000FF);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "1. Blue rectangle blocked by overlays", context.getScaledWindowWidth() - 196, 10, 0xFFFFFFFF);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "such as powder snow", context.getScaledWindowWidth() - 111, 20, 0xFFFFFFFF);
+ });
// Render a red square in the center of the screen underneath the crosshair
- HudRenderEvents.AFTER_MISC_OVERLAYS.register((context, tickCounter) -> context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, 0xFFFF0000));
+ HudRenderEvents.AFTER_MISC_OVERLAYS.register((context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, 0xFFFF0000);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "2. Red square underneath crosshair", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() / 2 + 10, 0xFFFFFFFF);
+ });
// Render a green rectangle at the bottom of the screen, and it should block the hotbar and status bars
- HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() - 50, context.getScaledWindowHeight() - 10, 0xFF00FF00));
+ HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, 0xFF00FF00);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, 0xFFFFFFFF);
+ });
// Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
- HudRenderEvents.BEFORE_CHAT.register((context, tickCounter) -> context.fill(0, context.getScaledWindowHeight() / 2, 100, context.getScaledWindowHeight() - 10, 0xFF0000FF));
+ HudRenderEvents.BEFORE_CHAT.register((context, tickCounter) -> {
+ context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, 0xFF0000FF);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, 0xFFFFFFFF);
+ });
// Render a yellow rectangle at the top of the screen, and it should block the player list
- HudRenderEvents.LAST.register((context, tickCounter) -> context.fill(0, 0, context.getScaledWindowWidth(), 100, 0xFFFFFF00));
+ HudRenderEvents.LAST.register((context, tickCounter) -> {
+ context.fill(0, 0, context.getScaledWindowWidth(), 10, 0xFFFFFF00);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, 0xFFFFFFFF);
+ });
}
}
From 668c53313d780e9084c65e4205b4dcdb930e498a Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Wed, 25 Sep 2024 08:49:54 -0400
Subject: [PATCH 04/11] Add client parameter and apply suggestions
---
.../client/rendering/v1/HudRenderEvents.java | 12 ++++---
.../client/rendering/InGameHudMixin.java | 17 +++++++---
.../client/HudRenderEventsTests.java | 33 ++++++++++---------
3 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index c742d1c150..49eb56c25a 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -16,6 +16,7 @@
package net.fabricmc.fabric.api.client.rendering.v1;
+import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderTickCounter;
@@ -27,7 +28,7 @@
*
* These events will not be called if the HUD is hidden with F1.
*/
-public class HudRenderEvents {
+public final class HudRenderEvents {
/**
* Called at the start of HUD rendering, right before anything is rendered.
*/
@@ -53,10 +54,12 @@ public class HudRenderEvents {
*/
public static final Event LAST = createEventForStage();
+ private HudRenderEvents() { }
+
private static Event createEventForStage() {
- return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (context, tickDelta) -> {
+ return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (client, context, tickCounter) -> {
for (HudRenderStage listener : listeners) {
- listener.onRender(context, tickDelta);
+ listener.onHudRender(client, context, tickCounter);
}
});
}
@@ -66,9 +69,10 @@ public interface HudRenderStage {
/**
* Called sometime during a specific HUD render stage.
*
+ * @param client The {@link MinecraftClient} instance
* @param context The {@link DrawContext} instance
* @param tickCounter The {@link RenderTickCounter} instance
*/
- void onRender(DrawContext context, RenderTickCounter tickCounter);
+ void onHudRender(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
}
}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index f4e134e33c..48acba80d6 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -16,13 +16,16 @@
package net.fabricmc.fabric.mixin.client.rendering;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.gui.hud.InGameHud;
@@ -33,12 +36,16 @@
@Mixin(InGameHud.class)
public class InGameHudMixin {
+ @Shadow
+ @Final
+ private MinecraftClient client;
+
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.START.invoker().onRender(context, tickCounter);
+ HudRenderEvents.START.invoker().onHudRender(client, context, tickCounter);
miscOverlaysLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onRender(context, tickCounter);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onHudRender(client, context, tickCounter);
};
}
@@ -46,14 +53,14 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$afterMainHudAndExperienceLevel(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
experienceLevelLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MAIN_HUD.invoker().onRender(context, tickCounter);
+ HudRenderEvents.AFTER_MAIN_HUD.invoker().onHudRender(client, context, tickCounter);
};
}
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.BEFORE_CHAT.invoker().onRender(context, tickCounter);
+ HudRenderEvents.BEFORE_CHAT.invoker().onHudRender(client, context, tickCounter);
beforeChatLayer.render(context, tickCounter);
};
}
@@ -62,7 +69,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
- HudRenderEvents.LAST.invoker().onRender(context, tickCounter);
+ HudRenderEvents.LAST.invoker().onHudRender(client, context, tickCounter);
};
}
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
index 3ba1c8604c..bf66a45cda 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -17,6 +17,7 @@
package net.fabricmc.fabric.test.rendering.client;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.util.Colors;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderEvents;
@@ -25,30 +26,30 @@ public class HudRenderEventsTests implements ClientModInitializer {
@Override
public void onInitializeClient() {
// Render a blue rectangle at the top right of the screen, and it should be blocked by misc overlays such as vignette, spyglass, and powder snow
- HudRenderEvents.START.register((context, tickCounter) -> {
- context.fill(context.getScaledWindowWidth() - 200, 0, context.getScaledWindowWidth(), 30, 0xFF0000FF);
- context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "1. Blue rectangle blocked by overlays", context.getScaledWindowWidth() - 196, 10, 0xFFFFFFFF);
- context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "such as powder snow", context.getScaledWindowWidth() - 111, 20, 0xFFFFFFFF);
+ HudRenderEvents.START.register((client, context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() - 200, 0, context.getScaledWindowWidth(), 30, Colors.BLUE);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "1. Blue rectangle blocked by overlays", context.getScaledWindowWidth() - 196, 10, Colors.WHITE);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "such as powder snow", context.getScaledWindowWidth() - 111, 20, Colors.WHITE);
});
// Render a red square in the center of the screen underneath the crosshair
- HudRenderEvents.AFTER_MISC_OVERLAYS.register((context, tickCounter) -> {
- context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, 0xFFFF0000);
- context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "2. Red square underneath crosshair", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() / 2 + 10, 0xFFFFFFFF);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.register((client, context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, Colors.RED);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "2. Red square underneath crosshair", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() / 2 + 10, Colors.WHITE);
});
// Render a green rectangle at the bottom of the screen, and it should block the hotbar and status bars
- HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> {
- context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, 0xFF00FF00);
- context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, 0xFFFFFFFF);
+ HudRenderEvents.AFTER_MAIN_HUD.register((client, context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, Colors.GREEN);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, Colors.WHITE);
});
// Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
- HudRenderEvents.BEFORE_CHAT.register((context, tickCounter) -> {
- context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, 0xFF0000FF);
- context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, 0xFFFFFFFF);
+ HudRenderEvents.BEFORE_CHAT.register((client, context, tickCounter) -> {
+ context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, Colors.BLUE);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, Colors.WHITE);
});
// Render a yellow rectangle at the top of the screen, and it should block the player list
- HudRenderEvents.LAST.register((context, tickCounter) -> {
- context.fill(0, 0, context.getScaledWindowWidth(), 10, 0xFFFFFF00);
- context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, 0xFFFFFFFF);
+ HudRenderEvents.LAST.register((client, context, tickCounter) -> {
+ context.fill(0, 0, context.getScaledWindowWidth(), 10, Colors.YELLOW);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
});
}
}
From f781eb7e48257b553235014e7ef364597b720c26 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Wed, 2 Oct 2024 23:49:32 -0400
Subject: [PATCH 05/11] Split HudRenderEvents into separate interfaces
---
.../client/rendering/v1/HudRenderEvents.java | 94 +++++++++++++++----
.../client/rendering/InGameHudMixin.java | 10 +-
2 files changed, 82 insertions(+), 22 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index 49eb56c25a..ec71344205 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -32,47 +32,107 @@ public final class HudRenderEvents {
/**
* Called at the start of HUD rendering, right before anything is rendered.
*/
- public static final Event START = createEventForStage();
+ public static final Event START = EventFactory.createArrayBacked(Start.class, listeners -> (client, context, tickCounter) -> {
+ for (Start listener : listeners) {
+ listener.onHudStart(client, context, tickCounter);
+ }
+ });
/**
* Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
*/
- public static final Event AFTER_MISC_OVERLAYS = createEventForStage();
+ public static final Event AFTER_MISC_OVERLAYS = EventFactory.createArrayBacked(AfterMiscOverlays.class, listeners -> (client, context, tickCounter) -> {
+ for (AfterMiscOverlays listener : listeners) {
+ listener.afterMiscOverlays(client, context, tickCounter);
+ }
+ });
/**
* Called after the hotbar, status bars, and experience bar have been rendered, and before the status effects overlays are rendered.
*/
- public static final Event AFTER_MAIN_HUD = createEventForStage();
+ public static final Event AFTER_MAIN_HUD = EventFactory.createArrayBacked(AfterMainHud.class, listeners -> (client, context, tickCounter) -> {
+ for (AfterMainHud listener : listeners) {
+ listener.afterMainHud(client, context, tickCounter);
+ }
+ });
/**
* Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
*/
- public static final Event BEFORE_CHAT = createEventForStage();
+ public static final Event BEFORE_CHAT = EventFactory.createArrayBacked(BeforeChat.class, listeners -> (client, context, tickCounter) -> {
+ for (BeforeChat listener : listeners) {
+ listener.beforeChat(client, context, tickCounter);
+ }
+ });
/**
* Called after the entire HUD is rendered.
*/
- public static final Event LAST = createEventForStage();
+ public static final Event LAST = EventFactory.createArrayBacked(Last.class, listeners -> (client, context, tickCounter) -> {
+ for (Last listener : listeners) {
+ listener.onHudLast(client, context, tickCounter);
+ }
+ });
private HudRenderEvents() { }
- private static Event createEventForStage() {
- return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (client, context, tickCounter) -> {
- for (HudRenderStage listener : listeners) {
- listener.onHudRender(client, context, tickCounter);
- }
- });
+ @FunctionalInterface
+ public interface Start {
+ /**
+ * Called at the start of HUD rendering, right before anything is rendered.
+ *
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
+ */
+ void onHudStart(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ }
+
+ @FunctionalInterface
+ public interface AfterMiscOverlays {
+ /**
+ * Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
+ *
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
+ */
+ void afterMiscOverlays(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ }
+
+ @FunctionalInterface
+ public interface AfterMainHud {
+ /**
+ * Called after the hotbar, status bars, and experience bar have been rendered, and before the status effects overlays are rendered.
+ *
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
+ */
+ void afterMainHud(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ }
+
+ @FunctionalInterface
+ public interface BeforeChat {
+ /**
+ * Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
+ *
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
+ */
+ void beforeChat(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
}
@FunctionalInterface
- public interface HudRenderStage {
+ public interface Last {
/**
- * Called sometime during a specific HUD render stage.
+ * Called after the entire HUD is rendered.
*
- * @param client The {@link MinecraftClient} instance
- * @param context The {@link DrawContext} instance
- * @param tickCounter The {@link RenderTickCounter} instance
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
*/
- void onHudRender(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ void onHudLast(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
}
}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index 48acba80d6..f639a78c5c 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -43,9 +43,9 @@ public class InGameHudMixin {
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.START.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.START.invoker().onHudStart(client, context, tickCounter);
miscOverlaysLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().afterMiscOverlays(client, context, tickCounter);
};
}
@@ -53,14 +53,14 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$afterMainHudAndExperienceLevel(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
experienceLevelLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MAIN_HUD.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.AFTER_MAIN_HUD.invoker().afterMainHud(client, context, tickCounter);
};
}
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.BEFORE_CHAT.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.BEFORE_CHAT.invoker().beforeChat(client, context, tickCounter);
beforeChatLayer.render(context, tickCounter);
};
}
@@ -69,7 +69,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
- HudRenderEvents.LAST.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.LAST.invoker().onHudLast(client, context, tickCounter);
};
}
From f13daa52e3b5c6294da65f2c50bacf5a31834b4d Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Thu, 3 Oct 2024 00:29:57 -0400
Subject: [PATCH 06/11] Fix before chat and last
---
.../fabric/mixin/client/rendering/InGameHudMixin.java | 4 ++--
.../fabric/test/rendering/client/HudRenderEventsTests.java | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index f639a78c5c..be2d917b22 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -57,7 +57,7 @@ public class InGameHudMixin {
};
}
- @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
+ @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
HudRenderEvents.BEFORE_CHAT.invoker().beforeChat(client, context, tickCounter);
@@ -65,7 +65,7 @@ public class InGameHudMixin {
};
}
- @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 1)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 7))
+ @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 7))
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
index bf66a45cda..923f0f986e 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -48,7 +48,7 @@ public void onInitializeClient() {
});
// Render a yellow rectangle at the top of the screen, and it should block the player list
HudRenderEvents.LAST.register((client, context, tickCounter) -> {
- context.fill(0, 0, context.getScaledWindowWidth(), 10, Colors.YELLOW);
+ context.fill(context.getScaledWindowWidth() / 2 - 150, 0, context.getScaledWindowWidth() / 2 + 150, 15, Colors.YELLOW);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
});
}
From ce182edcb7e193b81bbb0a4195f498a4a89a3771 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Thu, 3 Oct 2024 12:17:20 -0400
Subject: [PATCH 07/11] Add after sleep overlay event and update after main hud
injection point
---
.../client/rendering/v1/HudRenderEvents.java | 25 +++++++++++++++++--
.../client/rendering/InGameHudMixin.java | 12 +++++++--
.../client/HudRenderEventsTests.java | 10 ++++++--
3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index ec71344205..4f5326df86 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -48,7 +48,7 @@ public final class HudRenderEvents {
});
/**
- * Called after the hotbar, status bars, and experience bar have been rendered, and before the status effects overlays are rendered.
+ * Called after the hotbar, status bars, experience bar, status effects overlays, and boss bar have been rendered, and before the sleep overlay is rendered.
*/
public static final Event AFTER_MAIN_HUD = EventFactory.createArrayBacked(AfterMainHud.class, listeners -> (client, context, tickCounter) -> {
for (AfterMainHud listener : listeners) {
@@ -56,6 +56,15 @@ public final class HudRenderEvents {
}
});
+ /**
+ * Called after the sleep overlay has been rendered, and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle are rendered.
+ */
+ public static final Event AFTER_SLEEP_OVERLAY = EventFactory.createArrayBacked(AfterSleepOverlay.class, listeners -> (client, context, tickCounter) -> {
+ for (AfterSleepOverlay listener : listeners) {
+ listener.afterSleepOverlay(client, context, tickCounter);
+ }
+ });
+
/**
* Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
*/
@@ -103,7 +112,7 @@ public interface AfterMiscOverlays {
@FunctionalInterface
public interface AfterMainHud {
/**
- * Called after the hotbar, status bars, and experience bar have been rendered, and before the status effects overlays are rendered.
+ * Called after the hotbar, status bars, experience bar, status effects overlays, and boss bar have been rendered, and before the sleep overlay is rendered.
*
* @param client the {@link MinecraftClient} instance
* @param context the {@link DrawContext} instance
@@ -112,6 +121,18 @@ public interface AfterMainHud {
void afterMainHud(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
}
+ @FunctionalInterface
+ public interface AfterSleepOverlay {
+ /**
+ * Called after the sleep overlay has been rendered, and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle are rendered.
+ *
+ * @param client the {@link MinecraftClient} instance
+ * @param context the {@link DrawContext} instance
+ * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
+ */
+ void afterSleepOverlay(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ }
+
@FunctionalInterface
public interface BeforeChat {
/**
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index be2d917b22..d70118d067 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -49,14 +49,22 @@ public class InGameHudMixin {
};
}
- @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 3))
- private LayeredDrawer.Layer fabric$afterMainHudAndExperienceLevel(LayeredDrawer.Layer experienceLevelLayer) {
+ @ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
+ private LayeredDrawer.Layer fabric$afterMainHudExperienceLevelStatusEffectOverlayAndBossBar(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
experienceLevelLayer.render(context, tickCounter);
HudRenderEvents.AFTER_MAIN_HUD.invoker().afterMainHud(client, context, tickCounter);
};
}
+ @ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
+ private LayeredDrawer.Layer fabric$afterSleepOverlay(LayeredDrawer.Layer demoTimerLayer) {
+ return (context, tickCounter) -> {
+ HudRenderEvents.AFTER_SLEEP_OVERLAY.invoker().afterSleepOverlay(client, context, tickCounter);
+ demoTimerLayer.render(context, tickCounter);
+ };
+ }
+
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
index 923f0f986e..48e98c7c08 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -41,15 +41,21 @@ public void onInitializeClient() {
context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, Colors.GREEN);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, Colors.WHITE);
});
+ // Render a yellow rectangle at the right of the screen, and it should be above the sleep overlay but below the scoreboard
+ HudRenderEvents.AFTER_SLEEP_OVERLAY.register((client, context, tickCounter) -> {
+ context.fill(context.getScaledWindowWidth() - 240, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth(), context.getScaledWindowHeight() / 2 + 10, Colors.YELLOW);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This yellow rectangle should be above", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2 - 10, Colors.WHITE);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "the sleep overlay but below the scoreboard.", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2, Colors.WHITE);
+ });
// Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
HudRenderEvents.BEFORE_CHAT.register((client, context, tickCounter) -> {
context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, Colors.BLUE);
- context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, Colors.WHITE);
+ context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, Colors.WHITE);
});
// Render a yellow rectangle at the top of the screen, and it should block the player list
HudRenderEvents.LAST.register((client, context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() / 2 - 150, 0, context.getScaledWindowWidth() / 2 + 150, 15, Colors.YELLOW);
- context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
+ context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "6. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
});
}
}
From 6362810c66b490875a1b162a9f8023c95ea151ed Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Fri, 11 Oct 2024 12:30:38 -0400
Subject: [PATCH 08/11] Add comments for injection points
---
.../fabric/mixin/client/rendering/InGameHudMixin.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index d70118d067..5aa9e12ad8 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -40,6 +40,7 @@ public class InGameHudMixin {
@Final
private MinecraftClient client;
+ // Targeting the first addLayer call of the first layered drawer, currently the misc overlays layer (renderMiscOverlays) as of 1.21.
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
return (context, tickCounter) -> {
@@ -49,6 +50,7 @@ public class InGameHudMixin {
};
}
+ // Targeting the last addLayer call of the first layered drawer, which is after the main hud, currently the boss bar layer (bossBarHud.render) as of 1.21.
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$afterMainHudExperienceLevelStatusEffectOverlayAndBossBar(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
@@ -57,6 +59,7 @@ public class InGameHudMixin {
};
}
+ // Targeting the first addLayer call of the second layered drawer, currently the demo timer layer (renderDemoTimer) as of 1.21.
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$afterSleepOverlay(LayeredDrawer.Layer demoTimerLayer) {
return (context, tickCounter) -> {
@@ -65,6 +68,7 @@ public class InGameHudMixin {
};
}
+ // Targeting the chat layer (renderChat), currently the sixth addLayer call of the second layered drawer as of 1.21.
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
@@ -73,6 +77,7 @@ public class InGameHudMixin {
};
}
+ // Targeting the last addLayer call of the second layered drawer, currently the subtitles hud layer (subtitlesHud.render) as of 1.21.
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 7))
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
@@ -81,6 +86,7 @@ public class InGameHudMixin {
};
}
+ // Inject after the HUD is rendered. Deprecated in favor of HudRenderEvents.
@Deprecated
@Inject(method = "render", at = @At(value = "TAIL"))
public void render(DrawContext drawContext, RenderTickCounter tickCounter, CallbackInfo callbackInfo) {
From 28557b12b3aaf90526698ffa0df246d8acea5e52 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Fri, 11 Oct 2024 13:08:28 -0400
Subject: [PATCH 09/11] Revert splitting HudRenderEvents into separate
interfaces
---
.../client/rendering/v1/HudRenderEvents.java | 106 +++---------------
.../client/rendering/InGameHudMixin.java | 12 +-
2 files changed, 21 insertions(+), 97 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index 4f5326df86..5c83b2620b 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -32,128 +32,52 @@ public final class HudRenderEvents {
/**
* Called at the start of HUD rendering, right before anything is rendered.
*/
- public static final Event START = EventFactory.createArrayBacked(Start.class, listeners -> (client, context, tickCounter) -> {
- for (Start listener : listeners) {
- listener.onHudStart(client, context, tickCounter);
- }
- });
+ public static final Event START = createEventForStage();
/**
* Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
*/
- public static final Event AFTER_MISC_OVERLAYS = EventFactory.createArrayBacked(AfterMiscOverlays.class, listeners -> (client, context, tickCounter) -> {
- for (AfterMiscOverlays listener : listeners) {
- listener.afterMiscOverlays(client, context, tickCounter);
- }
- });
+ public static final Event AFTER_MISC_OVERLAYS = createEventForStage();
/**
* Called after the hotbar, status bars, experience bar, status effects overlays, and boss bar have been rendered, and before the sleep overlay is rendered.
*/
- public static final Event AFTER_MAIN_HUD = EventFactory.createArrayBacked(AfterMainHud.class, listeners -> (client, context, tickCounter) -> {
- for (AfterMainHud listener : listeners) {
- listener.afterMainHud(client, context, tickCounter);
- }
- });
+ public static final Event AFTER_MAIN_HUD = createEventForStage();
/**
* Called after the sleep overlay has been rendered, and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle are rendered.
*/
- public static final Event AFTER_SLEEP_OVERLAY = EventFactory.createArrayBacked(AfterSleepOverlay.class, listeners -> (client, context, tickCounter) -> {
- for (AfterSleepOverlay listener : listeners) {
- listener.afterSleepOverlay(client, context, tickCounter);
- }
- });
+ public static final Event AFTER_SLEEP_OVERLAY = createEventForStage();
/**
* Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
*/
- public static final Event BEFORE_CHAT = EventFactory.createArrayBacked(BeforeChat.class, listeners -> (client, context, tickCounter) -> {
- for (BeforeChat listener : listeners) {
- listener.beforeChat(client, context, tickCounter);
- }
- });
+ public static final Event BEFORE_CHAT = createEventForStage();
/**
* Called after the entire HUD is rendered.
*/
- public static final Event LAST = EventFactory.createArrayBacked(Last.class, listeners -> (client, context, tickCounter) -> {
- for (Last listener : listeners) {
- listener.onHudLast(client, context, tickCounter);
- }
- });
+ public static final Event LAST = createEventForStage();
private HudRenderEvents() { }
- @FunctionalInterface
- public interface Start {
- /**
- * Called at the start of HUD rendering, right before anything is rendered.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void onHudStart(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
- }
-
- @FunctionalInterface
- public interface AfterMiscOverlays {
- /**
- * Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void afterMiscOverlays(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
- }
-
- @FunctionalInterface
- public interface AfterMainHud {
- /**
- * Called after the hotbar, status bars, experience bar, status effects overlays, and boss bar have been rendered, and before the sleep overlay is rendered.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void afterMainHud(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
- }
-
- @FunctionalInterface
- public interface AfterSleepOverlay {
- /**
- * Called after the sleep overlay has been rendered, and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle are rendered.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void afterSleepOverlay(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
- }
-
- @FunctionalInterface
- public interface BeforeChat {
- /**
- * Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void beforeChat(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ private static Event createEventForStage() {
+ return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (client, context, tickCounter) -> {
+ for (HudRenderStage listener : listeners) {
+ listener.onHudRender(client, context, tickCounter);
+ }
+ });
}
@FunctionalInterface
- public interface Last {
+ public interface HudRenderStage {
/**
- * Called after the entire HUD is rendered.
+ * Called during a HUD render stage.
*
* @param client the {@link MinecraftClient} instance
* @param context the {@link DrawContext} instance
* @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
*/
- void onHudLast(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
+ void onHudRender(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
}
}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index 5aa9e12ad8..234cb8c211 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -44,9 +44,9 @@ public class InGameHudMixin {
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.START.invoker().onHudStart(client, context, tickCounter);
+ HudRenderEvents.START.invoker().onHudRender(client, context, tickCounter);
miscOverlaysLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().afterMiscOverlays(client, context, tickCounter);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onHudRender(client, context, tickCounter);
};
}
@@ -55,7 +55,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$afterMainHudExperienceLevelStatusEffectOverlayAndBossBar(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
experienceLevelLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MAIN_HUD.invoker().afterMainHud(client, context, tickCounter);
+ HudRenderEvents.AFTER_MAIN_HUD.invoker().onHudRender(client, context, tickCounter);
};
}
@@ -63,7 +63,7 @@ public class InGameHudMixin {
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$afterSleepOverlay(LayeredDrawer.Layer demoTimerLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.AFTER_SLEEP_OVERLAY.invoker().afterSleepOverlay(client, context, tickCounter);
+ HudRenderEvents.AFTER_SLEEP_OVERLAY.invoker().onHudRender(client, context, tickCounter);
demoTimerLayer.render(context, tickCounter);
};
}
@@ -72,7 +72,7 @@ public class InGameHudMixin {
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.BEFORE_CHAT.invoker().beforeChat(client, context, tickCounter);
+ HudRenderEvents.BEFORE_CHAT.invoker().onHudRender(client, context, tickCounter);
beforeChatLayer.render(context, tickCounter);
};
}
@@ -82,7 +82,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
- HudRenderEvents.LAST.invoker().onHudLast(client, context, tickCounter);
+ HudRenderEvents.LAST.invoker().onHudRender(client, context, tickCounter);
};
}
From 0d2bcf291eda8c1b5353412e421323e09eebd2c2 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Wed, 23 Oct 2024 17:35:55 -0400
Subject: [PATCH 10/11] Use vanilla layered drawer layer interface
---
.../client/rendering/v1/HudRenderEvents.java | 36 ++++++-------------
.../client/rendering/InGameHudMixin.java | 12 +++----
.../client/HudRenderEventsTests.java | 12 +++----
3 files changed, 23 insertions(+), 37 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
index 5c83b2620b..d405274c4f 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/api/client/rendering/v1/HudRenderEvents.java
@@ -16,9 +16,7 @@
package net.fabricmc.fabric.api.client.rendering.v1;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.DrawContext;
-import net.minecraft.client.render.RenderTickCounter;
+import net.minecraft.client.gui.LayeredDrawer;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
@@ -32,52 +30,40 @@ public final class HudRenderEvents {
/**
* Called at the start of HUD rendering, right before anything is rendered.
*/
- public static final Event START = createEventForStage();
+ public static final Event START = createEventForStage();
/**
* Called after misc overlays (vignette, spyglass, and powder snow) have been rendered, and before the crosshair is rendered.
*/
- public static final Event AFTER_MISC_OVERLAYS = createEventForStage();
+ public static final Event AFTER_MISC_OVERLAYS = createEventForStage();
/**
* Called after the hotbar, status bars, experience bar, status effects overlays, and boss bar have been rendered, and before the sleep overlay is rendered.
*/
- public static final Event AFTER_MAIN_HUD = createEventForStage();
+ public static final Event AFTER_MAIN_HUD = createEventForStage();
/**
* Called after the sleep overlay has been rendered, and before the demo timer, debug HUD, scoreboard, overlay message (action bar), and title and subtitle are rendered.
*/
- public static final Event AFTER_SLEEP_OVERLAY = createEventForStage();
+ public static final Event AFTER_SLEEP_OVERLAY = createEventForStage();
/**
* Called after the debug HUD, scoreboard, overlay message (action bar), and title and subtitle have been rendered, and before the {@link net.minecraft.client.gui.hud.ChatHud} is rendered.
*/
- public static final Event BEFORE_CHAT = createEventForStage();
+ public static final Event BEFORE_CHAT = createEventForStage();
/**
* Called after the entire HUD is rendered.
*/
- public static final Event LAST = createEventForStage();
+ public static final Event LAST = createEventForStage();
private HudRenderEvents() { }
- private static Event createEventForStage() {
- return EventFactory.createArrayBacked(HudRenderStage.class, listeners -> (client, context, tickCounter) -> {
- for (HudRenderStage listener : listeners) {
- listener.onHudRender(client, context, tickCounter);
+ private static Event createEventForStage() {
+ return EventFactory.createArrayBacked(LayeredDrawer.Layer.class, listeners -> (context, tickCounter) -> {
+ for (LayeredDrawer.Layer listener : listeners) {
+ listener.render(context, tickCounter);
}
});
}
-
- @FunctionalInterface
- public interface HudRenderStage {
- /**
- * Called during a HUD render stage.
- *
- * @param client the {@link MinecraftClient} instance
- * @param context the {@link DrawContext} instance
- * @param tickCounter the {@link RenderTickCounter} instance with access to tick delta
- */
- void onHudRender(MinecraftClient client, DrawContext context, RenderTickCounter tickCounter);
- }
}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index 234cb8c211..0c80d3a582 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -44,9 +44,9 @@ public class InGameHudMixin {
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.START.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.START.invoker().render(context, tickCounter);
miscOverlaysLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.AFTER_MISC_OVERLAYS.invoker().render(context, tickCounter);
};
}
@@ -55,7 +55,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$afterMainHudExperienceLevelStatusEffectOverlayAndBossBar(LayeredDrawer.Layer experienceLevelLayer) {
return (context, tickCounter) -> {
experienceLevelLayer.render(context, tickCounter);
- HudRenderEvents.AFTER_MAIN_HUD.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.AFTER_MAIN_HUD.invoker().render(context, tickCounter);
};
}
@@ -63,7 +63,7 @@ public class InGameHudMixin {
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$afterSleepOverlay(LayeredDrawer.Layer demoTimerLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.AFTER_SLEEP_OVERLAY.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.AFTER_SLEEP_OVERLAY.invoker().render(context, tickCounter);
demoTimerLayer.render(context, tickCounter);
};
}
@@ -72,7 +72,7 @@ public class InGameHudMixin {
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 5))
private LayeredDrawer.Layer fabric$beforeChat(LayeredDrawer.Layer beforeChatLayer) {
return (context, tickCounter) -> {
- HudRenderEvents.BEFORE_CHAT.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.BEFORE_CHAT.invoker().render(context, tickCounter);
beforeChatLayer.render(context, tickCounter);
};
}
@@ -82,7 +82,7 @@ public class InGameHudMixin {
private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
- HudRenderEvents.LAST.invoker().onHudRender(client, context, tickCounter);
+ HudRenderEvents.LAST.invoker().render(context, tickCounter);
};
}
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
index 48e98c7c08..508e97505a 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/HudRenderEventsTests.java
@@ -26,34 +26,34 @@ public class HudRenderEventsTests implements ClientModInitializer {
@Override
public void onInitializeClient() {
// Render a blue rectangle at the top right of the screen, and it should be blocked by misc overlays such as vignette, spyglass, and powder snow
- HudRenderEvents.START.register((client, context, tickCounter) -> {
+ HudRenderEvents.START.register((context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() - 200, 0, context.getScaledWindowWidth(), 30, Colors.BLUE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "1. Blue rectangle blocked by overlays", context.getScaledWindowWidth() - 196, 10, Colors.WHITE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "such as powder snow", context.getScaledWindowWidth() - 111, 20, Colors.WHITE);
});
// Render a red square in the center of the screen underneath the crosshair
- HudRenderEvents.AFTER_MISC_OVERLAYS.register((client, context, tickCounter) -> {
+ HudRenderEvents.AFTER_MISC_OVERLAYS.register((context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() / 2 - 10, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth() / 2 + 10, context.getScaledWindowHeight() / 2 + 10, Colors.RED);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "2. Red square underneath crosshair", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() / 2 + 10, Colors.WHITE);
});
// Render a green rectangle at the bottom of the screen, and it should block the hotbar and status bars
- HudRenderEvents.AFTER_MAIN_HUD.register((client, context, tickCounter) -> {
+ HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() / 2 - 50, context.getScaledWindowHeight() - 50, context.getScaledWindowWidth() / 2 + 50, context.getScaledWindowHeight() - 10, Colors.GREEN);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "3. This green rectangle should block the hotbar and status bars.", context.getScaledWindowWidth() / 2, context.getScaledWindowHeight() - 40, Colors.WHITE);
});
// Render a yellow rectangle at the right of the screen, and it should be above the sleep overlay but below the scoreboard
- HudRenderEvents.AFTER_SLEEP_OVERLAY.register((client, context, tickCounter) -> {
+ HudRenderEvents.AFTER_SLEEP_OVERLAY.register((context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() - 240, context.getScaledWindowHeight() / 2 - 10, context.getScaledWindowWidth(), context.getScaledWindowHeight() / 2 + 10, Colors.YELLOW);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "4. This yellow rectangle should be above", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2 - 10, Colors.WHITE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "the sleep overlay but below the scoreboard.", context.getScaledWindowWidth() - 236, context.getScaledWindowHeight() / 2, Colors.WHITE);
});
// Render a blue rectangle at the bottom left of the screen, and it should be blocked by the chat
- HudRenderEvents.BEFORE_CHAT.register((client, context, tickCounter) -> {
+ HudRenderEvents.BEFORE_CHAT.register((context, tickCounter) -> {
context.fill(0, context.getScaledWindowHeight() - 40, 300, context.getScaledWindowHeight() - 50, Colors.BLUE);
context.drawTextWithShadow(MinecraftClient.getInstance().textRenderer, "5. This blue rectangle should be blocked by the chat.", 0, context.getScaledWindowHeight() - 50, Colors.WHITE);
});
// Render a yellow rectangle at the top of the screen, and it should block the player list
- HudRenderEvents.LAST.register((client, context, tickCounter) -> {
+ HudRenderEvents.LAST.register((context, tickCounter) -> {
context.fill(context.getScaledWindowWidth() / 2 - 150, 0, context.getScaledWindowWidth() / 2 + 150, 15, Colors.YELLOW);
context.drawCenteredTextWithShadow(MinecraftClient.getInstance().textRenderer, "6. This yellow rectangle should block the player list.", context.getScaledWindowWidth() / 2, 0, Colors.WHITE);
});
From 4a9d3d8cde4796dbe38860dc8465b306143d3854 Mon Sep 17 00:00:00 2001
From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Date: Fri, 25 Oct 2024 00:15:24 -0400
Subject: [PATCH 11/11] Cleanup InGameHudMixin
---
.../fabric/mixin/client/rendering/InGameHudMixin.java | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
index 0c80d3a582..df8bc84ece 100644
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
+++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/InGameHudMixin.java
@@ -16,16 +16,13 @@
package net.fabricmc.fabric.mixin.client.rendering;
-import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.LayeredDrawer;
import net.minecraft.client.gui.hud.InGameHud;
@@ -36,10 +33,6 @@
@Mixin(InGameHud.class)
public class InGameHudMixin {
- @Shadow
- @Final
- private MinecraftClient client;
-
// Targeting the first addLayer call of the first layered drawer, currently the misc overlays layer (renderMiscOverlays) as of 1.21.
@ModifyArg(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 0))
private LayeredDrawer.Layer fabric$beforeStartAndAfterMiscOverlays(LayeredDrawer.Layer miscOverlaysLayer) {
@@ -79,7 +72,7 @@ public class InGameHudMixin {
// Targeting the last addLayer call of the second layered drawer, currently the subtitles hud layer (subtitlesHud.render) as of 1.21.
@ModifyArg(method = "", slice = @Slice(from = @At(value = "NEW", target = "Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 2)), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/LayeredDrawer;addLayer(Lnet/minecraft/client/gui/LayeredDrawer$Layer;)Lnet/minecraft/client/gui/LayeredDrawer;", ordinal = 7))
- private LayeredDrawer.Layer fabric$AfterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
+ private LayeredDrawer.Layer fabric$afterSubtitlesHud(LayeredDrawer.Layer subtitlesHudLayer) {
return (context, tickCounter) -> {
subtitlesHudLayer.render(context, tickCounter);
HudRenderEvents.LAST.invoker().render(context, tickCounter);