Skip to content

Commit

Permalink
Fix block outline rendering
Browse files Browse the repository at this point in the history
- Move outline event invoker to before either normal or high contrast outlines are rendered
- Remove outline layer reset, fixing high contrast outline being rendered with wrong layer
- Pass translucent parameter to BEFORE_BLOCK_OUTLINE event
- Remove deprecated BlockOutlineContext#vertexConsumer
  • Loading branch information
PepperCode1 committed Dec 8, 2024
1 parent f906699 commit 2f117f7
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import net.minecraft.client.render.Frustum;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
Expand Down Expand Up @@ -110,12 +109,6 @@ public interface WorldRenderContext {
* {@code WorldRenderer.drawBlockOutline}.
*/
interface BlockOutlineContext {
/**
* @deprecated Use {@link #consumers()} directly.
*/
@Deprecated
VertexConsumer vertexConsumer();

Entity entity();

double cameraX();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ private WorldRenderEvents() { }
* renders. Mods that replace the default block outline for specific blocks
* should instead subscribe to {@link #BLOCK_OUTLINE}.
*/
public static final Event<BeforeBlockOutline> BEFORE_BLOCK_OUTLINE = EventFactory.createArrayBacked(BeforeBlockOutline.class, (context, hit) -> true, callbacks -> (context, hit) -> {
public static final Event<BeforeBlockOutline> BEFORE_BLOCK_OUTLINE = EventFactory.createArrayBacked(BeforeBlockOutline.class, (context, translucent, hit) -> true, callbacks -> (context, translucent, hit) -> {
boolean shouldRender = true;

for (final BeforeBlockOutline callback : callbacks) {
if (!callback.beforeBlockOutline(context, hit)) {
if (!callback.beforeBlockOutline(context, translucent, hit)) {
shouldRender = false;
}
}
Expand Down Expand Up @@ -279,13 +279,15 @@ public interface BeforeBlockOutline {
* Event signature for {@link WorldRenderEvents#BEFORE_BLOCK_OUTLINE}.
*
* @param context Access to state and parameters available during world rendering.
* @param translucent If {@code true}, current block outline is being rendered after translucent terrain.
* Otherwise, it is being rendered after solid terrain.
* @param hitResult The game object currently under the crosshair target.
* Normally equivalent to {@link MinecraftClient#crosshairTarget}. Provided for convenience.
* @return true if vanilla block outline rendering should happen.
* Returning false prevents {@link WorldRenderEvents#BLOCK_OUTLINE} from invoking
* and also skips the vanilla block outline render, but has no effect on other subscribers to this event.
*/
boolean beforeBlockOutline(WorldRenderContext context, @Nullable HitResult hitResult);
boolean beforeBlockOutline(WorldRenderContext context, boolean translucent, @Nullable HitResult hitResult);
}

@FunctionalInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.Frustum;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
Expand Down Expand Up @@ -166,11 +164,6 @@ public boolean advancedTranslucency() {
return advancedTranslucency;
}

@Override
public VertexConsumer vertexConsumer() {
return consumers.getBuffer(RenderLayer.getLines());
}

@Override
public Entity entity() {
return entity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.block.BlockState;
Expand All @@ -39,15 +38,13 @@
import net.minecraft.client.render.FrameGraphBuilder;
import net.minecraft.client.render.Frustum;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPass;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

Expand Down Expand Up @@ -118,41 +115,27 @@ private void afterEntities(CallbackInfo ci) {
WorldRenderEvents.AFTER_ENTITIES.invoker().afterEntities(context);
}

@Inject(
method = "renderTargetBlockOutline",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/MinecraftClient;crosshairTarget:Lnet/minecraft/util/hit/HitResult;",
shift = At.Shift.AFTER,
ordinal = 0
)
)
private void beforeRenderOutline(CallbackInfo ci) {
context.renderBlockOutline = WorldRenderEvents.BEFORE_BLOCK_OUTLINE.invoker().beforeBlockOutline(context, client.crosshairTarget);
@Inject(method = "renderTargetBlockOutline", at = @At("HEAD"))
private void beforeRenderOutline(Camera camera, VertexConsumerProvider.Immediate vertexConsumers, MatrixStack matrices, boolean translucent, CallbackInfo ci) {
context.renderBlockOutline = WorldRenderEvents.BEFORE_BLOCK_OUTLINE.invoker().beforeBlockOutline(context, translucent, 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, int color, CallbackInfo ci) {
@Inject(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "net/minecraft/client/option/GameOptions.getHighContrastBlockOutline()Lnet/minecraft/client/option/SimpleOption;"), cancellable = true)
private void onDrawBlockOutline(Camera camera, VertexConsumerProvider.Immediate vertexConsumers, MatrixStack matrices, boolean translucent, CallbackInfo ci, @Local BlockPos blockPos, @Local BlockState blockState, @Local Vec3d cameraPos) {
if (!context.renderBlockOutline) {
// Was cancelled before we got here, so do not
// fire the BLOCK_OUTLINE event per contract of the API.
ci.cancel();
} else {
context.prepareBlockOutline(entity, cameraX, cameraY, cameraZ, blockPos, blockState);

if (!WorldRenderEvents.BLOCK_OUTLINE.invoker().onBlockOutline(context, context)) {
ci.cancel();
}
return;
}
}

@SuppressWarnings("ConstantConditions")
@ModifyVariable(method = "drawBlockOutline", at = @At("HEAD"))
private VertexConsumer resetBlockOutlineBuffer(VertexConsumer vertexConsumer) {
// The original VertexConsumer may have been ended during the block outlines event, so we
// have to re-request it to prevent a crash when the vanilla block overlay is submitted.
return context.consumers().getBuffer(RenderLayer.getLines());
context.prepareBlockOutline(camera.getFocusedEntity(), cameraPos.x, cameraPos.y, cameraPos.z, blockPos, blockState);

if (!WorldRenderEvents.BLOCK_OUTLINE.invoker().onBlockOutline(context, context)) {
vertexConsumers.drawCurrentLayer();
ci.cancel();
}
}

@Inject(
Expand Down

0 comments on commit 2f117f7

Please sign in to comment.