Skip to content
Open
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false
id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false
}

architectury {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.shedaniel.lightoverlay.common;

import static me.shedaniel.lightoverlay.common.LightOverlay.*;
import net.minecraft.client.gui.components.debug.*;
import net.minecraft.world.level.*;
import net.minecraft.world.level.chunk.*;
import org.jetbrains.annotations.*;

public class DebugEntryLightOverlay implements DebugScreenEntry {
@Override
public void display(DebugScreenDisplayer debugScreenDisplayer, @Nullable Level level, @Nullable LevelChunk levelChunk, @Nullable LevelChunk levelChunk2) {
if (enabled) {
if (caching) {
debugScreenDisplayer.addLine(String.format("[Light Overlay] Chunks to queue: %02d", ticker.POS.size()));
} else {
debugScreenDisplayer.addLine("[Light Overlay] Enabled");
}
} else {
debugScreenDisplayer.addLine("[Light Overlay] Disabled");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import dev.architectury.platform.Platform;
import dev.architectury.registry.client.keymappings.KeyMappingRegistry;
import net.minecraft.client.KeyMapping;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.client.gui.components.debug.*;
import net.minecraft.resources.*;
import net.minecraft.util.Mth;

import java.io.File;
Expand Down Expand Up @@ -45,22 +46,11 @@ public static void register() {
configFile = new File(Platform.getConfigFolder().toFile(), "lightoverlay.properties");
loadConfig(configFile);

enableOverlay = createKeyBinding(ResourceLocation.fromNamespaceAndPath("lightoverlay", "enable_overlay"), InputConstants.Type.KEYSYM, 296, "key.lightoverlay.category");
enableOverlay = createKeyBinding(Identifier.fromNamespaceAndPath("lightoverlay", "enable_overlay"), InputConstants.Type.KEYSYM, 296, "key.lightoverlay.category");
KeyMappingRegistry.register(enableOverlay);

registerDebugRenderer(renderer);

ClientGuiEvent.DEBUG_TEXT_LEFT.register(list -> {
if (enabled) {
if (caching) {
list.add(String.format("[Light Overlay] Chunks to queue: %02d", ticker.POS.size()));
} else {
list.add("[Light Overlay] Enabled");
}
} else {
list.add("[Light Overlay] Disabled");
}
});
DebugScreenEntries.register(Identifier.fromNamespaceAndPath("lightoverlay", "debug"), new DebugEntryLightOverlay());
ClientTickEvent.CLIENT_POST.register(ticker::tick);
}

Expand Down Expand Up @@ -197,8 +187,8 @@ public static void saveConfig(File file) throws IOException {
fos.close();
}

private static KeyMapping createKeyBinding(ResourceLocation id, InputConstants.Type type, int code, String category) {
return new KeyMapping("key." + id.getNamespace() + "." + id.getPath(), type, code, category);
private static KeyMapping createKeyBinding(Identifier id, InputConstants.Type type, int code, String category) {
return new KeyMapping("key." + id.getNamespace() + "." + id.getPath(), type, code, KeyMapping.Category.register(Identifier.fromNamespaceAndPath("lightoverlay", category)));
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package me.shedaniel.lightoverlay.common;

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.pipeline.*;
import com.mojang.blaze3d.platform.*;
import com.mojang.blaze3d.vertex.*;
import it.unimi.dsi.fastutil.longs.Long2ByteMap;
import net.minecraft.Util;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.*;
import static net.minecraft.client.renderer.RenderPipelines.LINES_SNIPPET;
import static net.minecraft.client.renderer.RenderPipelines.MATRICES_PROJECTION_SNIPPET;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.rendertype.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.gizmos.*;
import net.minecraft.util.*;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.*;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.joml.Matrix4f;
Expand All @@ -29,22 +30,23 @@
import java.util.function.Function;

public class LightOverlayRenderer implements Consumer<PoseStack> {
private static final Function<Double, RenderType.CompositeRenderType> LINE = Util.memoize(
double_ -> RenderType.create(
"light_overlay_lines",
DefaultVertexFormat.POSITION_COLOR,
VertexFormat.Mode.DEBUG_LINES,
256,
RenderType.CompositeState.builder()
.setShaderState(RenderStateShard.POSITION_COLOR_SHADER)
.setLineState(new RenderStateShard.LineStateShard(OptionalDouble.of(double_)))
.setTransparencyState(RenderStateShard.NO_TRANSPARENCY)
.setCullState(RenderStateShard.NO_CULL)
.createCompositeState(false)
private static final RenderPipeline LINE_PIPELINE = RenderPipeline.builder(MATRICES_PROJECTION_SNIPPET)
.withLocation("pipeline/debug_line_strip")
.withVertexShader("core/position_color")
.withFragmentShader("core/position_color")
.withCull(false)
.withVertexFormat(DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.DEBUG_LINES)
.build();
private static final Function<Object, RenderType> LINE = Util.memoize(
double_ -> RenderType.create("light_overlay_lines",
RenderSetup.builder(LINE_PIPELINE).createRenderSetup()
)
);




private final Minecraft minecraft = Minecraft.getInstance();

public Frustum frustum;
public LightOverlayTicker ticker;

Expand All @@ -54,6 +56,7 @@ public LightOverlayRenderer(LightOverlayTicker ticker) {

@Override
public void accept(PoseStack poses) {
Minecraft minecraft = Minecraft.getInstance();
if (LightOverlay.enabled) {
LocalPlayer playerEntity = minecraft.player;
BlockPos playerPos = new BlockPos(playerEntity.getBlockX(), playerEntity.getBlockY(), playerEntity.getBlockZ());
Expand All @@ -65,19 +68,19 @@ public void accept(PoseStack poses) {
int chunkRange = LightOverlay.getChunkRange();

if (LightOverlay.showNumber) {
renderLevels(poses, camera, playerPos, playerPosX, playerPosY, playerPosZ, chunkRange, collisionContext);
renderLevels(playerPos, playerPosX, playerPosY, playerPosZ, chunkRange);
} else {
renderCrosses(poses, camera, playerPos, playerPosX, playerPosY, playerPosZ, chunkRange, collisionContext);
renderCrosses(playerPos, playerPosX, playerPosY, playerPosZ, chunkRange, collisionContext);
}
Minecraft.getInstance().renderBuffers().bufferSource().endLastBatch();
minecraft.renderBuffers().bufferSource().endLastBatch();
}
}

private void renderLevels(PoseStack poses, Camera camera, BlockPos playerPos, int playerPosX, int playerPosY, int playerPosZ, int chunkRange, CollisionContext collisionContext) {
RenderSystem.depthMask(true);
private void renderLevels(BlockPos playerPos, int playerPosX, int playerPosY, int playerPosZ, int chunkRange) {
Minecraft minecraft = Minecraft.getInstance();
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();
BlockPos.MutableBlockPos downMutable = new BlockPos.MutableBlockPos();
MultiBufferSource.BufferSource source = Minecraft.getInstance().renderBuffers().bufferSource();
MultiBufferSource.BufferSource source = minecraft.renderBuffers().bufferSource();
for (Map.Entry<CubicChunkPos, Long2ByteMap> entry : ticker.CHUNK_MAP.entrySet()) {
CubicChunkPos chunkPos = entry.getKey();
if (LightOverlay.caching && (Mth.abs(chunkPos.x - playerPosX) > chunkRange || Mth.abs(chunkPos.y - playerPosY) > Math.max(1, chunkRange >> 1) || Mth.abs(chunkPos.z - playerPosZ) > chunkRange)) {
Expand All @@ -88,37 +91,22 @@ private void renderLevels(PoseStack poses, Camera camera, BlockPos playerPos, in
if (mutable.closerThan(playerPos, LightOverlay.reach)) {
if (isFrustumVisible(mutable.getX(), mutable.getY(), mutable.getZ(), mutable.getX() + 1, mutable.getX() + 1, mutable.getX() + 1)) {
downMutable.set(mutable.getX(), mutable.getY() - 1, mutable.getZ());
renderLevel(poses, source, camera, minecraft.level, mutable, downMutable, objectEntry.getByteValue(), collisionContext);
renderLevel(downMutable, objectEntry.getByteValue());
}
}
}
}
RenderSystem.enableDepthTest();
}
public void renderLevel(PoseStack poses, MultiBufferSource.BufferSource source, Camera camera, Level world, BlockPos pos, BlockPos down, byte level, CollisionContext collisionContext) {

public void renderLevel(BlockPos down, byte level) {
String text = String.valueOf(level);
Font font = minecraft.font;
double cameraX = camera.getPosition().x;
double cameraY = camera.getPosition().y;
VoxelShape upperOutlineShape = world.getBlockState(down).getShape(world, down, collisionContext);
if (!upperOutlineShape.isEmpty())
cameraY += 1 - upperOutlineShape.max(Direction.Axis.Y);
double cameraZ = camera.getPosition().z;
poses.pushPose();
poses.translate(pos.getX() + 0.5 - cameraX, pos.getY() - cameraY + 0.005, pos.getZ() + 0.5 - cameraZ);
poses.mulPose(new Quaternionf().fromAxisAngleDeg(1, 0, 0, 90));
// poses.glNormal3f(0.0F, 1.0F, 0.0F);
float size = 0.07F;
poses.scale(-size, -size, size);
float float_3 = (float) (-font.width(text)) / 2.0F + 0.4f;
font.drawInBatch(text, float_3, -3.5f, level > LightOverlay.higherCrossLevel ? 0xff042404 : (LightOverlay.lowerCrossLevel >= 0 && level > LightOverlay.lowerCrossLevel ? 0xff0066ff : 0xff731111),
false, poses.last().pose(), source, Font.DisplayMode.SEE_THROUGH, 0, 15728880);
poses.popPose();
int color = level > LightOverlay.higherCrossLevel ? 0xff042404 : (LightOverlay.lowerCrossLevel >= 0 && level > LightOverlay.lowerCrossLevel ? 0xff0066ff : 0xff731111);
Gizmos.billboardText(text, Vec3.atLowerCornerWithOffset(down, 0.5, 1.3 + 1 * 0.2, 0.5), TextGizmo.Style.forColorAndCentered(color).withScale(1));
}

private void renderCrosses(PoseStack poses, Camera camera, BlockPos playerPos, int playerPosX, int playerPosY, int playerPosZ, int chunkRange, CollisionContext collisionContext) {
MultiBufferSource.BufferSource source = Minecraft.getInstance().renderBuffers().bufferSource();
private void renderCrosses(BlockPos playerPos, int playerPosX, int playerPosY, int playerPosZ, int chunkRange, CollisionContext collisionContext) {
Minecraft minecraft = Minecraft.getInstance();
MultiBufferSource.BufferSource source = minecraft.renderBuffers().bufferSource();
VertexConsumer buffer = source.getBuffer(LINE.apply((double) LightOverlay.lineWidth));
BlockPos.MutableBlockPos mutable = new BlockPos.MutableBlockPos();

Expand All @@ -138,33 +126,26 @@ private void renderCrosses(PoseStack poses, Camera camera, BlockPos playerPos, i
case LightOverlay.CROSS_YELLOW -> LightOverlay.yellowColor;
default -> LightOverlay.secondaryColor;
};
renderCross(poses.last().pose(), buffer, camera, minecraft.level, mutable, color, collisionContext);
renderCross(minecraft.level, mutable, color, collisionContext);
}
}
}
}
}

public void renderCross(Matrix4f pose, VertexConsumer builder, Camera camera, Level world, BlockPos pos, int color, CollisionContext collisionContext) {
float cameraX = (float) camera.getPosition().x;
float cameraY = (float) camera.getPosition().y - .005f;

public void renderCross(Level world, BlockPos pos, int color, CollisionContext collisionContext) {
float blockOffset = 0;
VoxelShape upperOutlineShape = world.getBlockState(pos).getShape(world, pos, collisionContext);
if (!upperOutlineShape.isEmpty()) {
blockOffset += upperOutlineShape.max(Direction.Axis.Y);
blockOffset += (float) upperOutlineShape.max(Direction.Axis.Y);
}
float cameraZ = (float) camera.getPosition().z;

int red = (color >> 16) & 255;
int green = (color >> 8) & 255;
int blue = color & 255;
float x = pos.getX() - cameraX;
float y = pos.getY() - cameraY + blockOffset;
float z = pos.getZ() - cameraZ;
builder.addVertex(pose, x + .01f, y, z + .01f).setColor(red, green, blue, 255);
builder.addVertex(pose, x + .99f, y, z + .99f).setColor(red, green, blue, 255);
builder.addVertex(pose, x + .99f, y, z + .01f).setColor(red, green, blue, 255);
builder.addVertex(pose, x + .01f, y, z + .99f).setColor(red, green, blue, 255);
color |= 0xFF000000;

float x = pos.getX()/* - cameraX*/;
float y = pos.getY()/* - cameraY*/ + blockOffset;
float z = pos.getZ()/* - cameraZ*/;
Gizmos.line(new Vec3(x + .01f, y, z + .01f),new Vec3(x + .99f, y, z + .99f),color,LightOverlay.lineWidth);
Gizmos.line(new Vec3(x + .99f, y, z + .01f),new Vec3(x + .01f, y, z + .99f),color,LightOverlay.lineWidth);
}

public boolean isFrustumVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import java.util.function.Supplier;

public class LightOverlayTicker {
private final Minecraft minecraft = Minecraft.getInstance();
private long ticks = 0;
private static int threadNumber = 0;
private static final ThreadPoolExecutor EXECUTOR = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> {
Expand Down Expand Up @@ -119,7 +118,7 @@ public void tick(Minecraft minecraft) {
} else {
assert Minecraft.getInstance().level != null;
var height = Mth.ceil(Minecraft.getInstance().level.getHeight() / 32.0);
var start = Math.floorDiv(Minecraft.getInstance().level.getMinBuildHeight(), 32);
var start = Math.floorDiv(Minecraft.getInstance().level.getMinY(), 32);
int playerPosX = ((int) player.getX()) >> 4;
int playerPosY = ((int) player.getY()) >> 5;
int playerPosZ = ((int) player.getZ()) >> 4;
Expand Down Expand Up @@ -206,6 +205,7 @@ public void tick(Minecraft minecraft) {
}

private void processChunk(CubicChunkPos pos, int playerPosX, int playerPosY, int playerPosZ, CollisionContext context) {
Minecraft minecraft = Minecraft.getInstance();
CALCULATING_POS.remove(pos);
int chunkRange = LightOverlay.getChunkRange();
if (Mth.abs(pos.x - playerPosX) > chunkRange || Mth.abs(pos.y - playerPosY) > Math.max(1, chunkRange >> 1) || Mth.abs(pos.z - playerPosZ) > chunkRange || POS.contains(pos)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package me.shedaniel.lightoverlay.fabric;

import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.lightoverlay.common.LightOverlay;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import me.shedaniel.lightoverlay.common.*;

import java.util.function.Consumer;

public class LightOverlayImpl {
public static LightOverlayRenderer renderer = LightOverlay.renderer;
public static Consumer<PoseStack> debugRenderer = poses -> {};

public static void init() {
LightOverlay.register();
WorldRenderEvents.AFTER_SETUP.register(context -> LightOverlay.renderer.frustum = context.frustum());
WorldRenderEvents.BEFORE_DEBUG_RENDER.register(context -> debugRenderer.accept(context.matrixStack()));
}


public static void renderWorldLast(PoseStack stack) {
debugRenderer.accept(stack);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ private static void handlePacket(Packet<?> packet, PacketListener listener, Call
LightOverlay.queueChunkAndNear(new CubicChunkPos(p.getPos()));
} else if (packet instanceof ClientboundSetChunkCacheCenterPacket p) {
var height = Mth.ceil(level.getHeight() / 32.0);
var start = Math.floorDiv(level.getMinBuildHeight(), 32);
var start = Math.floorDiv(level.getMinY(), 32);
for (int y = start; y < start + height; y++) {
LightOverlay.queueChunkAndNear(new CubicChunkPos(p.getX(), y, p.getZ()));
}
} else if (packet instanceof ClientboundSectionBlocksUpdatePacket p) {
LightOverlay.queueChunkAndNear(new CubicChunkPos(p.sectionPos.getX(), p.sectionPos.getY() >> 1, p.sectionPos.getZ()));
} else if (packet instanceof ClientboundLightUpdatePacket p) {
var height = Mth.ceil(level.getHeight() / 32.0);
var start = Math.floorDiv(level.getMinBuildHeight(), 32);
var start = Math.floorDiv(level.getMinY(), 32);
for (int y = start; y < start + height; y++) {
LightOverlay.queueChunk(new CubicChunkPos(p.getX(), y, p.getZ()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package me.shedaniel.lightoverlay.fabric.mixin;

import com.mojang.blaze3d.vertex.*;
import me.shedaniel.lightoverlay.fabric.*;
import net.minecraft.client.*;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.culling.*;
import net.minecraft.client.renderer.debug.*;
import net.minecraft.client.renderer.rendertype.*;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.*;

@Mixin(DebugRenderer.class)
public class MixinDebugRenderer {
@Inject(method = "emitGizmos", at = @At("HEAD"))
private void render(Frustum frustum, double d, double e, double f, float g, CallbackInfo ci) {
LightOverlayImpl.renderWorldLast(null);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.shedaniel.lightoverlay.fabric.mixin;

import me.shedaniel.lightoverlay.fabric.*;
import net.minecraft.client.*;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.culling.*;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.*;

@Mixin(LevelRenderer.class)
public class MixinLevelRenderer {
@Inject(method = "cullTerrain", at = @At("HEAD"))
private void setupTerrain(Camera arg, Frustum frustum, boolean bl, CallbackInfo ci) {
LightOverlayImpl.renderer.frustum = frustum;
}
}
2 changes: 1 addition & 1 deletion fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"depends": {
"fabricloader": ">=0.14.11",
"fabric-api": "*",
"minecraft": "~1.21",
"minecraft": "1.21.11",
"java": ">=17",
"architectury": ">=13-",
"cloth-config2": ">=15-"
Expand Down
Loading