Fix a WorldRenderEvents.BLOCK_OUTLINE bug (#1319)

* Fix bug related to immediate mode VCP

* Add testmod
This commit is contained in:
Technici4n 2021-04-14 19:40:14 +02:00 committed by GitHub
parent f801c28735
commit 6d5e24549f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 7 deletions

View file

@ -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();

View file

@ -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

View file

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

View file

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

View file

@ -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"
]
}
}