Skip to content

Commit

Permalink
Add translucent block outline to context
Browse files Browse the repository at this point in the history
  • Loading branch information
PepperCode1 committed Dec 9, 2024
1 parent 94d646b commit 41cb15e
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ public interface WorldRenderContext {
*/
WorldRenderer worldRenderer();

/**
* The matrix stack is only not null in {@link WorldRenderEvents#AFTER_ENTITIES} or later events.
*/
@Nullable
MatrixStack matrixStack();

RenderTickCounter tickCounter();

boolean blockOutlines();
Expand All @@ -58,10 +52,10 @@ public interface WorldRenderContext {

GameRenderer gameRenderer();

Matrix4f projectionMatrix();

Matrix4f positionMatrix();

Matrix4f projectionMatrix();

/**
* Convenient access to {WorldRenderer.world}.
*
Expand Down Expand Up @@ -92,30 +86,39 @@ public interface WorldRenderContext {
* possible, caller should use a separate "immediate" instance.
*
* <p>This property is {@code null} before {@link WorldRenderEvents#BEFORE_ENTITIES} and after
* {@link WorldRenderEvents#BEFORE_DEBUG_RENDER} because the consumer buffers are not available before or
* {@link WorldRenderEvents#BLOCK_OUTLINE} (translucent) because the consumer buffers are not available before or
* drawn after that in vanilla world rendering. Renders that cannot draw in one of the supported events
* must be drawn directly to the frame buffer, preferably in {@link WorldRenderEvents#LAST} to avoid being
* overdrawn or cleared.
*/
@Nullable VertexConsumerProvider consumers();
@Nullable
VertexConsumerProvider consumers();

/**
* View frustum, after it is initialized. Will be {@code null} during
* {@link WorldRenderEvents#START}.
*/
@Nullable Frustum frustum();
@Nullable
Frustum frustum();

/**
* Used in {@code BLOCK_OUTLINE} to convey the parameters normally sent to
* The matrix stack is only not null in {@link WorldRenderEvents#AFTER_ENTITIES} or later events.
*/
@Nullable
MatrixStack matrixStack();

/**
* Meant to be used in {@link WorldRenderEvents#BEFORE_BLOCK_OUTLINE} and {@link WorldRenderEvents#BLOCK_OUTLINE}.
* @return {@code true} if the current block outline is being rendered after translucent terrain; {@code false} if
* it is being rendered after solid terrain
*/
boolean translucentBlockOutline();

/**
* Used in {@link WorldRenderEvents#BLOCK_OUTLINE} to convey the parameters normally sent to
* {@code WorldRenderer.drawBlockOutline}.
*/
interface BlockOutlineContext {
/**
* @deprecated Use {@link #consumers()} directly.
*/
@Deprecated
VertexConsumer vertexConsumer();

Entity entity();

double cameraX();
Expand All @@ -127,5 +130,11 @@ interface BlockOutlineContext {
BlockPos blockPos();

BlockState blockState();

/**
* @deprecated Use {@link #consumers()} directly.
*/
@Deprecated
VertexConsumer vertexConsumer();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@
* <li>AFTER_SETUP
* <li>BEFORE_ENTITIES
* <li>AFTER_ENTITIES
* <li>BEFORE_BLOCK_OUTLINE
* <li>BLOCK_OUTLINE (If not cancelled in BEFORE_BLOCK_OUTLINE)
* <li>BEFORE_BLOCK_OUTLINE (non-translucent)
* <li>BLOCK_OUTLINE (if not cancelled in non-translucent BEFORE_BLOCK_OUTLINE and vanilla checks pass)
* <li>BEFORE_DEBUG_RENDER
* <li>BEFORE_BLOCK_OUTLINE (translucent)
* <li>BLOCK_OUTLINE (if not cancelled in translucent BEFORE_BLOCK_OUTLINE and vanilla checks pass)
* <li>AFTER_TRANSLUCENT
* <li>LAST
* <li>END</ul>
Expand Down Expand Up @@ -139,11 +141,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, translucent, hit) -> true, callbacks -> (context, translucent, hit) -> {
public static final Event<BeforeBlockOutline> BEFORE_BLOCK_OUTLINE = EventFactory.createArrayBacked(BeforeBlockOutline.class, (context, hit) -> true, callbacks -> (context, hit) -> {
boolean shouldRender = true;

for (final BeforeBlockOutline callback : callbacks) {
if (!callback.beforeBlockOutline(context, translucent, hit)) {
if (!callback.beforeBlockOutline(context, hit)) {
shouldRender = false;
}
}
Expand Down Expand Up @@ -279,15 +281,13 @@ 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, boolean translucent, @Nullable HitResult hitResult);
boolean beforeBlockOutline(WorldRenderContext context, @Nullable HitResult hitResult);
}

@FunctionalInterface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package net.fabricmc.fabric.impl.client.rendering;

import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;

import net.minecraft.block.BlockState;
Expand All @@ -37,17 +38,21 @@
public final class WorldRenderContextImpl implements WorldRenderContext.BlockOutlineContext, WorldRenderContext {
private WorldRenderer worldRenderer;
private RenderTickCounter tickCounter;
private MatrixStack matrixStack;
private boolean blockOutlines;
private Camera camera;
private Frustum frustum;
private GameRenderer gameRenderer;
private Matrix4f projectionMatrix;
private Matrix4f positionMatrix;
private Matrix4f projectionMatrix;
private VertexConsumerProvider consumers;
private boolean advancedTranslucency;
private ClientWorld world;

@Nullable
private Frustum frustum;
@Nullable
private MatrixStack matrixStack;
private boolean translucentBlockOutline;

private Entity entity;
private double cameraX;
private double cameraY;
Expand All @@ -59,27 +64,29 @@ public final class WorldRenderContextImpl implements WorldRenderContext.BlockOut

public void prepare(
WorldRenderer worldRenderer,
RenderTickCounter delta,
RenderTickCounter tickCounter,
boolean blockOutlines,
Camera camera,
GameRenderer gameRenderer,
Matrix4f projectionMatrix,
Matrix4f positionMatrix,
Matrix4f projectionMatrix,
VertexConsumerProvider consumers,
boolean advancedTranslucency,
ClientWorld world
) {
this.worldRenderer = worldRenderer;
this.tickCounter = delta;
this.matrixStack = null;
this.tickCounter = tickCounter;
this.blockOutlines = blockOutlines;
this.camera = camera;
this.gameRenderer = gameRenderer;
this.projectionMatrix = projectionMatrix;
this.positionMatrix = positionMatrix;
this.projectionMatrix = projectionMatrix;
this.consumers = consumers;
this.advancedTranslucency = advancedTranslucency;
this.world = world;

frustum = null;
matrixStack = null;
}

public void setFrustum(Frustum frustum) {
Expand All @@ -90,6 +97,10 @@ public void setMatrixStack(MatrixStack matrixStack) {
this.matrixStack = matrixStack;
}

public void setTranslucentBlockOutline(boolean translucentBlockOutline) {
this.translucentBlockOutline = translucentBlockOutline;
}

public void prepareBlockOutline(
Entity entity,
double cameraX,
Expand All @@ -111,11 +122,6 @@ public WorldRenderer worldRenderer() {
return worldRenderer;
}

@Override
public MatrixStack matrixStack() {
return matrixStack;
}

@Override
public RenderTickCounter tickCounter() {
return this.tickCounter;
Expand All @@ -132,23 +138,28 @@ public Camera camera() {
}

@Override
public Matrix4f projectionMatrix() {
return projectionMatrix;
public GameRenderer gameRenderer() {
return gameRenderer;
}

@Override
public Matrix4f positionMatrix() {
return positionMatrix;
}

@Override
public Matrix4f projectionMatrix() {
return projectionMatrix;
}

@Override
public ClientWorld world() {
return world;
}

@Override
public Frustum frustum() {
return frustum;
public boolean advancedTranslucency() {
return advancedTranslucency;
}

@Override
Expand All @@ -157,18 +168,20 @@ public VertexConsumerProvider consumers() {
}

@Override
public GameRenderer gameRenderer() {
return gameRenderer;
@Nullable
public Frustum frustum() {
return frustum;
}

@Override
public boolean advancedTranslucency() {
return advancedTranslucency;
@Nullable
public MatrixStack matrixStack() {
return matrixStack;
}

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

@Override
Expand Down Expand Up @@ -200,4 +213,10 @@ public BlockPos blockPos() {
public BlockState blockState() {
return blockState;
}

@Deprecated
@Override
public VertexConsumer vertexConsumer() {
return consumers.getBuffer(RenderLayer.getLines());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public abstract class WorldRendererMixin {

@Inject(method = "render", at = @At("HEAD"))
private void beforeRender(ObjectAllocator objectAllocator, RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
context.prepare((WorldRenderer) (Object) this, tickCounter, renderBlockOutline, camera, gameRenderer, projectionMatrix, positionMatrix, bufferBuilders.getEntityVertexConsumers(), MinecraftClient.isFabulousGraphicsOrBetter(), world);
context.prepare((WorldRenderer) (Object) this, tickCounter, renderBlockOutline, camera, gameRenderer, positionMatrix, projectionMatrix, bufferBuilders.getEntityVertexConsumers(), MinecraftClient.isFabulousGraphicsOrBetter(), world);
WorldRenderEvents.START.invoker().onStart(context);
}

Expand Down Expand Up @@ -117,7 +117,8 @@ private void afterEntities(CallbackInfo ci) {

@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);
context.setTranslucentBlockOutline(translucent);
context.renderBlockOutline = WorldRenderEvents.BEFORE_BLOCK_OUTLINE.invoker().beforeBlockOutline(context, client.crosshairTarget);
}

@SuppressWarnings("ConstantConditions")
Expand Down

0 comments on commit 41cb15e

Please sign in to comment.