mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-22 23:58:02 -05:00
Fix a WorldRenderEvents.BLOCK_OUTLINE bug (#1319)
* Fix bug related to immediate mode VCP
* Add testmod
(cherry picked from commit 6d5e24549f
)
This commit is contained in:
parent
aaa30be003
commit
78c482ee45
5 changed files with 89 additions and 6 deletions
|
@ -120,7 +120,11 @@ public interface WorldRenderContext {
|
||||||
* {@code WorldRenderer.drawBlockOutline}.
|
* {@code WorldRenderer.drawBlockOutline}.
|
||||||
*/
|
*/
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public interface BlockOutlineContext {
|
interface BlockOutlineContext {
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #consumers()} directly.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
VertexConsumer vertexConsumer();
|
VertexConsumer vertexConsumer();
|
||||||
|
|
||||||
Entity entity();
|
Entity entity();
|
||||||
|
|
|
@ -21,6 +21,7 @@ import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.Frustum;
|
import net.minecraft.client.render.Frustum;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
import net.minecraft.client.render.LightmapTextureManager;
|
import net.minecraft.client.render.LightmapTextureManager;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
import net.minecraft.client.render.VertexConsumerProvider;
|
||||||
import net.minecraft.client.render.WorldRenderer;
|
import net.minecraft.client.render.WorldRenderer;
|
||||||
|
@ -52,7 +53,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut
|
||||||
private boolean advancedTranslucency;
|
private boolean advancedTranslucency;
|
||||||
private ClientWorld world;
|
private ClientWorld world;
|
||||||
|
|
||||||
private VertexConsumer vertexConsumer;
|
|
||||||
private Entity entity;
|
private Entity entity;
|
||||||
private double cameraX;
|
private double cameraX;
|
||||||
private double cameraY;
|
private double cameraY;
|
||||||
|
@ -97,7 +97,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareBlockOutline(
|
public void prepareBlockOutline(
|
||||||
VertexConsumer vertexConsumer,
|
|
||||||
Entity entity,
|
Entity entity,
|
||||||
double cameraX,
|
double cameraX,
|
||||||
double cameraY,
|
double cameraY,
|
||||||
|
@ -105,7 +104,6 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut
|
||||||
BlockPos blockPos,
|
BlockPos blockPos,
|
||||||
BlockState blockState
|
BlockState blockState
|
||||||
) {
|
) {
|
||||||
this.vertexConsumer = vertexConsumer;
|
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.cameraX = cameraX;
|
this.cameraX = cameraX;
|
||||||
this.cameraY = cameraY;
|
this.cameraY = cameraY;
|
||||||
|
@ -186,7 +184,7 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer vertexConsumer() {
|
public VertexConsumer vertexConsumer() {
|
||||||
return vertexConsumer;
|
return consumers.getBuffer(RenderLayer.getLines());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,6 +32,7 @@ import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.Frustum;
|
import net.minecraft.client.render.Frustum;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
import net.minecraft.client.render.LightmapTextureManager;
|
import net.minecraft.client.render.LightmapTextureManager;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.render.WorldRenderer;
|
import net.minecraft.client.render.WorldRenderer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
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);
|
context.renderBlockOutline = WorldRenderEvents.BEFORE_BLOCK_OUTLINE.invoker().beforeBlockOutline(context, client.crosshairTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
@Inject(method = "drawBlockOutline", at = @At("HEAD"), cancellable = true)
|
@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) {
|
private void onDrawBlockOutline(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double cameraX, double cameraY, double cameraZ, BlockPos blockPos, BlockState blockState, CallbackInfo ci) {
|
||||||
if (!context.renderBlockOutline) {
|
if (!context.renderBlockOutline) {
|
||||||
|
@ -104,11 +106,15 @@ public abstract class MixinWorldRenderer {
|
||||||
// fire the BLOCK_OUTLINE event per contract of the API.
|
// fire the BLOCK_OUTLINE event per contract of the API.
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
} else {
|
} 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)) {
|
if (!WorldRenderEvents.BLOCK_OUTLINE.invoker().onBlockOutline(context, context)) {
|
||||||
ci.cancel();
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
19
fabric-rendering-v1/src/testmod/resources/fabric.mod.json
Normal file
19
fabric-rendering-v1/src/testmod/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "fabric-rendering-v1-testmod",
|
||||||
|
"name": "Fabric Rendering (v1) Test Mod",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"environment": "*",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"depends": {
|
||||||
|
"fabric-rendering-v1": "*"
|
||||||
|
},
|
||||||
|
"entrypoints": {
|
||||||
|
"main": [
|
||||||
|
"net.fabricmc.fabric.test.rendering.CustomArmorTests"
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
"net.fabricmc.fabric.test.rendering.client.WorldRenderEventsTests"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue