diff --git a/fabric-client-gametest-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/gametest/ClientGameTestTest.java b/fabric-client-gametest-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/gametest/ClientGameTestTest.java
index a724495d58..ed9a2257a2 100644
--- a/fabric-client-gametest-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/gametest/ClientGameTestTest.java
+++ b/fabric-client-gametest-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/gametest/ClientGameTestTest.java
@@ -124,7 +124,7 @@ public void runTest(ClientGameTestContext context) {
private static void waitForTitleScreenFade(ClientGameTestContext context) {
context.waitFor(client -> {
- return !(client.screen instanceof TitleScreenAccessor titleScreen) || !titleScreen.isFading();
+ return (client.screen instanceof TitleScreenAccessor titleScreen) && !titleScreen.isFading();
});
}
diff --git a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandler.java b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandler.java
index d6ab1c151a..fa4b95e128 100644
--- a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandler.java
+++ b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/FluidRenderHandler.java
@@ -21,8 +21,9 @@
import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.client.renderer.block.LiquidBlockRenderer;
-import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.SpriteGetter;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
@@ -95,8 +96,10 @@ default void renderFluid(BlockPos pos, BlockAndTintGetter level, VertexConsumer
*
The "fabric-textures" module contains sprite rendering facilities,
* which may come in handy here.
*
- * @param textureAtlas The blocks texture atlas, provided for convenience.
+ * @param spriteGetter The {@link SpriteGetter} to look up sprites.
+ * @return A {@link ChunkSectionLayer} to indicate the transparency of the fluid.
*/
- default void reloadTextures(TextureAtlas textureAtlas) {
+ default ChunkSectionLayer reloadTextures(SpriteGetter spriteGetter) {
+ return ChunkSectionLayer.SOLID;
}
}
diff --git a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/SimpleFluidRenderHandler.java b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/SimpleFluidRenderHandler.java
index d0b514ef3f..9a8ff82f22 100644
--- a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/SimpleFluidRenderHandler.java
+++ b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/api/client/render/fluid/v1/SimpleFluidRenderHandler.java
@@ -21,10 +21,12 @@
import org.jspecify.annotations.Nullable;
import net.minecraft.client.renderer.block.BlockAndTintGetter;
-import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.ModelBakery;
+import net.minecraft.client.resources.model.SpriteGetter;
+import net.minecraft.client.resources.model.SpriteId;
import net.minecraft.core.BlockPos;
-import net.minecraft.resources.Identifier;
import net.minecraft.world.level.material.FluidState;
/**
@@ -39,34 +41,9 @@
* that.
*/
public class SimpleFluidRenderHandler implements FluidRenderHandler {
- /**
- * The vanilla still water texture identifier.
- */
- public static final Identifier WATER_STILL = Identifier.withDefaultNamespace("block/water_still");
-
- /**
- * The vanilla flowing water texture identifier.
- */
- public static final Identifier WATER_FLOWING = Identifier.withDefaultNamespace("block/water_flow");
-
- /**
- * The vanilla water overlay texture identifier.
- */
- public static final Identifier WATER_OVERLAY = Identifier.withDefaultNamespace("block/water_overlay");
-
- /**
- * The vanilla still lava texture identifier.
- */
- public static final Identifier LAVA_STILL = Identifier.withDefaultNamespace("block/lava_still");
-
- /**
- * The vanilla flowing lava texture identifier.
- */
- public static final Identifier LAVA_FLOWING = Identifier.withDefaultNamespace("block/lava_flow");
-
- protected final Identifier stillTexture;
- protected final Identifier flowingTexture;
- protected final Identifier overlayTexture;
+ protected final SpriteId stillTexture;
+ protected final SpriteId flowingTexture;
+ protected final SpriteId overlayTexture;
protected final TextureAtlasSprite[] sprites;
@@ -83,7 +60,7 @@ public class SimpleFluidRenderHandler implements FluidRenderHandler {
* transparent blocks}.
* @param tint The fluid color RGB. Alpha is ignored.
*/
- public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTexture, @Nullable Identifier overlayTexture, int tint) {
+ public SimpleFluidRenderHandler(SpriteId stillTexture, SpriteId flowingTexture, @Nullable SpriteId overlayTexture, int tint) {
this.stillTexture = Objects.requireNonNull(stillTexture, "stillTexture");
this.flowingTexture = Objects.requireNonNull(flowingTexture, "flowingTexture");
this.overlayTexture = overlayTexture;
@@ -100,7 +77,7 @@ public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTextu
* {@linkplain FluidRenderHandlerRegistry#setBlockTransparency registered
* transparent blocks}.
*/
- public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTexture, Identifier overlayTexture) {
+ public SimpleFluidRenderHandler(SpriteId stillTexture, SpriteId flowingTexture, SpriteId overlayTexture) {
this(stillTexture, flowingTexture, overlayTexture, -1);
}
@@ -112,7 +89,7 @@ public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTextu
* @param flowingTexture The texture for flowing/falling fluid.
* @param tint The fluid color RGB. Alpha is ignored.
*/
- public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTexture, int tint) {
+ public SimpleFluidRenderHandler(SpriteId stillTexture, SpriteId flowingTexture, int tint) {
this(stillTexture, flowingTexture, null, tint);
}
@@ -122,7 +99,7 @@ public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTextu
* @param stillTexture The texture for still fluid.
* @param flowingTexture The texture for flowing/falling fluid.
*/
- public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTexture) {
+ public SimpleFluidRenderHandler(SpriteId stillTexture, SpriteId flowingTexture) {
this(stillTexture, flowingTexture, null, -1);
}
@@ -131,12 +108,12 @@ public SimpleFluidRenderHandler(Identifier stillTexture, Identifier flowingTextu
* fixed, custom color.
*
* @param tint The fluid color RGB. Alpha is ignored.
- * @see #WATER_STILL
- * @see #WATER_FLOWING
- * @see #WATER_OVERLAY
+ * @see ModelBakery#WATER_STILL
+ * @see ModelBakery#WATER_FLOW
+ * @see ModelBakery#WATER_OVERLAY
*/
public static SimpleFluidRenderHandler coloredWater(int tint) {
- return new SimpleFluidRenderHandler(WATER_STILL, WATER_FLOWING, WATER_OVERLAY, tint);
+ return new SimpleFluidRenderHandler(ModelBakery.WATER_STILL, ModelBakery.WATER_FLOW, ModelBakery.WATER_OVERLAY, tint);
}
/**
@@ -151,13 +128,15 @@ public TextureAtlasSprite[] getFluidSprites(@Nullable BlockAndTintGetter level,
* {@inheritDoc}
*/
@Override
- public void reloadTextures(TextureAtlas textureAtlas) {
- sprites[0] = textureAtlas.getSprite(stillTexture);
- sprites[1] = textureAtlas.getSprite(flowingTexture);
+ public ChunkSectionLayer reloadTextures(SpriteGetter spriteGetter) {
+ sprites[0] = spriteGetter.get(stillTexture);
+ sprites[1] = spriteGetter.get(flowingTexture);
if (overlayTexture != null) {
- sprites[2] = textureAtlas.getSprite(overlayTexture);
+ sprites[2] = spriteGetter.get(overlayTexture);
}
+
+ return ChunkSectionLayer.byTransparency(sprites[0].transparency().or(sprites[1].transparency()));
}
/**
diff --git a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/fluid/FluidRenderHandlerRegistryImpl.java b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/fluid/FluidRenderHandlerRegistryImpl.java
index 7656b0ea03..65761c8ca2 100644
--- a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/fluid/FluidRenderHandlerRegistryImpl.java
+++ b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/fluid/FluidRenderHandlerRegistryImpl.java
@@ -23,14 +23,13 @@
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
import org.jspecify.annotations.Nullable;
-import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.client.renderer.block.LiquidBlockRenderer;
-import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.SpriteGetter;
import net.minecraft.core.BlockPos;
-import net.minecraft.data.AtlasIds;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HalfTransparentBlock;
@@ -85,19 +84,29 @@ public boolean isBlockTransparent(Block block) {
return transparencyForOverlay.getOrDefault(block, block instanceof HalfTransparentBlock || block instanceof LeavesBlock);
}
- public void onFluidRendererReload(LiquidBlockRenderer renderer, TextureAtlasSprite[] waterSprites, TextureAtlasSprite[] lavaSprites, TextureAtlasSprite waterOverlay) {
+ public Map onFluidRendererReload(SpriteGetter spriteGetter, LiquidBlockRenderer renderer, TextureAtlasSprite[] waterSprites, TextureAtlasSprite[] lavaSprites, TextureAtlasSprite waterOverlay) {
FluidRenderingImpl.setVanillaRenderer(renderer);
WaterRenderHandler.INSTANCE.updateSprites(waterSprites, waterOverlay);
LavaRenderHandler.INSTANCE.updateSprites(lavaSprites);
- TextureAtlas texture = Minecraft.getInstance()
- .getAtlasManager()
- .getAtlasOrThrow(AtlasIds.BLOCKS);
+ Map fluidChunkSectionLayers = new IdentityHashMap<>();
- for (FluidRenderHandler handler : handlers.values()) {
- handler.reloadTextures(texture);
+ // Multiple fluids may share the same handler, so we need to avoid reloading the same handler multiple times.
+ Map loadedHandlers = new IdentityHashMap<>();
+
+ for (Map.Entry entry : handlers.entrySet()) {
+ ChunkSectionLayer chunkSectionLayer = loadedHandlers.get(entry.getValue());
+
+ if (chunkSectionLayer == null) {
+ chunkSectionLayer = entry.getValue().reloadTextures(spriteGetter);
+ loadedHandlers.put(entry.getValue(), chunkSectionLayer);
+ }
+
+ fluidChunkSectionLayers.put(entry.getKey(), chunkSectionLayer);
}
+
+ return fluidChunkSectionLayers;
}
private static class WaterRenderHandler implements FluidRenderHandler {
diff --git a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/fluid/LiquidBlockRendererMixin.java b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/fluid/LiquidBlockRendererMixin.java
index 0dd96aa5c4..dfccceb080 100644
--- a/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/fluid/LiquidBlockRendererMixin.java
+++ b/fabric-rendering-fluids-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/fluid/LiquidBlockRendererMixin.java
@@ -16,6 +16,9 @@
package net.fabricmc.fabric.mixin.client.rendering.fluid;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
import com.llamalad7.mixinextras.expression.Definition;
import com.llamalad7.mixinextras.expression.Expression;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
@@ -26,6 +29,7 @@
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@@ -36,10 +40,13 @@
import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.client.renderer.block.LiquidBlockRenderer;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.SpriteGetter;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
@@ -70,10 +77,19 @@ public class LiquidBlockRendererMixin {
@Final
private TextureAtlasSprite lavaFlowing;
+ @Shadow
+ @Final
+ @Mutable
+ private Map layerByFluid;
+
@Inject(method = "", at = @At("RETURN"))
- public void onResourceReloadReturn(CallbackInfo info) {
+ public void onResourceReloadReturn(SpriteGetter sprites, CallbackInfo info) {
LiquidBlockRenderer self = (LiquidBlockRenderer) (Object) this;
- ((FluidRenderHandlerRegistryImpl) FluidRenderHandlerRegistry.INSTANCE).onFluidRendererReload(self, new TextureAtlasSprite[]{waterStill, waterFlowing, waterOverlay}, new TextureAtlasSprite[]{lavaStill, lavaFlowing}, waterOverlay);
+ Map moddedLayers = ((FluidRenderHandlerRegistryImpl) FluidRenderHandlerRegistry.INSTANCE).onFluidRendererReload(sprites, self, new TextureAtlasSprite[]{waterStill, waterFlowing, waterOverlay}, new TextureAtlasSprite[]{lavaStill, lavaFlowing}, waterOverlay);
+
+ Map layers = new IdentityHashMap<>(this.layerByFluid);
+ layers.putAll(moddedLayers);
+ this.layerByFluid = Map.copyOf(layers);
}
@Inject(method = "tesselate", at = @At("HEAD"), cancellable = true)
diff --git a/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/CustomizedFluidRenderer.java b/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/CustomizedFluidRenderer.java
index dcb9f433f7..e4bc4c5482 100644
--- a/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/CustomizedFluidRenderer.java
+++ b/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/CustomizedFluidRenderer.java
@@ -20,15 +20,15 @@
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.client.resources.model.SpriteId;
import net.minecraft.core.BlockPos;
-import net.minecraft.resources.Identifier;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.fabricmc.fabric.api.client.render.fluid.v1.SimpleFluidRenderHandler;
public class CustomizedFluidRenderer extends SimpleFluidRenderHandler {
- public CustomizedFluidRenderer(Identifier overlayTexture) {
+ public CustomizedFluidRenderer(SpriteId overlayTexture) {
super(overlayTexture, overlayTexture, overlayTexture);
}
diff --git a/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/FabricFluidRenderingTestModClient.java b/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/FabricFluidRenderingTestModClient.java
index 25fc862201..496b4f7aab 100644
--- a/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/FabricFluidRenderingTestModClient.java
+++ b/fabric-rendering-fluids-v1/src/testmodClient/java/net/fabricmc/fabric/test/client/rendering/fluid/FabricFluidRenderingTestModClient.java
@@ -16,6 +16,7 @@
package net.fabricmc.fabric.test.client.rendering.fluid;
+import net.minecraft.client.renderer.Sheets;
import net.minecraft.resources.Identifier;
import net.minecraft.world.level.block.Blocks;
@@ -41,20 +42,20 @@ public void onInitializeClient() {
FluidRenderHandlerRegistry.INSTANCE.setBlockTransparency(Blocks.RED_STAINED_GLASS, false);
FluidRenderHandlerRegistry.INSTANCE.register(TestFluids.NO_OVERLAY, TestFluids.NO_OVERLAY_FLOWING, new SimpleFluidRenderHandler(
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_still"),
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_flowing"),
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_still")),
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_flowing")),
0xFF5555
));
FluidRenderHandlerRegistry.INSTANCE.register(TestFluids.OVERLAY, TestFluids.OVERLAY_FLOWING, new SimpleFluidRenderHandler(
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_still"),
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_flowing"),
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_overlay"),
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_still")),
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_flowing")),
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_overlay")),
0x5555FF
));
FluidRenderHandlerRegistry.INSTANCE.register(TestFluids.CUSTOM, TestFluids.CUSTOM_FLOWING, new CustomizedFluidRenderer(
- Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "block/test_fluid_overlay")
+ Sheets.BLOCKS_MAPPER.apply(Identifier.fromNamespaceAndPath("fabric-rendering-fluids-v1-testmod", "test_fluid_overlay"))
));
}
}
diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/ChunkSectionLayerMapImpl.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/ChunkSectionLayerMapImpl.java
deleted file mode 100644
index 60fe0c2fb4..0000000000
--- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/impl/client/rendering/ChunkSectionLayerMapImpl.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.impl.client.rendering;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.BiConsumer;
-
-import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
-import net.minecraft.world.level.material.Fluid;
-
-public final class ChunkSectionLayerMapImpl {
- private static final Map FLUID_RENDER_LAYER_MAP = new HashMap<>();
-
- // These consumers initially add to the maps above, and then are later set (when setup is called) to insert straight into the target map.
- private static BiConsumer fluidHandler = FLUID_RENDER_LAYER_MAP::put;
-
- public static void putFluid(Fluid fluid, ChunkSectionLayer layer) {
- Objects.requireNonNull(fluid, "fluid must not be null");
- Objects.requireNonNull(layer, "render layer must not be null");
-
- fluidHandler.accept(fluid, layer);
- }
-
- public static void setup(BiConsumer vanillaFluidHandler) {
- // Add all the preexisting render layers
- FLUID_RENDER_LAYER_MAP.forEach(vanillaFluidHandler);
-
- // Set the handlers to directly accept later additions
- fluidHandler = vanillaFluidHandler;
- }
-
- private ChunkSectionLayerMapImpl() {
- }
-}
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/LevelRenderEventsTests.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/LevelRenderEventsTests.java
index 3f3db87e4a..8ec10c383f 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/LevelRenderEventsTests.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/LevelRenderEventsTests.java
@@ -17,8 +17,9 @@
package net.fabricmc.fabric.test.rendering.client;
import com.mojang.blaze3d.vertex.PoseStack;
+import org.jspecify.annotations.Nullable;
-import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.block.BlockModelResolver;
import net.minecraft.client.renderer.rendertype.RenderTypes;
import net.minecraft.client.renderer.state.BlockOutlineRenderState;
import net.minecraft.core.BlockPos;
@@ -43,6 +44,8 @@
public class LevelRenderEventsTests implements ClientModInitializer, FabricClientGameTest {
private static final RenderStateDataKey DIAMOND_BLOCK_OUTLINE = RenderStateDataKey.create(() -> "fabric api test mod block outline diamond block");
+ @Nullable
+ private static BlockModelResolver blockModelResolver = null;
private static void extractBlockOutline(LevelExtractionContext context, HitResult hitResult) {
if (hitResult instanceof BlockHitResult blockHitResult && blockHitResult.getType() != HitResult.Type.MISS && context.level().getBlockState(blockHitResult.getBlockPos()).is(Blocks.DIAMOND_BLOCK)) {
@@ -52,23 +55,18 @@ private static void extractBlockOutline(LevelExtractionContext context, HitResul
private static boolean beforeBlockOutline(LevelRenderContext context, BlockOutlineRenderState outlineRenderState) {
if (Boolean.TRUE.equals(outlineRenderState.getData(DIAMOND_BLOCK_OUTLINE))) {
- PoseStack poseStack = new PoseStack();
+ PoseStack poseStack = context.poseStack();
poseStack.pushPose();
- Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().position();
+ Vec3 cameraPos = context.levelState().cameraRenderState.pos;
BlockPos pos = outlineRenderState.pos();
double x = pos.getX() - cameraPos.x;
double y = pos.getY() - cameraPos.y;
double z = pos.getZ() - cameraPos.z;
poseStack.translate(x + 0.25, y + 0.25 + 1, z + 0.25);
poseStack.scale(0.5f, 0.5f, 0.5f);
-
- /* TODO 26.1
- Minecraft.getInstance().getBlockRenderer().renderSingleBlock(
- Blocks.DIAMOND_BLOCK.defaultBlockState(),
- poseStack, context.bufferSource(), 15728880, OverlayTexture.NO_OVERLAY
- );
- */
-
+ AABB box = new AABB(0, 0, 0, 1, 1, 1);
+ int green = ARGB.colorFromFloat(1.0f, 0, 1, 0);
+ TestRenderUtils.drawFilledBox(poseStack, context.bufferSource().getBuffer(RenderTypes.debugFilledBox()), box, green);
poseStack.popPose();
}
@@ -121,7 +119,6 @@ public void runTest(ClientGameTestContext context) {
singleplayer.getServer().runCommand("/tp @a 0 100 -3");
singleplayer.getServer().runCommand("/setblock 0 101 0 minecraft:diamond_block");
singleplayer.getClientLevel().waitForChunksRender();
-
context.assertScreenshotEquals(TestScreenshotComparisonOptions.of("level_render_events_block_outline_and_after_translucent").withRegion(356, 98, 142, 238).save());
}
}
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/RenderLayerTest.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/RenderLayerTest.java
index a7563ca5f3..9fe4c727a9 100644
--- a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/RenderLayerTest.java
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/RenderLayerTest.java
@@ -16,23 +16,30 @@
package net.fabricmc.fabric.test.rendering.client;
+import java.util.Objects;
+
import com.mojang.blaze3d.vertex.PoseStack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.client.model.player.PlayerModel;
import net.minecraft.client.renderer.SubmitNodeCollector;
+import net.minecraft.client.renderer.block.BlockModelRenderState;
import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.client.renderer.entity.player.AvatarRenderer;
import net.minecraft.client.renderer.entity.state.AvatarRenderState;
+import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.entity.EntityType;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityRenderLayerRegistrationCallback;
+import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey;
public final class RenderLayerTest implements ClientModInitializer {
+ public static RenderStateDataKey DIAMOND_BLOCK = RenderStateDataKey.create(() -> "fabric api test mod diamond block render state");
+
private static final Logger LOGGER = LoggerFactory.getLogger(RenderLayerTest.class);
private int playerRegistrations = 0;
@@ -73,13 +80,12 @@ private static class TestPlayerRenderLayer extends RenderLayer {
+ @Unique
+ private BlockModelResolver blockModelResolver;
+
+ @Inject(method = "", at = @At("RETURN"))
+ private void init(EntityRendererProvider.Context context, boolean slimSteve, CallbackInfo ci) {
+ blockModelResolver = context.getBlockModelResolver();
+ }
+
+ @Inject(method = "extractRenderState(Lnet/minecraft/world/entity/Avatar;Lnet/minecraft/client/renderer/entity/state/AvatarRenderState;F)V", at = @At("RETURN"))
+ private void extractRenderState(AvatarlikeEntity entity, AvatarRenderState state, float partialTicks, CallbackInfo ci) {
+ if (!(entity instanceof LocalPlayer player)) {
+ return;
+ }
+
+ BlockModelRenderState blockRenderState = state.getData(RenderLayerTest.DIAMOND_BLOCK);
+
+ if (blockRenderState == null) {
+ blockRenderState = new BlockModelRenderState();
+ state.setData(RenderLayerTest.DIAMOND_BLOCK, blockRenderState);
+ }
+
+ this.blockModelResolver.update(blockRenderState, Blocks.DIAMOND_BLOCK.defaultBlockState());
+ }
+}
diff --git a/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/mixin/MinecraftAccessor.java b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/mixin/MinecraftAccessor.java
new file mode 100644
index 0000000000..e1edfed3ed
--- /dev/null
+++ b/fabric-rendering-v1/src/testmodClient/java/net/fabricmc/fabric/test/rendering/client/mixin/MinecraftAccessor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.mixin;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.block.BlockModelResolver;
+
+@Mixin(Minecraft.class)
+public interface MinecraftAccessor {
+ @Accessor
+ BlockModelResolver getBlockModelResolver();
+}
diff --git a/fabric-rendering-v1/src/testmodClient/resources/fabric-rendering-v1-testmod.client.mixins.json b/fabric-rendering-v1/src/testmodClient/resources/fabric-rendering-v1-testmod.client.mixins.json
index 390d18ccb2..50a0c6eccf 100644
--- a/fabric-rendering-v1/src/testmodClient/resources/fabric-rendering-v1-testmod.client.mixins.json
+++ b/fabric-rendering-v1/src/testmodClient/resources/fabric-rendering-v1-testmod.client.mixins.json
@@ -3,9 +3,11 @@
"package": "net.fabricmc.fabric.test.rendering.client.mixin",
"compatibilityLevel": "JAVA_25",
"client": [
+ "AvatarRendererMixin",
"GameRendererAccessor",
"GuiRendererAccessor",
- "PigRendererMixin"
+ "PigRendererMixin",
+ "MinecraftAccessor"
],
"injectors": {
"defaultRequire": 1
diff --git a/fabric-rendering-v1/src/testmodClient/resources/templates/level_render_events_block_outline_and_after_translucent.png b/fabric-rendering-v1/src/testmodClient/resources/templates/level_render_events_block_outline_and_after_translucent.png
index 3d1b5c652d..f54ca7272b 100644
Binary files a/fabric-rendering-v1/src/testmodClient/resources/templates/level_render_events_block_outline_and_after_translucent.png and b/fabric-rendering-v1/src/testmodClient/resources/templates/level_render_events_block_outline_and_after_translucent.png differ