Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -95,8 +96,10 @@ default void renderFluid(BlockPos pos, BlockAndTintGetter level, VertexConsumer
* <p>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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

/**
Expand All @@ -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()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Fluid, ChunkSectionLayer> 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<Fluid, ChunkSectionLayer> 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<FluidRenderHandler, ChunkSectionLayer> loadedHandlers = new IdentityHashMap<>();

for (Map.Entry<Fluid, FluidRenderHandler> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -70,10 +77,19 @@ public class LiquidBlockRendererMixin {
@Final
private TextureAtlasSprite lavaFlowing;

@Shadow
@Final
@Mutable
private Map<Fluid, ChunkSectionLayer> layerByFluid;

@Inject(method = "<init>", 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<Fluid, ChunkSectionLayer> moddedLayers = ((FluidRenderHandlerRegistryImpl) FluidRenderHandlerRegistry.INSTANCE).onFluidRendererReload(sprites, self, new TextureAtlasSprite[]{waterStill, waterFlowing, waterOverlay}, new TextureAtlasSprite[]{lavaStill, lavaFlowing}, waterOverlay);

Map<Fluid, ChunkSectionLayer> layers = new IdentityHashMap<>(this.layerByFluid);
layers.putAll(moddedLayers);
this.layerByFluid = Map.copyOf(layers);
}

@Inject(method = "tesselate", at = @At("HEAD"), cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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"))
));
}
}

This file was deleted.

Loading
Loading