Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix block outline rendering #4286

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
PepperCode1 marked this conversation as resolved.
Show resolved Hide resolved

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);
PepperCode1 marked this conversation as resolved.
Show resolved Hide resolved
}

@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