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: shader block outline draw #5143

Merged
merged 4 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -19,50 +19,49 @@
*/
package net.ccbluex.liquidbounce.injection.mixins.minecraft.render;

import com.llamalad7.mixinextras.sugar.Local;
import net.ccbluex.liquidbounce.common.OutlineFlag;
import net.ccbluex.liquidbounce.features.module.modules.render.ModuleStorageESP;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.ModifyArg;

@Mixin(BlockEntityRenderDispatcher.class)
public class MixinBlockEntityRenderDispatcher {

/**
* Inject StorageESP glow effect
*
* @author 1zuna
*/
@Redirect(
@ModifyArg(
method = "render(Lnet/minecraft/client/render/block/entity/BlockEntityRenderer;Lnet/minecraft/block/entity/BlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/entity/BlockEntityRenderer;render(Lnet/minecraft/block/entity/BlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;II)V")
)
private static void render(BlockEntityRenderer blockEntityRenderer, BlockEntity blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
private static <T extends BlockEntity> VertexConsumerProvider render(
VertexConsumerProvider vertexConsumerProvider,
@Local(argsOnly = true) T blockEntity
) {
if (ModuleStorageESP.Glow.INSTANCE.getRunning()) {
var outlineVertexConsumerProvider = MinecraftClient.getInstance().getBufferBuilders()
.getOutlineVertexConsumers();
var type = ModuleStorageESP.categorize(blockEntity);

if (type != null && type.shouldRender(blockEntity.getPos())) {
var color = type.getColor();

if (color.getA() > 0) {
outlineVertexConsumerProvider.setColor(color.getR(), color.getG(), color.getB(), color.getA());

blockEntityRenderer.render(blockEntity, tickDelta, matrices, outlineVertexConsumerProvider, light, overlay);
var outlineVertexConsumerProvider = MinecraftClient.getInstance().getBufferBuilders()
.getOutlineVertexConsumers();
outlineVertexConsumerProvider.setColor(color.getR(), color.getG(), color.getB(), 255);
OutlineFlag.drawOutline = true;
return;
return outlineVertexConsumerProvider;
}
}
}

blockEntityRenderer.render(blockEntity, tickDelta, matrices, vertexConsumers, light, overlay);
return vertexConsumerProvider;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package net.ccbluex.liquidbounce.injection.mixins.minecraft.render;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import net.ccbluex.liquidbounce.common.OutlineFlag;
import net.ccbluex.liquidbounce.event.EventManager;
Expand Down Expand Up @@ -46,22 +47,15 @@
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args;

import static org.lwjgl.opengl.GL11.*;

@Mixin(WorldRenderer.class)
public abstract class MixinWorldRenderer {

@Shadow
public abstract @Nullable Framebuffer getEntityOutlinesFramebuffer();

@Shadow
protected abstract boolean canDrawEntityOutlines();

@Shadow
protected abstract void renderTargetBlockOutline(Camera camera, VertexConsumerProvider.Immediate vertexConsumers, MatrixStack matrices, boolean translucent);

@Shadow
@Final
private MinecraftClient client;
Expand All @@ -76,6 +70,9 @@ public abstract class MixinWorldRenderer {
@Nullable
public Framebuffer entityOutlineFramebuffer;

@Shadow
public abstract @Nullable Framebuffer getEntityOutlinesFramebuffer();

@Inject(method = "loadEntityOutlinePostProcessor", at = @At("RETURN"))
private void onLoadEntityOutlineShader(CallbackInfo info) {
// load the shader class to compile the shaders
Expand All @@ -87,7 +84,7 @@ private void onLoadEntityOutlineShader(CallbackInfo info) {
private void onRender(ObjectAllocator allocator, RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, Matrix4f positionMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
try {
OutlineShader outlineShader = OutlineShader.INSTANCE;
OutlineShader.INSTANCE.update();
outlineShader.update();
outlineShader.getHandle().get().beginWrite(false);

var event = new DrawOutlinesEvent(new MatrixStack(), camera, tickCounter.getTickDelta(false), DrawOutlinesEvent.OutlineType.INBUILT_OUTLINE);
Expand Down Expand Up @@ -184,77 +181,45 @@ private boolean hookFreeCamRenderPlayerFromAllPerspectives(LivingEntity instance
return ModuleFreeCam.INSTANCE.renderPlayerFromAllPerspectives(instance);
}

/**
* Enables an outline glow when ESP is enabled and glow mode is active
*
* @author 1zuna
*/
@Redirect(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
private boolean injectHasOutline(MinecraftClient instance, Entity entity) {
if (ModuleItemESP.GlowMode.INSTANCE.getRunning() && ModuleItemESP.INSTANCE.shouldRender(entity)) {
return true;
}
if (ModuleESP.GlowMode.INSTANCE.getRunning() && CombatExtensionsKt.shouldBeShown(entity)) {
return true;
}
if (ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp() && entity instanceof TntEntity) {
return true;
}

if (ModuleStorageESP.Glow.INSTANCE.getRunning() && ModuleStorageESP.categorize(entity) != null) {
return true;
}
@ModifyExpressionValue(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
private boolean injectHasOutline(boolean original, @Local Entity entity) {
return original || shouldRenderOutline(entity);
}

return instance.hasOutline(entity);
@ModifyExpressionValue(method = "getEntitiesToRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
private boolean injectHasOutline2(boolean original, @Local Entity entity) {
return original || shouldRenderOutline(entity);
}

@Redirect(method = "getEntitiesToRender", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
private boolean injectHasOutline2(MinecraftClient instance, Entity entity) {
@Unique
private boolean shouldRenderOutline(Entity entity) {
if (ModuleItemESP.GlowMode.INSTANCE.getRunning() && ModuleItemESP.INSTANCE.shouldRender(entity)) {
return true;
}
if (ModuleESP.GlowMode.INSTANCE.getRunning() && CombatExtensionsKt.shouldBeShown(entity)) {
} else if (ModuleESP.GlowMode.INSTANCE.getRunning() && CombatExtensionsKt.shouldBeShown(entity)) {
return true;
}
if (ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp() && entity instanceof TntEntity) {
return true;
}

if (ModuleStorageESP.Glow.INSTANCE.getRunning() && ModuleStorageESP.categorize(entity) != null) {
} else if (ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp() && entity instanceof TntEntity) {
return true;
} else {
return false;
}

return instance.hasOutline(entity);
}

/**
* Inject ESP color as glow color
*
* @author 1zuna
*/
@Redirect(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I"))
private int injectTeamColor(Entity instance) {
if (ModuleItemESP.GlowMode.INSTANCE.getRunning() && ModuleItemESP.INSTANCE.shouldRender(instance)) {
@ModifyExpressionValue(method = "renderEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I"))
private int injectTeamColor(int original, @Local Entity entity) {
if (entity instanceof LivingEntity livingEntity && ModuleESP.GlowMode.INSTANCE.getRunning()) {
return ModuleESP.INSTANCE.getColor(livingEntity).toARGB();
} else if (ModuleItemESP.GlowMode.INSTANCE.getRunning() && ModuleItemESP.INSTANCE.shouldRender(entity)) {
return ModuleItemESP.INSTANCE.getColor().toARGB();
} else if (entity instanceof TntEntity tntEntity && ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp()) {
return ModuleTNTTimer.INSTANCE.getTntColor(tntEntity.getFuse()).toARGB();
} else {
return original;
}

if (instance instanceof TntEntity && ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp()) {
return ModuleTNTTimer.INSTANCE.getTntColor(((TntEntity) instance).getFuse()).toARGB();
}

if (ModuleStorageESP.Glow.INSTANCE.getRunning()) {
var categorizedEntity = ModuleStorageESP.categorize(instance);
if (categorizedEntity != null) {
return categorizedEntity.getColor().toARGB();
}
}

if (instance instanceof LivingEntity && ModuleESP.GlowMode.INSTANCE.getRunning()) {
final Color4b color = ModuleESP.INSTANCE.getColor((LivingEntity) instance);
return color.toARGB();
}

return instance.getTeamColorValue();
}

@Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/OutlineVertexConsumerProvider;draw()V", shift = At.Shift.BEFORE))
Expand All @@ -265,22 +230,22 @@ private void onRenderOutline(Fog fog, RenderTickCounter renderTickCounter, Camer

//noinspection DataFlowIssue
this.getEntityOutlinesFramebuffer().beginWrite(false);

var event = new DrawOutlinesEvent(new MatrixStack(), camera, renderTickCounter.getTickDelta(false), DrawOutlinesEvent.OutlineType.MINECRAFT_GLOW);

EventManager.INSTANCE.callEvent(event);

OutlineFlag.drawOutline |= event.getDirtyFlag();

MinecraftClient.getInstance().getFramebuffer().beginWrite(false);
client.getFramebuffer().beginWrite(false);
}

@Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/BufferBuilderStorage;getOutlineVertexConsumers()Lnet/minecraft/client/render/OutlineVertexConsumerProvider;", shift = At.Shift.AFTER))
private void hookOutlineFlag(Fog fog, RenderTickCounter renderTickCounter, Camera camera, Profiler profiler, Matrix4f matrix4f, Matrix4f matrix4f2, Handle handle, Handle handle2, Handle handle3, Handle handle4, boolean bl, Frustum frustum, Handle handle5, CallbackInfo ci, @Local(ordinal = 0) VertexConsumerProvider.Immediate immediate, @Local(ordinal = 0) MatrixStack matrixStack) {
if (OutlineFlag.drawOutline && !bl) {
@ModifyVariable(method = "render", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gl/ShaderLoader;loadPostEffect(Lnet/minecraft/util/Identifier;Ljava/util/Set;)Lnet/minecraft/client/gl/PostEffectProcessor;"
), name = "bl3", ordinal = 3)
private boolean modifyDrawOutline(boolean original) {
var flag = OutlineFlag.drawOutline;
if (flag) {
OutlineFlag.drawOutline = false;
renderTargetBlockOutline(camera, immediate, matrixStack, false);
}
return original || flag;
}

@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;setupTerrain(Lnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/Frustum;ZZ)V"), index = 3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,11 @@ object ModuleBlockESP : ClientModule("BlockESP", Category.RENDER) {

val dirty = Box.drawBoxMode(event.matrixStack, drawOutline = false, fullAlpha = true)

if (dirty)
if (dirty) {
event.markDirty()
}
}

}

private object Outline : Choice("Outline") {
Expand Down
Loading