From 33a3f2c6148ab60df84fcb8b38350157e6a8d14d Mon Sep 17 00:00:00 2001 From: Zpiboo Date: Fri, 22 Aug 2025 19:55:14 +0200 Subject: [PATCH 1/3] fix: use DrawContext scissor methods instead of GL ones in 1.20+ (GL's scissor boxes don't work in newer versions :'( ) --- .../fabric_1_20_4/FunctionCompatibility.java | 22 ++++++++----------- .../fabric_1_20_6/FunctionCompatibility.java | 22 ++++++++----------- .../fabric_1_21_3/FunctionCompatibility.java | 22 ++++++++----------- .../fabric_1_21_5/FunctionCompatibility.java | 22 ++++++++----------- .../fabric_1_21_5/FunctionCompatibility.java | 22 ++++++++----------- .../fabric_1_21/FunctionCompatibility.java | 22 ++++++++----------- 6 files changed, 54 insertions(+), 78 deletions(-) diff --git a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java index c17cff10..0fbab932 100644 --- a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java +++ b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java @@ -21,7 +21,6 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.client.render.*; import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.Registries; @@ -32,11 +31,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -254,19 +252,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } diff --git a/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java b/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java index d2b19659..5d269d12 100644 --- a/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java +++ b/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java @@ -21,7 +21,6 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.client.render.*; import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.registry.Registries; import net.minecraft.sound.SoundEvents; @@ -31,11 +30,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -253,19 +251,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } diff --git a/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java b/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java index bcc525cd..0d70a6ca 100644 --- a/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java +++ b/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java @@ -22,7 +22,6 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.client.render.*; import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.registry.Registries; import net.minecraft.sound.SoundEvents; @@ -33,11 +32,10 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.profiler.Profilers; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -250,19 +248,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } diff --git a/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java b/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java index 95216c78..55f55937 100644 --- a/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java +++ b/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java @@ -23,7 +23,6 @@ import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexRendering; import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.registry.Registries; import net.minecraft.sound.SoundEvents; @@ -33,11 +32,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.profiler.Profilers; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -189,19 +187,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } diff --git a/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java b/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java index de2aa710..68de5db1 100644 --- a/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java +++ b/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java @@ -29,7 +29,6 @@ import net.minecraft.client.render.VertexRendering; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.client.texture.TextureSetup; -import net.minecraft.client.util.Window; import net.minecraft.registry.Registries; import net.minecraft.sound.SoundEvents; import net.minecraft.util.Util; @@ -39,11 +38,10 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.profiler.Profilers; import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -197,19 +195,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java index 70fb00d3..21025552 100644 --- a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java @@ -21,7 +21,6 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.client.render.*; import net.minecraft.client.sound.PositionedSoundInstance; -import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.registry.Registries; import net.minecraft.sound.SoundEvents; @@ -31,11 +30,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; import java.awt.*; -import java.util.List; import java.util.*; +import java.util.List; public class FunctionCompatibility implements FunctionHolder, SoundManager.Interface, @@ -250,19 +248,17 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + int x1 = (int) x; + int y1 = (int) y; + int x2 = (int) (x + w); + int y2 = (int) (y + h); + drawContext.enableScissor(x1, y1, x2, y2); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + try { + drawContext.disableScissor(); + } catch (IllegalStateException ignored) {} } From 5c1f99736fe60bae1a54abeeee73ead23ac661e9 Mon Sep 17 00:00:00 2001 From: Zpiboo Date: Sat, 23 Aug 2025 13:47:05 +0200 Subject: [PATCH 2/3] refactor: rework scissor stack handling - Move Renderer2D's scissorStack to version-specific code for older versions, as newer ones already have it built-in along with a scissorContains method. - Take the current scissor into account in the Component::contains method. --- .../compatibility/MCClasses/Renderer2D.java | 49 ++++--------- .../mpkmod/gui/components/Component.java | 4 +- .../fabric_1_19_4/FunctionCompatibility.java | 67 +++++++++++++++--- .../fabric_1_20_4/FunctionCompatibility.java | 66 +++++++++++++++--- .../fabric_1_20_6/FunctionCompatibility.java | 14 ++++ .../fabric_1_21_3/FunctionCompatibility.java | 16 ++++- .../fabric_1_21_5/FunctionCompatibility.java | 14 ++++ .../fabric_1_21_5/FunctionCompatibility.java | 14 ++++ .../fabric_1_21/FunctionCompatibility.java | 14 ++++ .../forge_1_8/FunctionCompatibility.java | 68 ++++++++++++++++--- 10 files changed, 261 insertions(+), 65 deletions(-) diff --git a/common/src/main/java/io/github/kurrycat/mpkmod/compatibility/MCClasses/Renderer2D.java b/common/src/main/java/io/github/kurrycat/mpkmod/compatibility/MCClasses/Renderer2D.java index db60b756..1eca0626 100644 --- a/common/src/main/java/io/github/kurrycat/mpkmod/compatibility/MCClasses/Renderer2D.java +++ b/common/src/main/java/io/github/kurrycat/mpkmod/compatibility/MCClasses/Renderer2D.java @@ -7,11 +7,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Optional; -import java.util.Stack; public class Renderer2D { - private static final Stack scissorStack = new Stack<>(); - /** * @param pos top left corner of the rectangle * @param size size of the rectangle (edge is contained within) @@ -101,36 +98,25 @@ public static void drawLines(Collection points, Color color) { } public static void enableScissor(double x, double y, double w, double h) { - ScissorBox box; - if (scissorStack.isEmpty()) box = new ScissorBox(x, y, w, h); - else { - ScissorBox prev = scissorStack.peek(); - double bx = Math.max(prev.x, x), by = Math.max(prev.y, y); - box = new ScissorBox(bx, by, - Math.min(x + w, prev.x + prev.w) - bx, - Math.min(y + h, prev.y + prev.h) - by - ); - } - scissorStack.push(box); - setScissor(box); - } - - private static void setScissor(ScissorBox box) { Optional renderer = Interface.get(); - if (!renderer.isPresent()) return; - if (box == null) renderer.get().disableScissor(); - else renderer.get().enableScissor(box.x, box.y, box.w, box.h); + renderer.ifPresent(renderer2DInterface -> renderer2DInterface.enableScissor(x, y, w, h)); } public static void endFrame() { - setScissor(null); - scissorStack.clear(); + Optional renderer = Interface.get(); + renderer.ifPresent(Interface::clearScissors); } public static void disableScissor() { - if (!scissorStack.isEmpty()) scissorStack.pop(); - if (scissorStack.isEmpty()) setScissor(null); - else setScissor(scissorStack.peek()); + Optional renderer = Interface.get(); + renderer.ifPresent(Interface::disableScissor); + } + + public static boolean scissorContains(Vector2D point) { + Optional renderer = Interface.get(); + return renderer + .map(renderer2DInterface -> renderer2DInterface.scissorContains(point)) + .orElse(false); } public interface Interface extends FunctionHolder { @@ -149,16 +135,9 @@ static Optional get() { void enableScissor(double x, double y, double w, double h); void disableScissor(); - } - private static class ScissorBox { - public double x, y, w, h; + void clearScissors(); - public ScissorBox(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } + boolean scissorContains(Vector2D point); } } diff --git a/common/src/main/java/io/github/kurrycat/mpkmod/gui/components/Component.java b/common/src/main/java/io/github/kurrycat/mpkmod/gui/components/Component.java index 936b0aa5..cc3228f0 100644 --- a/common/src/main/java/io/github/kurrycat/mpkmod/gui/components/Component.java +++ b/common/src/main/java/io/github/kurrycat/mpkmod/gui/components/Component.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonSetter; +import io.github.kurrycat.mpkmod.compatibility.MCClasses.Renderer2D; import io.github.kurrycat.mpkmod.util.JSONPos2D; import io.github.kurrycat.mpkmod.util.Mouse; import io.github.kurrycat.mpkmod.util.Vector2D; @@ -73,7 +74,8 @@ public PopupMenu getPopupMenu() { public boolean contains(Vector2D testPos) { if (testPos == null) return false; if (getDisplayedPos() == null) return false; - return testPos.isInRectBetween(getDisplayedPos(), getDisplayedPos().add(getDisplayedSize())); + return Renderer2D.scissorContains(testPos) && + testPos.isInRectBetween(getDisplayedPos(), getDisplayedPos().add(getDisplayedSize())); } @Override diff --git a/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java b/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java index f034f4b4..92d2e4e5 100644 --- a/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java +++ b/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java @@ -48,6 +48,7 @@ public class FunctionCompatibility implements FunctionHolder, Profiler.Interface { public static final Set pressedButtons = new HashSet<>(); public MatrixStack matrixStack = new MatrixStack(); + private static final Stack scissorStack = new Stack<>(); public void playButtonSound() { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); @@ -253,19 +254,49 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); - Window r = MinecraftClient.getInstance().getWindow(); - - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + ScissorBox box; + if (scissorStack.isEmpty()) box = new ScissorBox(x, y, w, h); + else { + ScissorBox prev = scissorStack.peek(); + double bx = Math.max(prev.x, x), by = Math.max(prev.y, y); + box = new ScissorBox(bx, by, + Math.min(x + w, prev.x + prev.w) - bx, + Math.min(y + h, prev.y + prev.h) - by + ); + } + scissorStack.push(box); + setScissor(box); } public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + if (!scissorStack.isEmpty()) scissorStack.pop(); + if (scissorStack.isEmpty()) setScissor(null); + else setScissor(scissorStack.peek()); + } + + public void clearScissors() { + scissorStack.clear(); + setScissor(null); + } + + private void setScissor(ScissorBox box) { + if (box == null) { + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } else { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + Window r = MinecraftClient.getInstance().getWindow(); + + double scaleFactor = r.getScaleFactor(); + double posX = box.x * scaleFactor; + double posY = r.getFramebufferHeight() - (box.y + box.h) * scaleFactor; + double width = box.w * scaleFactor; + double height = box.h * scaleFactor; + GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + } + } + + public boolean scissorContains(Vector2D point) { + return scissorStack.isEmpty() || scissorStack.peek().contains(point); } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { @@ -421,4 +452,20 @@ public void endStartSection(String name) { public void endSection() { MinecraftClient.getInstance().getProfiler().pop(); } + + private static class ScissorBox { + public double x, y, w, h; + + public ScissorBox(double x, double y, double w, double h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public boolean contains(Vector2D point) { + return x <= point.getX() && point.getX() < x + w && + y <= point.getY() && point.getY() < y + h; + } + } } diff --git a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java index 0fbab932..c1c2970e 100644 --- a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java +++ b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java @@ -21,6 +21,7 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.client.render.*; import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.Registries; @@ -31,6 +32,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; import java.awt.*; import java.util.*; @@ -47,6 +49,7 @@ public class FunctionCompatibility implements FunctionHolder, Profiler.Interface { public static final Set pressedButtons = new HashSet<>(); public DrawContext drawContext = null; + private static final Stack scissorStack = new Stack<>(); public void playButtonSound() { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); @@ -252,19 +255,50 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - int x1 = (int) x; - int y1 = (int) y; - int x2 = (int) (x + w); - int y2 = (int) (y + h); - drawContext.enableScissor(x1, y1, x2, y2); + ScissorBox box; + if (scissorStack.isEmpty()) box = new ScissorBox(x, y, w, h); + else { + ScissorBox prev = scissorStack.peek(); + double bx = Math.max(prev.x, x), by = Math.max(prev.y, y); + box = new ScissorBox(bx, by, + Math.min(x + w, prev.x + prev.w) - bx, + Math.min(y + h, prev.y + prev.h) - by + ); + } + scissorStack.push(box); + setScissor(box); } public void disableScissor() { - try { - drawContext.disableScissor(); - } catch (IllegalStateException ignored) {} + if (!scissorStack.isEmpty()) scissorStack.pop(); + if (scissorStack.isEmpty()) setScissor(null); + else setScissor(scissorStack.peek()); + } + + public void clearScissors() { + scissorStack.clear(); + setScissor(null); } + private void setScissor(ScissorBox box) { + if (box == null) { + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } else { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + Window r = MinecraftClient.getInstance().getWindow(); + + double scaleFactor = r.getScaleFactor(); + double posX = box.x * scaleFactor; + double posY = r.getFramebufferHeight() - (box.y + box.h) * scaleFactor; + double width = box.w * scaleFactor; + double height = box.h * scaleFactor; + GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + } + } + + public boolean scissorContains(Vector2D point) { + return scissorStack.isEmpty() || scissorStack.peek().contains(point); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; @@ -419,4 +453,20 @@ public void endStartSection(String name) { public void endSection() { MinecraftClient.getInstance().getProfiler().pop(); } + + private static class ScissorBox { + public double x, y, w, h; + + public ScissorBox(double x, double y, double w, double h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public boolean contains(Vector2D point) { + return x <= point.getX() && point.getX() < x + w && + y <= point.getY() && point.getY() < y + h; + } + } } diff --git a/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java b/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java index 5d269d12..7e1d53d7 100644 --- a/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java +++ b/fabric-1.20.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_6/FunctionCompatibility.java @@ -264,6 +264,20 @@ public void disableScissor() { } catch (IllegalStateException ignored) {} } + public void clearScissors() { + boolean clearedAll = false; + while (!clearedAll) { + try { + drawContext.disableScissor(); + } catch (IllegalStateException e) { + clearedAll = true; + } + } + } + + public boolean scissorContains(Vector2D point) { + return drawContext.scissorContains(point.getXI(), point.getYI()); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; diff --git a/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java b/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java index 0d70a6ca..7c2ad19f 100644 --- a/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java +++ b/fabric-1.21.3/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_3/FunctionCompatibility.java @@ -125,7 +125,7 @@ public String getLookingAtBlock() { public void drawBox(BoundingBox3D bb, Color color, float partialTicks) { int r = color.getRed(), g = color.getGreen(), b = color.getBlue(), a = color.getAlpha(); - + RenderSystem.enableBlend(); RenderSystem.enableDepthTest(); RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); @@ -261,6 +261,20 @@ public void disableScissor() { } catch (IllegalStateException ignored) {} } + public void clearScissors() { + boolean clearedAll = false; + while (!clearedAll) { + try { + drawContext.disableScissor(); + } catch (IllegalStateException e) { + clearedAll = true; + } + } + } + + public boolean scissorContains(Vector2D point) { + return drawContext.scissorContains(point.getXI(), point.getYI()); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; diff --git a/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java b/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java index 55f55937..257de18e 100644 --- a/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java +++ b/fabric-1.21.5/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java @@ -200,6 +200,20 @@ public void disableScissor() { } catch (IllegalStateException ignored) {} } + public void clearScissors() { + boolean clearedAll = false; + while (!clearedAll) { + try { + drawContext.disableScissor(); + } catch (IllegalStateException e) { + clearedAll = true; + } + } + } + + public boolean scissorContains(Vector2D point) { + return drawContext.scissorContains(point.getXI(), point.getYI()); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; diff --git a/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java b/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java index 68de5db1..5759a2ec 100644 --- a/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java +++ b/fabric-1.21.6/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21_5/FunctionCompatibility.java @@ -208,6 +208,20 @@ public void disableScissor() { } catch (IllegalStateException ignored) {} } + public void clearScissors() { + boolean clearedAll = false; + while (!clearedAll) { + try { + drawContext.disableScissor(); + } catch (IllegalStateException e) { + clearedAll = true; + } + } + } + + public boolean scissorContains(Vector2D point) { + return drawContext.scissorContains(point.getXI(), point.getYI()); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java index 21025552..9a12590d 100644 --- a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java @@ -261,6 +261,20 @@ public void disableScissor() { } catch (IllegalStateException ignored) {} } + public void clearScissors() { + boolean clearedAll = false; + while (!clearedAll) { + try { + drawContext.disableScissor(); + } catch (IllegalStateException e) { + clearedAll = true; + } + } + } + + public boolean scissorContains(Vector2D point) { + return drawContext.scissorContains(point.getXI(), point.getYI()); + } public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { if (drawContext == null) return; diff --git a/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java b/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java index 996d8cba..0608ff35 100644 --- a/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java +++ b/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java @@ -47,6 +47,8 @@ public class FunctionCompatibility implements FunctionHolder, io.github.kurrycat.mpkmod.compatibility.MCClasses.Minecraft.Interface, io.github.kurrycat.mpkmod.compatibility.MCClasses.Keyboard.Interface, Profiler.Interface { + private static final Stack scissorStack = new Stack<>(); + /** * Is called in {@link SoundManager.Interface} */ @@ -249,20 +251,50 @@ public Vector2D getScreenSize() { } public void enableScissor(double x, double y, double w, double h) { - GL11.glEnable(GL11.GL_SCISSOR_TEST); + ScissorBox box; + if (scissorStack.isEmpty()) box = new ScissorBox(x, y, w, h); + else { + ScissorBox prev = scissorStack.peek(); + double bx = Math.max(prev.x, x), by = Math.max(prev.y, y); + box = new ScissorBox(bx, by, + Math.min(x + w, prev.x + prev.w) - bx, + Math.min(y + h, prev.y + prev.h) - by + ); + } + scissorStack.push(box); + setScissor(box); + } - ScaledResolution r = new ScaledResolution(Minecraft.getMinecraft()); + public void disableScissor() { + if (!scissorStack.isEmpty()) scissorStack.pop(); + if (scissorStack.isEmpty()) setScissor(null); + else setScissor(scissorStack.peek()); + } - double scaleFactor = r.getScaleFactor(); - double posX = x * scaleFactor; - double posY = Minecraft.getMinecraft().displayHeight - (y + h) * scaleFactor; - double width = w * scaleFactor; - double height = h * scaleFactor; - GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + public void clearScissors() { + scissorStack.clear(); + setScissor(null); } - public void disableScissor() { - GL11.glDisable(GL11.GL_SCISSOR_TEST); + private void setScissor(ScissorBox box) { + if (box == null) { + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } else { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + + ScaledResolution r = new ScaledResolution(Minecraft.getMinecraft()); + + double scaleFactor = r.getScaleFactor(); + double posX = box.x * scaleFactor; + double posY = Minecraft.getMinecraft().displayHeight - (box.y + box.h) * scaleFactor; + double width = box.w * scaleFactor; + double height = box.h * scaleFactor; + GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + } + } + + public boolean scissorContains(Vector2D point) { + return scissorStack.isEmpty() || scissorStack.peek().contains(point); } /** @@ -432,4 +464,20 @@ public void endStartSection(String name) { public void endSection() { Minecraft.getMinecraft().mcProfiler.endSection(); } + + private static class ScissorBox { + public double x, y, w, h; + + public ScissorBox(double x, double y, double w, double h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public boolean contains(Vector2D point) { + return x <= point.getX() && point.getX() < x + w && + y <= point.getY() && point.getY() < y + h; + } + } } From e14a4bfe6fc9fce86f5945de4f13304c2af7a15d Mon Sep 17 00:00:00 2001 From: Exterminate Date: Wed, 3 Sep 2025 10:20:59 +1000 Subject: [PATCH 3/3] Remove duplicate class --- .../github/kurrycat/mpkmod/util/ScissorBox.java | 17 +++++++++++++++++ .../fabric_1_19_4/FunctionCompatibility.java | 17 +---------------- .../fabric_1_20_4/FunctionCompatibility.java | 17 +---------------- .../forge_1_8/FunctionCompatibility.java | 17 +---------------- 4 files changed, 20 insertions(+), 48 deletions(-) create mode 100644 common/src/main/java/io/github/kurrycat/mpkmod/util/ScissorBox.java diff --git a/common/src/main/java/io/github/kurrycat/mpkmod/util/ScissorBox.java b/common/src/main/java/io/github/kurrycat/mpkmod/util/ScissorBox.java new file mode 100644 index 00000000..9cf66ed4 --- /dev/null +++ b/common/src/main/java/io/github/kurrycat/mpkmod/util/ScissorBox.java @@ -0,0 +1,17 @@ +package io.github.kurrycat.mpkmod.util; + +public class ScissorBox { + public double x, y, w, h; + + public ScissorBox(double x, double y, double w, double h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public boolean contains(Vector2D point) { + return x <= point.getX() && point.getX() < x + w && + y <= point.getY() && point.getY() < y + h; + } +} \ No newline at end of file diff --git a/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java b/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java index 92d2e4e5..81fd7705 100644 --- a/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java +++ b/fabric-1.19.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_19_4/FunctionCompatibility.java @@ -8,6 +8,7 @@ import io.github.kurrycat.mpkmod.util.Debug; import io.github.kurrycat.mpkmod.util.Vector2D; import io.github.kurrycat.mpkmod.util.Vector3D; +import io.github.kurrycat.mpkmod.util.ScissorBox; import io.github.kurrycat.mpknetapi.common.network.packet.MPKPacket; import io.netty.buffer.Unpooled; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; @@ -452,20 +453,4 @@ public void endStartSection(String name) { public void endSection() { MinecraftClient.getInstance().getProfiler().pop(); } - - private static class ScissorBox { - public double x, y, w, h; - - public ScissorBox(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - public boolean contains(Vector2D point) { - return x <= point.getX() && point.getX() < x + w && - y <= point.getY() && point.getY() < y + h; - } - } } diff --git a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java index c1c2970e..c568856e 100644 --- a/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java +++ b/fabric-1.20.4/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_20_4/FunctionCompatibility.java @@ -8,6 +8,7 @@ import io.github.kurrycat.mpkmod.util.Debug; import io.github.kurrycat.mpkmod.util.Vector2D; import io.github.kurrycat.mpkmod.util.Vector3D; +import io.github.kurrycat.mpkmod.util.ScissorBox; import io.github.kurrycat.mpknetapi.common.network.packet.MPKPacket; import io.netty.buffer.Unpooled; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; @@ -453,20 +454,4 @@ public void endStartSection(String name) { public void endSection() { MinecraftClient.getInstance().getProfiler().pop(); } - - private static class ScissorBox { - public double x, y, w, h; - - public ScissorBox(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - public boolean contains(Vector2D point) { - return x <= point.getX() && point.getX() < x + w && - y <= point.getY() && point.getY() < y + h; - } - } } diff --git a/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java b/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java index 0608ff35..ba491be0 100644 --- a/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java +++ b/forge-1.8.9/src/main/java/io/github/kurrycat/mpkmod/compatibility/forge_1_8/FunctionCompatibility.java @@ -5,6 +5,7 @@ import io.github.kurrycat.mpkmod.util.Debug; import io.github.kurrycat.mpkmod.util.Vector2D; import io.github.kurrycat.mpkmod.util.Vector3D; +import io.github.kurrycat.mpkmod.util.ScissorBox; import io.github.kurrycat.mpknetapi.common.network.packet.MPKPacket; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; @@ -464,20 +465,4 @@ public void endStartSection(String name) { public void endSection() { Minecraft.getMinecraft().mcProfiler.endSection(); } - - private static class ScissorBox { - public double x, y, w, h; - - public ScissorBox(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - public boolean contains(Vector2D point) { - return x <= point.getX() && point.getX() < x + w && - y <= point.getY() && point.getY() < y + h; - } - } }