diff --git a/src/main/java/carpet/mixins/FluidRenderingMixin.java b/src/main/java/carpet/mixins/FluidRenderingMixin.java new file mode 100644 index 000000000..32586ecf9 --- /dev/null +++ b/src/main/java/carpet/mixins/FluidRenderingMixin.java @@ -0,0 +1,29 @@ +package carpet.mixins; + +import carpet.script.utils.ShapesRenderer; +import net.minecraft.client.renderer.block.LiquidBlockRenderer; +import org.joml.Vector4f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; + +@Mixin(LiquidBlockRenderer.class) +public abstract class FluidRenderingMixin { + @ModifyArgs(method = "vertex", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/VertexConsumer;addVertex(FFF)Lcom/mojang/blaze3d/vertex/VertexConsumer;")) + private void injected(Args args) { + var pair = ShapesRenderer.DrawingShape.get(); + if (pair == null) return; + float f = args.get(0); + float g = args.get(1); + float h = args.get(2); + int x = pair.getSecond().getX() & 0xf; + int y = pair.getSecond().getY() & 0xf; + int z = pair.getSecond().getZ() & 0xf; + var vec = new Vector4f(f - x, g - y, h - z, 1); + pair.getFirst().pose().transform(vec); + args.set(0, vec.x); + args.set(1, vec.y); + args.set(2, vec.z); + } +} diff --git a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java index 4b1f40639..a5ede4cf2 100644 --- a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java +++ b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java @@ -41,7 +41,10 @@ private void renderScarpetThingsLate(FrameGraphBuilder frameGraphBuilder, Camera { FramePass pass = frameGraphBuilder.addPass("scarpet_shapes"); targets.main = pass.readsAndWrites(targets.main); - pass.executes(() -> CarpetClient.shapes.render(null, camera, f)); + pass.executes(() -> CarpetClient.shapes.render(0, camera, f)); + pass = frameGraphBuilder.addPass("scarpet_shapes-fluid"); + targets.main = pass.readsAndWrites(targets.main); + pass.executes(() -> CarpetClient.shapes.render(1, camera, f)); } } } diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index 928ec3969..5352dc80f 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -306,6 +306,7 @@ private static BiFunction, RegistryAccess, ExpiringShape> cre protected boolean discreteX, discreteY, discreteZ; protected ResourceKey shapeDimension; protected boolean debug; + protected boolean hud; protected ExpiringShape() @@ -373,6 +374,11 @@ protected void init(Map options, RegistryAccess regs) debug = options.get("debug").getBoolean(); } + hud = false; + if (options.containsKey("hud")) + { + hud = options.get("hud").getBoolean(); + } key = 0; followEntity = -1; shapeDimension = ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(options.get("dim").getString())); @@ -463,6 +469,8 @@ protected long calcKey(RegistryAccess regs) hash *= 1099511628211L; hash ^= Boolean.hashCode(debug); hash *= 1099511628211L; + hash ^= Boolean.hashCode(hud); + hash *= 1099511628211L; if (followEntity >= 0) { hash ^= snapTo.hashCode(); @@ -494,6 +502,7 @@ int vec3dhash(Vec3 vec) "follow", new NumericValue(-1), "line", new NumericValue(2.0), "debug", Value.FALSE, + "hud", Value.FALSE, "fill", new NumericValue(0xffffff00), "snap", new StringValue("xyz") ); @@ -1507,7 +1516,7 @@ public Value validate(java.util.Map options, MinecraftServer serv put("points", new PointsParam("points")); put("text", new FormattedTextParam("text")); put("value", new FormattedTextParam("value")); - put("size", new PositiveIntParam("size")); + put("size", new PositiveFloatParam("size")); put("align", new StringChoiceParam("align", "center", "left", "right")); put("block", new BlockParam("block")); @@ -1522,6 +1531,7 @@ public Value validate(java.util.Map options, MinecraftServer serv put("facing", new StringChoiceParam("facing", "player", "camera", "north", "south", "east", "west", "up", "down")); put("doublesided", new BoolParam("doublesided")); put("debug", new BoolParam("debug")); + put("hud", new BoolParam("hud")); }}; protected String id; diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index a7c7a9eb6..f23bf5f88 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -1,9 +1,10 @@ -package carpet.script.utils; +package carpet.script.utils; import carpet.script.CarpetScriptServer; import carpet.script.external.Carpet; import carpet.script.utils.shapes.ShapeDirection; +import com.mojang.blaze3d.ProjectionType; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.BufferUploader; @@ -12,7 +13,9 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.blaze3d.vertex.VertexSorting; import com.mojang.blaze3d.vertex.VertexFormat.Mode; +import com.mojang.datafixers.util.Pair; import com.mojang.math.Axis; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -53,10 +56,13 @@ public class ShapesRenderer { + private static final Matrix4f ORTHOMAT = new Matrix4f().m22(-1);//need to check if it should be that, or a simple identity matrix. private final Map, Long2ObjectOpenHashMap>> shapes; private final Map, Long2ObjectOpenHashMap>> labels; private final Minecraft client; + public static ThreadLocal> DrawingShape = new ThreadLocal<>(); + private final Map>> renderedShapes = new HashMap<>() {{ @@ -106,7 +112,7 @@ public ShapesRenderer(Minecraft minecraftClient) labels = new HashMap<>(); } - public void render(Matrix4f modelViewMatrix, Camera camera, float partialTick) + public void render(int passid, Camera camera, float partialTick) { Runnable token = Carpet.startProfilerSection("Scarpet client"); // posestack is not needed anymore - left as TODO to cleanup later @@ -156,7 +162,7 @@ public void render(Matrix4f modelViewMatrix, Camera camera, float partialTick) // lines RenderSystem.lineWidth(0.5F); shapes.get(dimensionType).values().forEach(s -> { - if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType)) + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType) && !s.shape.hud) { s.renderLines(matrices, tesselator, cameraX, cameraY, cameraZ, partialTick); } @@ -164,12 +170,39 @@ public void render(Matrix4f modelViewMatrix, Camera camera, float partialTick) // faces RenderSystem.lineWidth(0.1F); shapes.get(dimensionType).values().forEach(s -> { - if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType)) + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType) && !s.shape.hud) { s.renderFaces(tesselator, cameraX, cameraY, cameraZ, partialTick); } }); RenderSystem.lineWidth(1.0F); + + matrixStack.popMatrix(); + matrixStack.pushMatrix(); + matrixStack.identity(); + + //RenderSystem.applyModelViewMatrix(); + var ori=RenderSystem.getProjectionMatrix(); + RenderSystem.setProjectionMatrix(ORTHOMAT, ProjectionType.ORTHOGRAPHIC); + + // lines + RenderSystem.lineWidth(0.5F); + shapes.get(dimensionType).values().forEach(s -> { + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType) && s.shape.hud) + { + s.renderLines(matrices, tesselator, 0, 0, 0, partialTick); + } + }); + // faces + RenderSystem.lineWidth(0.1F); + shapes.get(dimensionType).values().forEach(s -> { + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType) && s.shape.hud) + { + s.renderFaces(tesselator, 0, 0, 0, partialTick); + } + }); + RenderSystem.lineWidth(1.0F); + RenderSystem.setProjectionMatrix(ori,ProjectionType.PERSPECTIVE); matrixStack.popMatrix(); } @@ -179,11 +212,33 @@ public void render(Matrix4f modelViewMatrix, Camera camera, float partialTick) entry -> entry.getValue().isExpired(currentTime) ); labels.get(dimensionType).values().forEach(s -> { - if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType)) + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType)&& !s.shape.hud) { - s.renderLines(matrices, tesselator, cameraX, cameraY, cameraZ, partialTick); + s.renderLines(matrices, tesselator, cameraX, cameraY, cameraZ, partialTick, passid); + } + }); + //PoseStack matrixStack = RenderSystem.getModelViewStack(); + //matrices.pushPose(); + Matrix4fStack matrixStack = RenderSystem.getModelViewStack(); + matrixStack.pushMatrix(); + matrixStack.identity(); + //RenderSystem.applyModelViewMatrix(); + matrices.pushPose(); + matrices.setIdentity(); + //RenderSystem.applyModelViewMatrix(); + var ori=RenderSystem.getProjectionMatrix(); + RenderSystem.setProjectionMatrix(ORTHOMAT,ProjectionType.ORTHOGRAPHIC); + labels.get(dimensionType).values().forEach(s -> { + if ((!s.shape.debug || entityBoxes) && s.shouldRender(dimensionType)&& s.shape.hud) + { + s.renderLines(matrices, tesselator, 0, 0, 0, partialTick, passid); } }); + matrices.popPose(); + //RenderSystem.applyModelViewMatrix(); + RenderSystem.setProjectionMatrix(ori,ProjectionType.PERSPECTIVE); + matrixStack.popMatrix(); + //RenderSystem.applyModelViewMatrix(); } RenderSystem.enableCull(); RenderSystem.depthMask(true); @@ -257,6 +312,9 @@ public abstract static class RenderedShape> 16 & 0xFF) / 255.0F; - float green = (color >> 8 & 0xFF) / 255.0F; - float blue = (color & 0xFF) / 255.0F; - RenderType type; - if (blockState.getBlock() instanceof LeavesBlock && !Minecraft.useFancyGraphics()) { - type = RenderType.solid(); - } else { - type = ItemBlockRenderTypes.getRenderType(blockState); + var bakedModel = client.getBlockRenderer().getBlockModel(blockState); + int color = client.getBlockColors().getColor(blockState, client.level, blockPos, 0); + //dont know why there is a 0. + //see https://github.com/senseiwells/EssentialClient/blob/4db1f291936f502304791ee323f369c206b3021d/src/main/java/me/senseiwells/essentialclient/utils/render/RenderHelper.java#L464 + float red = (color >> 16 & 0xFF) / 255.0F; + float green = (color >> 8 & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + RenderType type; + if (blockState.getBlock() instanceof LeavesBlock && !Minecraft.useFancyGraphics()) { + type = RenderType.solid(); + } else { + type = ItemBlockRenderTypes.getRenderType(blockState); + } + client.getBlockRenderer().getModelRenderer().renderModel(matrices.last(), immediate.getBuffer(type), blockState, bakedModel, red, green, blue, light, OverlayTexture.NO_OVERLAY); } - client.getBlockRenderer().getModelRenderer().renderModel(matrices.last(), immediate.getBuffer(type), blockState, bakedModel, red, green, blue, light, OverlayTexture.NO_OVERLAY); - } - // draw the block`s entity part - if (BlockEntity == null) - { - if (blockState.getBlock() instanceof EntityBlock eb) + // draw the block`s entity part + if (BlockEntity == null) { - BlockEntity = eb.newBlockEntity(blockPos, blockState); - if (BlockEntity != null) + if (blockState.getBlock() instanceof EntityBlock eb) { - BlockEntity.setLevel(client.level); - if (shape.blockEntity != null) + BlockEntity = eb.newBlockEntity(blockPos, blockState); + if (BlockEntity != null) { - BlockEntity.loadWithComponents(shape.blockEntity, client.level.registryAccess()); + BlockEntity.setLevel(client.level); + if (shape.blockEntity != null) + { + BlockEntity.loadWithComponents(shape.blockEntity, client.level.registryAccess()); + } } } } - } - if (BlockEntity != null) - { - BlockEntityRenderer blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity); - if (blockEntityRenderer != null) - { - blockEntityRenderer.render(BlockEntity, partialTick, - matrices, immediate, light, OverlayTexture.NO_OVERLAY); + if (BlockEntity != null) + { + BlockEntityRenderer blockEntityRenderer = client.getBlockEntityRenderDispatcher().getRenderer(BlockEntity); + if (blockEntityRenderer != null) + { + blockEntityRenderer.render(BlockEntity, partialTick, + matrices, immediate, light, OverlayTexture.NO_OVERLAY); - } + } + } + }else{ + var fluidstate = blockState.getFluidState(); + try { + DrawingShape.set(Pair.of(matrices.last(),blockPos)); + client.getBlockRenderer().renderLiquid(blockPos, client.level, immediate.getBuffer(ItemBlockRenderTypes.getRenderLayer(fluidstate)), blockState, fluidstate); + }finally { + DrawingShape.remove(); + } } } else @@ -457,6 +525,11 @@ public void renderLines(PoseStack matrices, Tesselator tesselator, double cx, do } + @Override + public void renderLines(PoseStack matrices, Tesselator tesselator, double cx, double cy, double cz, float partialTick) { + + } + @Override public boolean stageDeux() { diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index dee7b1676..c6d27949a 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -200,6 +200,7 @@ "ClientPacketListener_customPacketsMixin", "DebugRenderer_scarpetRenderMixin", "LevelRenderer_scarpetRenderMixin", + "FluidRenderingMixin", "ClientCommonPacketListenerImpl_customPacketMixin"