diff --git a/fabric-transfer-api-v1/build.gradle b/fabric-transfer-api-v1/build.gradle index 1d7adaddb..eaa5e0034 100644 --- a/fabric-transfer-api-v1/build.gradle +++ b/fabric-transfer-api-v1/build.gradle @@ -11,6 +11,7 @@ moduleDependencies(project, [ dependencies { testmodImplementation project(path: ':fabric-object-builder-api-v1', configuration: 'dev') + testmodImplementation project(path: ':fabric-rendering-v1', configuration: 'dev') testmodImplementation project(path: ':fabric-resource-loader-v0', configuration: 'dev') testmodImplementation project(path: ':fabric-tag-extensions-v0', configuration: 'dev') testmodImplementation project(path: ':fabric-tool-attribute-api-v1', configuration: 'dev') diff --git a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRenderHandler.java b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRenderHandler.java index 326808560..f2b904543 100644 --- a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRenderHandler.java +++ b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRenderHandler.java @@ -24,6 +24,8 @@ import org.jetbrains.annotations.Nullable; import net.minecraft.client.item.TooltipContext; import net.minecraft.client.texture.Sprite; import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.BlockRenderView; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -76,14 +78,29 @@ public interface FluidVariantRenderHandler { } /** - * Return the color to use when rendering {@linkplain #getSprite the sprite} of this fluid variant. + * @deprecated Use and implement {@linkplain #getColor(FluidVariant, BlockRenderView, BlockPos) the other more general overload}. + * This one will be removed in a future iteration of the API. */ + @Deprecated(forRemoval = true) default int getColor(FluidVariant fluidVariant) { + return getColor(fluidVariant, null, null); + } + + /** + * Return the color to use when rendering {@linkplain #getSprite the sprite} of this fluid variant. + * Transparency (alpha) will generally be taken into account and should be specified as well. + * + * <p>The world and position are optional context parameters and may be {@code null}. + * If they are null, this method must return a location-independent color. + * If they are provided, this method may return a color that depends on the location. + * For example, water returns the biome-dependent color if the context parameters are specified, or its default color if one of them is null. + */ + default int getColor(FluidVariant fluidVariant, @Nullable BlockRenderView view, @Nullable BlockPos pos) { // Use the fluid render handler by default. FluidRenderHandler fluidRenderHandler = FluidRenderHandlerRegistry.INSTANCE.get(fluidVariant.getFluid()); if (fluidRenderHandler != null) { - return fluidRenderHandler.getFluidColor(null, null, fluidVariant.getFluid().getDefaultState()); + return fluidRenderHandler.getFluidColor(view, pos, fluidVariant.getFluid().getDefaultState()) | 255 << 24; } else { return -1; } diff --git a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRendering.java b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRendering.java index 99a72a625..b2f9bc397 100644 --- a/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRendering.java +++ b/fabric-transfer-api-v1/src/main/java/net/fabricmc/fabric/api/transfer/v1/client/fluid/FluidVariantRendering.java @@ -22,13 +22,16 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.item.TooltipContext; import net.minecraft.client.texture.Sprite; import net.minecraft.fluid.Fluid; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; +import net.minecraft.world.BlockRenderView; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -81,7 +84,17 @@ public class FluidVariantRendering { } /** - * Return the tooltip for the passed fluid variant, including the name and additional lines if available + * Return a mutable list: the tooltip for the passed fluid variant, including the name and additional lines if available + * and the id of the fluid if advanced tooltips are enabled. + * + * <p>Compared to {@linkplain #getTooltip(FluidVariant, TooltipContext) the other overload}, the current tooltip context is automatically used. + */ + public static List<Text> getTooltip(FluidVariant fluidVariant) { + return getTooltip(fluidVariant, MinecraftClient.getInstance().options.advancedItemTooltips ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL); + } + + /** + * Return a mutable list: the tooltip for the passed fluid variant, including the name and additional lines if available * and the id of the fluid if advanced tooltips are enabled. */ public static List<Text> getTooltip(FluidVariant fluidVariant, TooltipContext context) { @@ -113,10 +126,21 @@ public class FluidVariantRendering { } /** - * Return the color that should be used to render {@linkplain #getSprite the sprite} of the passed fluid variant. + * Return the position-independent color that should be used to render {@linkplain #getSprite the sprite} of the passed fluid variant. */ public static int getColor(FluidVariant fluidVariant) { - return getHandlerOrDefault(fluidVariant.getFluid()).getColor(fluidVariant); + return getColor(fluidVariant, null, null); + } + + /** + * Return the color that should be used when rendering {@linkplain #getSprite the sprite} of the passed fluid variant. + * + * <p>If the world and the position parameters are null, a position-independent color is returned. + * If the world and position parameters are not null, the color may depend on the position. + * For example, if world and position are passed, water will use them to return a biome-dependent color. + */ + public static int getColor(FluidVariant fluidVariant, @Nullable BlockRenderView view, @Nullable BlockPos pos) { + return getHandlerOrDefault(fluidVariant.getFluid()).getColor(fluidVariant, view, pos); } /** diff --git a/fabric-transfer-api-v1/src/testmod/java/net/fabricmc/fabric/test/transfer/ingame/client/FluidVariantRenderTest.java b/fabric-transfer-api-v1/src/testmod/java/net/fabricmc/fabric/test/transfer/ingame/client/FluidVariantRenderTest.java new file mode 100644 index 000000000..353d5a6af --- /dev/null +++ b/fabric-transfer-api-v1/src/testmod/java/net/fabricmc/fabric/test/transfer/ingame/client/FluidVariantRenderTest.java @@ -0,0 +1,89 @@ +/* + * 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.transfer.ingame.client; + +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferRenderer; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormat; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.texture.SpriteAtlasTexture; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluids; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Matrix4f; +import net.minecraft.world.World; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.fabricmc.fabric.api.transfer.v1.client.fluid.FluidVariantRendering; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; + +/** + * Renders the water sprite in the top left of the screen, to make sure that it correctly depends on the position. + */ +public class FluidVariantRenderTest implements ClientModInitializer { + @Override + public void onInitializeClient() { + HudRenderCallback.EVENT.register((matrices, tickDelta) -> { + PlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) return; + drawFluidInGui(matrices, FluidVariant.of(Fluids.WATER), player.world, player.getBlockPos(), 0, 0); + }); + } + + private static void drawFluidInGui(MatrixStack ms, FluidVariant fluid, World world, BlockPos pos, int i, int j) { + RenderSystem.setShaderTexture(0, SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE); + Sprite sprite = FluidVariantRendering.getSprite(fluid); + int color = FluidVariantRendering.getColor(fluid, world, pos); + + if (sprite == null) return; + + float r = ((color >> 16) & 255) / 255f; + float g = ((color >> 8) & 255) / 255f; + float b = (color & 255) / 255f; + RenderSystem.disableDepthTest(); + + RenderSystem.setShader(GameRenderer::getPositionColorTexShader); + BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer(); + bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE); + float x0 = (float) i; + float y0 = (float) j; + float x1 = x0 + 16; + float y1 = y0 + 16; + float z = 0.5f; + float u0 = sprite.getMinU(); + float v0 = sprite.getMinV(); + float u1 = sprite.getMaxU(); + float v1 = sprite.getMaxV(); + Matrix4f model = ms.peek().getModel(); + bufferBuilder.vertex(model, x0, y1, z).color(r, g, b, 1).texture(u0, v1).next(); + bufferBuilder.vertex(model, x1, y1, z).color(r, g, b, 1).texture(u1, v1).next(); + bufferBuilder.vertex(model, x1, y0, z).color(r, g, b, 1).texture(u1, v0).next(); + bufferBuilder.vertex(model, x0, y0, z).color(r, g, b, 1).texture(u0, v0).next(); + bufferBuilder.end(); + BufferRenderer.draw(bufferBuilder); + + RenderSystem.enableDepthTest(); + } +} diff --git a/fabric-transfer-api-v1/src/testmod/resources/fabric.mod.json b/fabric-transfer-api-v1/src/testmod/resources/fabric.mod.json index aa6036370..3bf8edfba 100644 --- a/fabric-transfer-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-transfer-api-v1/src/testmod/resources/fabric.mod.json @@ -12,6 +12,9 @@ "main": [ "net.fabricmc.fabric.test.transfer.ingame.TransferTestInitializer", "net.fabricmc.fabric.test.transfer.unittests.UnitTestsInitializer" + ], + "client": [ + "net.fabricmc.fabric.test.transfer.ingame.client.FluidVariantRenderTest" ] } }