From 6d5e24549f1c6faa51b432ca03a507d6b30719ab Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Wed, 14 Apr 2021 19:40:14 +0200 Subject: [PATCH] Fix a WorldRenderEvents.BLOCK_OUTLINE bug (#1319) * Fix bug related to immediate mode VCP * Add testmod --- .../rendering/v1/WorldRenderContext.java | 6 +- .../rendering/WorldRenderContextImpl.java | 6 +- .../client/rendering/MixinWorldRenderer.java | 8 ++- .../client/WorldRenderEventsTests.java | 56 +++++++++++++++++++ .../src/testmod/resources/fabric.mod.json | 3 +- 5 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/WorldRenderEventsTests.java diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/WorldRenderContext.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/WorldRenderContext.java index 4eebdd015..5abba02ed 100644 --- a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/WorldRenderContext.java +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/WorldRenderContext.java @@ -120,7 +120,11 @@ public interface WorldRenderContext { * {@code WorldRenderer.drawBlockOutline}. */ @Environment(EnvType.CLIENT) - public interface BlockOutlineContext { + interface BlockOutlineContext { + /** + * @deprecated Use {@link #consumers()} directly. + */ + @Deprecated VertexConsumer vertexConsumer(); Entity entity(); diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/WorldRenderContextImpl.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/WorldRenderContextImpl.java index 4d47cedda..095780bf1 100644 --- a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/WorldRenderContextImpl.java +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/WorldRenderContextImpl.java @@ -21,6 +21,7 @@ import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.LightmapTextureManager; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.WorldRenderer; @@ -52,7 +53,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut private boolean advancedTranslucency; private ClientWorld world; - private VertexConsumer vertexConsumer; private Entity entity; private double cameraX; private double cameraY; @@ -97,7 +97,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut } public void prepareBlockOutline( - VertexConsumer vertexConsumer, Entity entity, double cameraX, double cameraY, @@ -105,7 +104,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut BlockPos blockPos, BlockState blockState ) { - this.vertexConsumer = vertexConsumer; this.entity = entity; this.cameraX = cameraX; this.cameraY = cameraY; @@ -186,7 +184,7 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut @Override public VertexConsumer vertexConsumer() { - return vertexConsumer; + return consumers.getBuffer(RenderLayer.getLines()); } @Override diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinWorldRenderer.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinWorldRenderer.java index dacc11957..4b9260590 100644 --- a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinWorldRenderer.java +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinWorldRenderer.java @@ -32,6 +32,7 @@ import net.minecraft.client.render.Camera; import net.minecraft.client.render.Frustum; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.LightmapTextureManager; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.util.math.MatrixStack; @@ -97,6 +98,7 @@ public abstract class MixinWorldRenderer { context.renderBlockOutline = WorldRenderEvents.BEFORE_BLOCK_OUTLINE.invoker().beforeBlockOutline(context, client.crosshairTarget); } + @SuppressWarnings("ConstantConditions") @Inject(method = "drawBlockOutline", at = @At("HEAD"), cancellable = true) private void onDrawBlockOutline(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double cameraX, double cameraY, double cameraZ, BlockPos blockPos, BlockState blockState, CallbackInfo ci) { if (!context.renderBlockOutline) { @@ -104,11 +106,15 @@ public abstract class MixinWorldRenderer { // fire the BLOCK_OUTLINE event per contract of the API. ci.cancel(); } else { - context.prepareBlockOutline(vertexConsumer, entity, cameraX, cameraY, cameraZ, blockPos, blockState); + context.prepareBlockOutline(entity, cameraX, cameraY, cameraZ, blockPos, blockState); if (!WorldRenderEvents.BLOCK_OUTLINE.invoker().onBlockOutline(context, context)) { ci.cancel(); } + + // The immediate mode VertexConsumers use a shared buffer, so we have to make sure that the immediate mode VCP + // can accept block outline lines rendered to the existing vertexConsumer by the vanilla block overlay. + context.consumers().getBuffer(RenderLayer.getLines()); } } diff --git a/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/WorldRenderEventsTests.java b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/WorldRenderEventsTests.java new file mode 100644 index 000000000..029649c87 --- /dev/null +++ b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/WorldRenderEventsTests.java @@ -0,0 +1,56 @@ +/* + * 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.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; + +public class WorldRenderEventsTests implements ClientModInitializer { + private static boolean onBlockOutline(WorldRenderContext wrc, WorldRenderContext.BlockOutlineContext blockOutlineContext) { + if (blockOutlineContext.blockState().isOf(Blocks.DIAMOND_BLOCK)) { + wrc.matrixStack().push(); + Vec3d cameraPos = MinecraftClient.getInstance().gameRenderer.getCamera().getPos(); + BlockPos pos = blockOutlineContext.blockPos(); + double x = pos.getX() - cameraPos.x; + double y = pos.getY() - cameraPos.y; + double z = pos.getZ() - cameraPos.z; + wrc.matrixStack().translate(x+0.25, y+0.25+1, z+0.25); + wrc.matrixStack().scale(0.5f, 0.5f, 0.5f); + + MinecraftClient.getInstance().getBlockRenderManager().renderBlockAsEntity( + Blocks.DIAMOND_BLOCK.getDefaultState(), + wrc.matrixStack(), wrc.consumers(), 15728880, OverlayTexture.DEFAULT_UV); + + wrc.matrixStack().pop(); + } + + return true; + } + + // Renders a diamond block above diamond blocks when they are looked at. + @Override + public void onInitializeClient() { + WorldRenderEvents.BLOCK_OUTLINE.register(WorldRenderEventsTests::onBlockOutline); + } +} diff --git a/fabric-rendering-v1/src/testmod/resources/fabric.mod.json b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json index 342edb10e..815ae0034 100644 --- a/fabric-rendering-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json @@ -13,7 +13,8 @@ "net.fabricmc.fabric.test.rendering.CustomArmorTests" ], "client": [ - "net.fabricmc.fabric.test.rendering.client.CustomArmorTestsClient" + "net.fabricmc.fabric.test.rendering.client.CustomArmorTestsClient", + "net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests" ] } }