From 0b469e6a5a5237118933d71f5505c432ead26640 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 18:23:31 +0100 Subject: [PATCH 01/12] Improved RenderScope for 1.21.4 #59 --- common | 2 +- .../features/mixins/render/RenderMixin.java | 4 +- .../impl/mixins/MatrixStackMixin.java | 35 +- .../impl/ui/EntityDrawerImpl.java | 36 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 642 ++++++++---------- .../saturnclient/impl/ui/RenderScopeImpl.java | 9 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 7 +- 7 files changed, 335 insertions(+), 400 deletions(-) diff --git a/common b/common index 6873f76..c72af13 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 6873f76c437c192cc8d386fb051dab12a2307bf7 +Subproject commit c72af1300a3783ad2b45405243a74aad7debfade diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java index caec854..124dc4f 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java @@ -65,8 +65,8 @@ public class RenderMixin { ModLayout dim = hud.getDimensions(); scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0f); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); + scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); + scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); if (dim.renderBackground) { scope.drawRoundedRectangle(0, 0, dim.width, dim.height, diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java index d8e88a4..b128808 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java @@ -1,59 +1,32 @@ package org.saturnclient.impl.mixins; -import org.joml.Quaternionf; import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.common.ref.render.QuaternionfRef; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Invoker; import net.minecraft.client.util.math.MatrixStack; @Mixin(MatrixStack.class) public abstract class MatrixStackMixin implements MatrixStackRef { - - @Shadow - public abstract void translate(double x, double y, double z); - @Shadow public abstract void translate(float x, float y, float z); @Shadow public abstract void scale(float x, float y, float z); - @Shadow - public abstract void multiply(Quaternionf quaternion); - - @Shadow - public abstract void multiply(Quaternionf quaternion, float originX, float originY, float originZ); - @Shadow public abstract void push(); @Shadow public abstract void pop(); - @Invoker("peek") - public abstract MatrixStack.Entry peekM(); - - @Shadow - public abstract boolean isEmpty(); - - @Shadow - public abstract void loadIdentity(); - @Override - public void multiply(QuaternionfRef quaternion) { - this.multiply((Quaternionf) quaternion); + public void translate(float x, float y) { + translate(x, y, 0); } @Override - public void multiply(QuaternionfRef quaternion, float originX, float originY, float originZ) { - this.multiply((Quaternionf) quaternion, originX, originY, originZ); - } - - @Override - public Object peek() { - return this.peekM(); + public void scale(float x, float y) { + scale(x, y, 1.0f); } } \ No newline at end of file diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index 9f9781f..77c8da3 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -3,7 +3,6 @@ package org.saturnclient.impl.ui; import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; -import org.saturnclient.common.ref.render.QuaternionfRef; import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; @@ -51,27 +50,28 @@ public class EntityDrawerImpl implements EntityDrawer { public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - renderScope.getMatrixStack().push(); - renderScope.getMatrixStack().translate((double) x, (double) y, 50.0); - renderScope.getMatrixStack().scale(size, size, -size); - renderScope.getMatrixStack().translate(vector3f.x, vector3f.y, vector3f.z); - renderScope.getMatrixStack().multiply((QuaternionfRef) quaternionf); - renderScope.draw(); - DiffuseLighting.method_34742(); - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + if (renderScope instanceof RenderScopeImpl scopeImpl) { + scopeImpl.matrices.push(); + scopeImpl.matrices.translate((double) x, (double) y, 0); + scopeImpl.matrices.scale(size, size, -size); + scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); + scopeImpl.matrices.multiply(quaternionf); + scopeImpl.draw(); + DiffuseLighting.method_34742(); + EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - entityRenderDispatcher.setRenderShadows(false); - if (renderScope instanceof RenderScopeImpl r) { - r.draw((vertexConsumers) -> { + entityRenderDispatcher.setRenderShadows(false); + scopeImpl.draw((vertexConsumers) -> { entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - r.matrices, vertexConsumers, - 15728880); + scopeImpl.matrices, vertexConsumers, 15728880); }); + + scopeImpl.draw(); + entityRenderDispatcher.setRenderShadows(true); + scopeImpl.getMatrixStack().pop(); + DiffuseLighting.enableGuiDepthLighting(); } - renderScope.draw(); - entityRenderDispatcher.setRenderShadows(true); - renderScope.getMatrixStack().pop(); - DiffuseLighting.enableGuiDepthLighting(); + } @Override diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 18e1ff9..ca83041 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -46,12 +46,18 @@ import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; public class RenderScopeImpl implements RenderScope { + // ---------------------------- + // Fields + // ---------------------------- public MatrixStack matrices; public VertexConsumerProvider.Immediate vertexConsumers; private ScissorStack scissorStack = new ScissorStack(); private int opacity = 255 << 24; private final ItemRenderState itemRenderState; + // ---------------------------- + // Constructors + // ---------------------------- public RenderScopeImpl(DrawContext context) { this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); } @@ -63,11 +69,17 @@ public class RenderScopeImpl implements RenderScope { this.itemRenderState = new ItemRenderState(); } + // ---------------------------- + // Matrix & Transform + // ---------------------------- @Override public MatrixStackRef getMatrixStack() { return (MatrixStackRef) matrices; } + // ---------------------------- + // Color & Opacity + // ---------------------------- @Override public void setOpacity(float alpha) { this.opacity = (int) (alpha * 255) << 24; @@ -81,132 +93,12 @@ public class RenderScopeImpl implements RenderScope { return (mixedAlpha << 24) | (color & 0x00FFFFFF); } + // ---------------------------- + // Draw / Window Info + // ---------------------------- @Override - public void drawRect(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - int i; - if (x1 < x2) { - i = x1; - x1 = x2; - x2 = i; - } - - if (y1 < y2) { - i = y1; - y1 = y2; - y2 = i; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) { - scale *= 2; - } - int i = 0; - for (String line : text.split("\n")) { - color = getColor(color); - matrices.push(); - matrices.translate(x, y + (i * Fonts.getHeight()), 0); - matrices.scale(scale, scale, 1.0f); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - textRenderer.draw((Text) Fonts.setFont(line, font), 0, - font == 0 ? 1 : 7, color, false, - this.matrices.peek().getPositionMatrix(), - this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880); - matrices.pop(); - i++; - } - } - - private void drawRoundedCorner(int width, int height, int radius, int color) { - int w = width * 20; - int h = height * 20; - - for (int y = 0; y < h; y++) { - int startX = 0; - - if (y < radius) { - double dy = radius - y - 0.5; - double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); - startX = radius - (int) dx; - } - - this.drawRect(startX, y, w - startX, 1, color); - } - } - - private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - // Top - this.matrices.push(); - - this.matrices.scale(0.05f, 0.05f, 1.0f); - - this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - - this.matrices.pop(); - - // Bottom - this.matrices.push(); - - this.matrices.translate(cornerWidth, cornerHeight * 2, 0); - - this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); - - this.matrices.translate(0, -cornerWidth, 0); - - this.matrices.scale(0.05f, 0.05f, 1.0f); - - this.drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - - this.matrices.pop(); - } - - @Override - public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { - if (color == 0) - return; - radius = Math.min(radius, Math.min(width, height)); - int cornerWidth = width / 2; - int cornerHeight = height / 2; - - this.matrices.push(); - - this.matrices.translate(x, y, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); - - this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); - - this.matrices.translate(0, 0, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.pop(); + public void draw() { + this.vertexConsumers.draw(); } @Override @@ -219,66 +111,221 @@ public class RenderScopeImpl implements RenderScope { return SaturnClient.client.getWindow().getScaledHeight(); } + public void draw(Consumer drawer) { + drawer.accept(this.vertexConsumers); + this.vertexConsumers.draw(); + } + + // ---------------------------- + // Shapes + // ---------------------------- @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); - } - - /* Minecraft sprites */ - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad(sprite, x, x + width, y, y + height, (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, - float v2, int color) { - - if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - + public void drawRectangle(int x, int y, int width, int height, int color) { if (color == 0) return; + color = getColor(color); + + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); + vertexConsumer.vertex(matrix4f, x1, y1, 0).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).color(color); + } + + @Override + public void fill(int x1, int y1, int x2, int y2, int color) { + fill(x1, y1, x2, y2, 0, color); + } + + public void fill(int x1, int y1, int x2, int y2, int z, int color) { + fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { + fill(layer, x1, y1, x2, y2, 0, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); + vertexConsumer.vertex(matrix4f, x1, y1, z).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, z).color(color); + } + + @Override + public void drawBorder(int x, int y, int width, int height, int color) { + fill(x, y, x + width, y + 1, color); + fill(x, y + height - 1, x + width, y + height, color); + fill(x, y + 1, x + 1, y + height - 1, color); + fill(x + width - 1, y + 1, x + width, y + height - 1, color); + } + + @Override + public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { + if (color == 0) + return; + + radius = Math.min(radius, Math.min(width, height)); + int cornerWidth = width / 2; + int cornerHeight = height / 2; + + matrices.push(); + matrices.translate(x, y, 0); + + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); + matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + matrices.pop(); + } + + // Rounded rectangle helpers + private void drawRoundedCorner(int width, int height, int radius, int color) { + int w = width * 20; + int h = height * 20; + + for (int y = 0; y < h; y++) { + int startX = 0; + if (y < radius) { + double dy = radius - y - 0.5; + double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); + startX = radius - (int) dx; + } + drawRectangle(startX, y, w - startX, 1, color); + } + } + + private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { + // Top + matrices.push(); + matrices.scale(0.05f, 0.05f, 1.0f); + drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); + matrices.pop(); + + // Bottom + matrices.push(); + matrices.translate(cornerWidth, cornerHeight * 2, 0); + matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); + matrices.translate(0, -cornerWidth, 0); + matrices.scale(0.05f, 0.05f, 1.0f); + drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); + matrices.pop(); + } + + // ---------------------------- + // Text + // ---------------------------- + @Override + public void drawText(String text, int x, int y, int font, int color) { + drawText(1.0f, text, x, y, font, color); + } + + @Override + public void drawText(float scale, String text, int x, int y, int font, int color) { + if (color == 0) + return; + if (font == 0) + scale *= 2; + + int i = 0; + for (String line : text.split("\n")) { + color = getColor(color); + matrices.push(); + matrices.translate(x, y + i * Fonts.getHeight(), 0); + matrices.scale(scale, scale, 1.0f); + TextRenderer textRenderer = SaturnClient.client.textRenderer; + textRenderer.draw((Text) Fonts.setFont(line, font), 0, font == 0 ? 1 : 7, color, false, + matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, 15728880); + matrices.pop(); + i++; + } + } + + // ---------------------------- + // Textures & Sprites + // ---------------------------- + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight) { + drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { + drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, + (u + 0.0f) / textureWidth, (u + regionWidth) / textureWidth, + (v + 0.0f) / textureHeight, (v + regionHeight) / textureHeight, color); + } + + @Override + public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { + drawSpriteStretched(sprite, x, y, width, height, -1); + } + + @Override + public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { + Sprite sprite = (Sprite) saturnSprite; + if (color == 0) + return; + if (width != 0 && height != 0) { + drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, + sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color); + } + } + + private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, + float u1, float u2, float v1, float v2, int color) { + if (sprite.toString().endsWith(".svg")) { + sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), + (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); + } + if (color == 0) + return; + x1 *= 4; x2 *= 4; y1 *= 4; @@ -288,58 +335,99 @@ public class RenderScopeImpl implements RenderScope { matrices.push(); matrices.scale(0.25f, 0.25f, 1.0f); RenderSystem.setShaderTexture(0, sprite); - RenderLayer renderLayer = (RenderLayer) RenderLayer.getGuiTextured(sprite); - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0.0F).texture(u1, v1).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0.0F).texture(u1, v2).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0.0F).texture(u2, v2).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0.0F).texture(u2, v1).color(color); + RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); + Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); + vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(u1, v1).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(u1, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(u2, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(u2, v1).color(color); matrices.pop(); } + // ---------------------------- + // Items + // ---------------------------- + @Override + public void drawItem(ItemStackRef item, int x, int y) { + drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, + int seed) { + drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, + int z) { + if (stack.isEmpty()) + return; + + SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ModelTransformationMode.GUI, + false, world, entity, seed); + + matrices.push(); + matrices.translate(x + 8, y + 8, 150 + (itemRenderState.hasDepth() ? z : 0)); + + try { + matrices.scale(16.0f, -16.0f, 16.0f); + boolean disableLighting = !itemRenderState.isSideLit(); + if (disableLighting) { + draw(); + DiffuseLighting.disableGuiDepthLighting(); + } + + itemRenderState.render(matrices, vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); + draw(); + + if (disableLighting) + DiffuseLighting.enableGuiDepthLighting(); + } catch (Throwable e) { + CrashReport crashReport = CrashReport.create(e, "Rendering item"); + CrashReportSection section = crashReport.addElement("Item being rendered"); + section.add("Item Type", () -> String.valueOf(stack.getItem())); + section.add("Item Components", () -> String.valueOf(stack.getComponents())); + section.add("Item Foil", () -> String.valueOf(stack.hasGlint())); + throw new CrashException(crashReport); + } + + matrices.pop(); + } + + // ---------------------------- + // Scissor / Clipping + // ---------------------------- @Override public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)) - .transform(this.matrices.peek().getPositionMatrix()); - this.setScissor(this.scissorStack.push(screenRect)); + ScreenRect screenRect = new ScreenRect(x1, y1, x2 - x1, y2 - y1) + .transform(matrices.peek().getPositionMatrix()); + setScissor(scissorStack.push(screenRect)); } @Override public void disableScissor() { - this.setScissor(this.scissorStack.pop()); + setScissor(scissorStack.pop()); } @Override public boolean scissorContains(int x, int y) { - return this.scissorStack.containsPoint(x, y); + return scissorStack.containsPoint(x, y); } private void setScissor(@Nullable ScreenRect rect) { - this.draw(); + draw(); if (rect != null) { Window window = SaturnClient.client.getWindow(); - int i = window.getFramebufferHeight(); - double d = window.getScaleFactor(); - double e = (double) rect.getLeft() * d; - double f = (double) i - (double) rect.getBottom() * d; - double g = (double) rect.width() * d; - double h = (double) rect.height() * d; - RenderSystem.enableScissor((int) e, (int) f, Math.max(0, (int) g), Math.max(0, (int) h)); + int framebufferHeight = window.getFramebufferHeight(); + double scaleFactor = window.getScaleFactor(); + RenderSystem.enableScissor( + (int) (rect.getLeft() * scaleFactor), + (int) (framebufferHeight - rect.getBottom() * scaleFactor), + Math.max(0, (int) (rect.width() * scaleFactor)), + Math.max(0, (int) (rect.height() * scaleFactor))); } else { RenderSystem.disableScissor(); } - - } - - @Override - public void draw() { - this.vertexConsumers.draw(); - } - - public void draw(Consumer drawer) { - drawer.accept(this.vertexConsumers); - this.vertexConsumers.draw(); } static class ScissorStack { @@ -372,132 +460,4 @@ public class RenderScopeImpl implements RenderScope { return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); } } - - @Override - public void drawItem(ItemStackRef item, int x, int y) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed, int z) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, (ItemStack) (Object) stack, x, y, seed, z); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y) { - this.drawItemWithoutEntity(stack, x, y, 0); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y, int seed) { - this.drawItem((LivingEntity) null, SaturnClient.client.world, stack, x, y, seed); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - this.drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ModelTransformationMode.GUI, - false, world, entity, seed); - this.matrices.push(); - this.matrices.translate((float) (x + 8), (float) (y + 8), - (float) (150 + (this.itemRenderState.hasDepth() ? z : 0))); - - try { - this.matrices.scale(16.0F, -16.0F, 16.0F); - boolean bl = !this.itemRenderState.isSideLit(); - if (bl) { - this.draw(); - DiffuseLighting.disableGuiDepthLighting(); - } - - this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); - this.draw(); - if (bl) { - DiffuseLighting.enableGuiDepthLighting(); - } - } catch (Throwable var11) { - CrashReport crashReport = CrashReport.create(var11, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> { - return String.valueOf(stack.getItem()); - }); - crashReportSection.add("Item Components", () -> { - return String.valueOf(stack.getComponents()); - }); - crashReportSection.add("Item Foil", () -> { - return String.valueOf(stack.hasGlint()); - }); - throw new CrashException(crashReport); - } - - this.matrices.pop(); - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - this.drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { - Sprite sprite = (Sprite) saturnSprite; - if (color == 0) - return; - if (width != 0 && height != 0) { - this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), - sprite.getMinV(), sprite.getMaxV(), color); - } - } - - public void fill(int x1, int y1, int x2, int y2, int color) { - this.fill(x1, y1, x2, y2, 0, color); - } - - public void fill(int x1, int y1, int x2, int y2, int z, int color) { - this.fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { - this.fill(layer, x1, y1, x2, y2, 0, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - int i; - if (x1 < x2) { - i = x1; - x1 = x2; - x2 = i; - } - - if (y1 < y2) { - i = y1; - y1 = y2; - y2 = i; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, (float) z).color(color); - } - - public void drawBorder(int x, int y, int width, int height, int color) { - this.fill(x, y, x + width, y + 1, color); - this.fill(x, y + height - 1, x + width, y + height, color); - this.fill(x, y + 1, x + 1, y + height - 1, color); - this.fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } } diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index dc04132..24f087b 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -82,7 +82,7 @@ public class RenderScopeImpl implements RenderScope { } @Override - public void drawRect(int x, int y, int width, int height, int color) { + public void drawRectangle(int x, int y, int width, int height, int color) { if (color == 0) return; color = getColor(color); @@ -154,7 +154,7 @@ public class RenderScopeImpl implements RenderScope { startX = radius - (int) dx; } - this.drawRect(startX, y, w - startX, 1, color); + this.drawRectangle(startX, y, w - startX, 1, color); } } @@ -405,10 +405,11 @@ public class RenderScopeImpl implements RenderScope { private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, int z) { if (!stack.isEmpty()) { - SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ItemDisplayContext.GUI, world, entity, seed); + SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ItemDisplayContext.GUI, world, + entity, seed); this.matrices.push(); this.matrices.translate((float) (x + 8), (float) (y + 8), - (float) (150 + z)); //always has depth + (float) (150 + z)); // always has depth try { this.matrices.scale(16.0F, -16.0F, 16.0F); diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 7937e81..68f3f93 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -102,7 +102,7 @@ public class RenderScopeImpl implements RenderScope { } @Override - public void drawRect(int x, int y, int width, int height, int color) { + public void drawRectangle(int x, int y, int width, int height, int color) { if (color == 0) return; color = getColor(color); @@ -166,7 +166,7 @@ public class RenderScopeImpl implements RenderScope { startX = radius - (int) dx; } - this.drawRect(startX, y, w - startX, 1, color); + this.drawRectangle(startX, y, w - startX, 1, color); } } @@ -300,7 +300,8 @@ public class RenderScopeImpl implements RenderScope { } this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(RenderPipelines.GUI, - TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, u2, + TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, + u2, v1, v2, color, this.scissorStack.peekLast())); } From bf280d945eaf028b43d7b67d4641359b1bd5781c Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 19:00:21 +0100 Subject: [PATCH 02/12] Improved #59 --- common | 2 +- .../impl/mixins/MatrixStackMixin.java | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/common b/common index c72af13..fc1500a 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c72af1300a3783ad2b45405243a74aad7debfade +Subproject commit fc1500abbdf911987ee3d98ee2015bec7cbc96eb diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java index b128808..1850b50 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java @@ -1,13 +1,21 @@ package org.saturnclient.impl.mixins; +import org.joml.Quaternionf; import org.saturnclient.common.ref.render.MatrixStackRef; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.RotationAxis; @Mixin(MatrixStack.class) public abstract class MatrixStackMixin implements MatrixStackRef { + @Shadow + public abstract void push(); + + @Shadow + public abstract void pop(); + @Shadow public abstract void translate(float x, float y, float z); @@ -15,10 +23,10 @@ public abstract class MatrixStackMixin implements MatrixStackRef { public abstract void scale(float x, float y, float z); @Shadow - public abstract void push(); + public abstract void multiply(Quaternionf quaternion); @Shadow - public abstract void pop(); + public abstract void multiply(Quaternionf quaternion, float originX, float originY, float originZ); @Override public void translate(float x, float y) { @@ -29,4 +37,14 @@ public abstract class MatrixStackMixin implements MatrixStackRef { public void scale(float x, float y) { scale(x, y, 1.0f); } -} \ No newline at end of file + + @Override + public void rotate(float angle, float originX, float originY, float originZ) { + multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle), originX, originY, originZ); + } + + @Override + public void rotate(float angle) { + multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle)); + } +} From d50d19b609070d0beae9a05ba3f197c898848b21 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 19:09:36 +0100 Subject: [PATCH 03/12] Refactored RenderScope and MatrixStack for 1.21.5 #59 --- .../features/mixins/render/RenderMixin.java | 4 +- .../impl/mixins/MatrixStackMixin.java | 48 +- .../impl/ui/EntityDrawerImpl.java | 36 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 650 +++++++++--------- 4 files changed, 354 insertions(+), 384 deletions(-) diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java index 063261a..f4efb30 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java @@ -65,8 +65,8 @@ public class RenderMixin { ModLayout dim = hud.getDimensions(); scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0f); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); + scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); + scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); if (dim.renderBackground) { scope.drawRoundedRectangle(0, 0, dim.width, dim.height, diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java index 2823f6a..4c4ae39 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java @@ -1,45 +1,49 @@ package org.saturnclient.impl.mixins; + import org.joml.Quaternionfc; import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.common.ref.render.QuaternionfRef; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Invoker; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.RotationAxis; @Mixin(MatrixStack.class) public abstract class MatrixStackMixin implements MatrixStackRef { - @Shadow - public abstract void translate(double x, double y, double z); - @Shadow - public abstract void translate(float x, float y, float z); - @Shadow - public abstract void scale(float x, float y, float z); - @Shadow - public abstract void multiply(Quaternionfc quaternion); - @Shadow - public abstract void multiply(Quaternionfc quaternion, float originX, float originY, float originZ); @Shadow public abstract void push(); + @Shadow public abstract void pop(); - @Invoker("peek") - public abstract MatrixStack.Entry peekM(); + @Shadow - public abstract boolean isEmpty(); + public abstract void translate(float x, float y, float z); + @Shadow - public abstract void loadIdentity(); + public abstract void scale(float x, float y, float z); + + @Shadow + public abstract void multiply(Quaternionfc quaternion); + + @Shadow + public abstract void multiply(Quaternionfc quaternion, float originX, float originY, float originZ); @Override - public void multiply(QuaternionfRef quaternion) { - this.multiply((Quaternionfc) quaternion); + public void translate(float x, float y) { + translate(x, y, 0); } + @Override - public void multiply(QuaternionfRef quaternion, float originX, float originY, float originZ) { - this.multiply((Quaternionfc) quaternion, originX, originY, originZ); + public void scale(float x, float y) { + scale(x, y, 1.0f); } + @Override - public Object peek() { - return this.peekM(); + public void rotate(float angle, float originX, float originY, float originZ) { + multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle), originX, originY, originZ); + } + + @Override + public void rotate(float angle) { + multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(angle)); } } \ No newline at end of file diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index beb41b6..7f0674b 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -3,7 +3,6 @@ package org.saturnclient.impl.ui; import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; -import org.saturnclient.common.ref.render.QuaternionfRef; import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; @@ -51,27 +50,28 @@ public class EntityDrawerImpl implements EntityDrawer { public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - renderScope.getMatrixStack().push(); - renderScope.getMatrixStack().translate((double) x, (double) y, 50.0); - renderScope.getMatrixStack().scale(size, size, -size); - renderScope.getMatrixStack().translate(vector3f.x, vector3f.y, vector3f.z); - renderScope.getMatrixStack().multiply((QuaternionfRef) quaternionf); - renderScope.draw(); - DiffuseLighting.disableGuiDepthLighting(); - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + if (renderScope instanceof RenderScopeImpl scopeImpl) { + scopeImpl.matrices.push(); + scopeImpl.matrices.translate((double) x, (double) y, 0); + scopeImpl.matrices.scale(size, size, -size); + scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); + scopeImpl.matrices.multiply(quaternionf); + scopeImpl.draw(); + DiffuseLighting.disableGuiDepthLighting(); + EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - entityRenderDispatcher.setRenderShadows(false); - if (renderScope instanceof RenderScopeImpl r) { - r.draw((vertexConsumers) -> { + entityRenderDispatcher.setRenderShadows(false); + scopeImpl.draw((vertexConsumers) -> { entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - r.matrices, vertexConsumers, - 15728880); + scopeImpl.matrices, vertexConsumers, 15728880); }); + + scopeImpl.draw(); + entityRenderDispatcher.setRenderShadows(true); + scopeImpl.getMatrixStack().pop(); + DiffuseLighting.enableGuiDepthLighting(); } - renderScope.draw(); - entityRenderDispatcher.setRenderShadows(true); - renderScope.getMatrixStack().pop(); - DiffuseLighting.enableGuiDepthLighting(); + } @Override diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 24f087b..4124776 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -35,8 +35,9 @@ import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; import net.minecraft.item.ItemDisplayContext; +import net.minecraft.item.ItemStack; + import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.crash.CrashException; @@ -46,12 +47,18 @@ import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; public class RenderScopeImpl implements RenderScope { + // ---------------------------- + // Fields + // ---------------------------- public MatrixStack matrices; public VertexConsumerProvider.Immediate vertexConsumers; private ScissorStack scissorStack = new ScissorStack(); private int opacity = 255 << 24; private final ItemRenderState itemRenderState; + // ---------------------------- + // Constructors + // ---------------------------- public RenderScopeImpl(DrawContext context) { this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); } @@ -63,11 +70,17 @@ public class RenderScopeImpl implements RenderScope { this.itemRenderState = new ItemRenderState(); } + // ---------------------------- + // Matrix & Transform + // ---------------------------- @Override public MatrixStackRef getMatrixStack() { return (MatrixStackRef) matrices; } + // ---------------------------- + // Color & Opacity + // ---------------------------- @Override public void setOpacity(float alpha) { this.opacity = (int) (alpha * 255) << 24; @@ -81,132 +94,12 @@ public class RenderScopeImpl implements RenderScope { return (mixedAlpha << 24) | (color & 0x00FFFFFF); } + // ---------------------------- + // Draw / Window Info + // ---------------------------- @Override - public void drawRectangle(int x, int y, int width, int height, int color) { - if (color == 0) - return; - color = getColor(color); - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - - int x1 = x; - int x2 = x + width; - int y1 = y; - int y2 = y + height; - - int i; - if (x1 < x2) { - i = x1; - x1 = x2; - x2 = i; - } - - if (y1 < y2) { - i = y1; - y1 = y2; - y2 = i; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0).color(color); - } - - @Override - public void drawText(String text, int x, int y, int font, int color) { - drawText(1.0f, text, x, y, font, color); - } - - @Override - public void drawText(float scale, String text, int x, int y, int font, int color) { - if (color == 0) - return; - if (font == 0) { - scale *= 2; - } - int i = 0; - for (String line : text.split("\n")) { - color = getColor(color); - matrices.push(); - matrices.translate(x, y + (i * Fonts.getHeight()), 0); - matrices.scale(scale, scale, 1.0f); - TextRenderer textRenderer = SaturnClient.client.textRenderer; - textRenderer.draw((Text) Fonts.setFont(line, font), 0, - font == 0 ? 1 : 7, color, false, - this.matrices.peek().getPositionMatrix(), - this.vertexConsumers, TextLayerType.NORMAL, 0, 15728880); - matrices.pop(); - i++; - } - } - - private void drawRoundedCorner(int width, int height, int radius, int color) { - int w = width * 20; - int h = height * 20; - - for (int y = 0; y < h; y++) { - int startX = 0; - - if (y < radius) { - double dy = radius - y - 0.5; - double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); - startX = radius - (int) dx; - } - - this.drawRectangle(startX, y, w - startX, 1, color); - } - } - - private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - // Top - this.matrices.push(); - - this.matrices.scale(0.05f, 0.05f, 1.0f); - - this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - - this.matrices.pop(); - - // Bottom - this.matrices.push(); - - this.matrices.translate(cornerWidth, cornerHeight * 2, 0); - - this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); - - this.matrices.translate(0, -cornerWidth, 0); - - this.matrices.scale(0.05f, 0.05f, 1.0f); - - this.drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - - this.matrices.pop(); - } - - @Override - public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { - if (color == 0) - return; - radius = Math.min(radius, Math.min(width, height)); - int cornerWidth = width / 2; - int cornerHeight = height / 2; - - this.matrices.push(); - - this.matrices.translate(x, y, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); - - this.matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); - - this.matrices.translate(0, 0, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.pop(); + public void draw() { + this.vertexConsumers.draw(); } @Override @@ -219,66 +112,221 @@ public class RenderScopeImpl implements RenderScope { return SaturnClient.client.getWindow().getScaledHeight(); } + public void draw(Consumer drawer) { + drawer.accept(this.vertexConsumers); + this.vertexConsumers.draw(); + } + + // ---------------------------- + // Shapes + // ---------------------------- @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); - } - - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); - } - - /* Minecraft sprites */ - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad(sprite, x, x + width, y, y + height, (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, - float v2, int color) { - - if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), - (IdentifierRef) (Object) sprite, - (x2 - x1) * 2, (y2 - y1) * 2); - } - + public void drawRectangle(int x, int y, int width, int height, int color) { if (color == 0) return; + color = getColor(color); + + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + + int x1 = x; + int x2 = x + width; + int y1 = y; + int y2 = y + height; + + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(RenderLayer.getGui()); + vertexConsumer.vertex(matrix4f, x1, y1, 0).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).color(color); + } + + @Override + public void fill(int x1, int y1, int x2, int y2, int color) { + fill(x1, y1, x2, y2, 0, color); + } + + public void fill(int x1, int y1, int x2, int y2, int z, int color) { + fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { + fill(layer, x1, y1, x2, y2, 0, color); + } + + public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { + Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); + if (x1 < x2) { + int tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 < y2) { + int tmp = y1; + y1 = y2; + y2 = tmp; + } + + VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); + vertexConsumer.vertex(matrix4f, x1, y1, z).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, z).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, z).color(color); + } + + @Override + public void drawBorder(int x, int y, int width, int height, int color) { + fill(x, y, x + width, y + 1, color); + fill(x, y + height - 1, x + width, y + height, color); + fill(x, y + 1, x + 1, y + height - 1, color); + fill(x + width - 1, y + 1, x + width, y + height - 1, color); + } + + @Override + public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { + if (color == 0) + return; + + radius = Math.min(radius, Math.min(width, height)); + int cornerWidth = width / 2; + int cornerHeight = height / 2; + + matrices.push(); + matrices.translate(x, y, 0); + + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); + matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + matrices.pop(); + } + + // Rounded rectangle helpers + private void drawRoundedCorner(int width, int height, int radius, int color) { + int w = width * 20; + int h = height * 20; + + for (int y = 0; y < h; y++) { + int startX = 0; + if (y < radius) { + double dy = radius - y - 0.5; + double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); + startX = radius - (int) dx; + } + drawRectangle(startX, y, w - startX, 1, color); + } + } + + private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { + // Top + matrices.push(); + matrices.scale(0.05f, 0.05f, 1.0f); + drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); + matrices.pop(); + + // Bottom + matrices.push(); + matrices.translate(cornerWidth, cornerHeight * 2, 0); + matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); + matrices.translate(0, -cornerWidth, 0); + matrices.scale(0.05f, 0.05f, 1.0f); + drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); + matrices.pop(); + } + + // ---------------------------- + // Text + // ---------------------------- + @Override + public void drawText(String text, int x, int y, int font, int color) { + drawText(1.0f, text, x, y, font, color); + } + + @Override + public void drawText(float scale, String text, int x, int y, int font, int color) { + if (color == 0) + return; + if (font == 0) + scale *= 2; + + int i = 0; + for (String line : text.split("\n")) { + color = getColor(color); + matrices.push(); + matrices.translate(x, y + i * Fonts.getHeight(), 0); + matrices.scale(scale, scale, 1.0f); + TextRenderer textRenderer = SaturnClient.client.textRenderer; + textRenderer.draw((Text) Fonts.setFont(line, font), 0, font == 0 ? 1 : 7, color, false, + matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, 15728880); + matrices.pop(); + i++; + } + } + + // ---------------------------- + // Textures & Sprites + // ---------------------------- + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight) { + drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, + int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { + drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, + (u + 0.0f) / textureWidth, (u + regionWidth) / textureWidth, + (v + 0.0f) / textureHeight, (v + regionHeight) / textureHeight, color); + } + + @Override + public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { + drawSpriteStretched(sprite, x, y, width, height, -1); + } + + @Override + public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { + Sprite sprite = (Sprite) saturnSprite; + if (color == 0) + return; + if (width != 0 && height != 0) { + drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, + sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV(), color); + } + } + + private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, + float u1, float u2, float v1, float v2, int color) { + if (sprite.toString().endsWith(".svg")) { + sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), + (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); + } + if (color == 0) + return; + x1 *= 4; x2 *= 4; y1 *= 4; @@ -287,58 +335,104 @@ public class RenderScopeImpl implements RenderScope { matrices.push(); matrices.scale(0.25f, 0.25f, 1.0f); - RenderLayer renderLayer = (RenderLayer) RenderLayer.getGuiTextured(sprite); - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(renderLayer); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, 0.0F).texture(u1, v1).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, 0.0F).texture(u1, v2).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, 0.0F).texture(u2, v2).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, 0.0F).texture(u2, v1).color(color); + RenderLayer renderLayer = RenderLayer.getGuiTextured(sprite); + Matrix4f matrix4f = matrices.peek().getPositionMatrix(); + VertexConsumer vertexConsumer = vertexConsumers.getBuffer(renderLayer); + vertexConsumer.vertex(matrix4f, x1, y1, 0).texture(u1, v1).color(color); + vertexConsumer.vertex(matrix4f, x1, y2, 0).texture(u1, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y2, 0).texture(u2, v2).color(color); + vertexConsumer.vertex(matrix4f, x2, y1, 0).texture(u2, v1).color(color); matrices.pop(); } + // ---------------------------- + // Items + // ---------------------------- + @Override + public void drawItem(ItemStackRef item, int x, int y) { + drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, + int seed) { + drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); + } + + private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, + int z) { + if (stack.isEmpty()) + return; + + SaturnClient.client.getItemModelManager().update(itemRenderState, stack, ItemDisplayContext.GUI, world, entity, + seed); + + if (!stack.isEmpty()) { + SaturnClient.client.getItemModelManager().clearAndUpdate(this.itemRenderState, stack, + ItemDisplayContext.GUI, world, + entity, seed); + this.matrices.push(); + this.matrices.translate((float) (x + 8), (float) (y + 8), (float) (150 + z)); + + try { + this.matrices.scale(16.0F, -16.0F, 16.0F); + boolean bl = !this.itemRenderState.isSideLit(); + if (bl) { + this.draw(); + DiffuseLighting.disableGuiDepthLighting(); + } + + this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); + this.draw(); + if (bl) { + DiffuseLighting.enableGuiDepthLighting(); + } + } catch (Throwable throwable) { + CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); + CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); + crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); + crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); + crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); + throw new CrashException(crashReport); + } + + this.matrices.pop(); + } + } + + // ---------------------------- + // Scissor / Clipping + // ---------------------------- @Override public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)) - .transform(this.matrices.peek().getPositionMatrix()); - this.setScissor(this.scissorStack.push(screenRect)); + ScreenRect screenRect = new ScreenRect(x1, y1, x2 - x1, y2 - y1) + .transform(matrices.peek().getPositionMatrix()); + setScissor(scissorStack.push(screenRect)); } @Override public void disableScissor() { - this.setScissor(this.scissorStack.pop()); + setScissor(scissorStack.pop()); } @Override public boolean scissorContains(int x, int y) { - return this.scissorStack.containsPoint(x, y); + return scissorStack.containsPoint(x, y); } private void setScissor(@Nullable ScreenRect rect) { - this.draw(); + draw(); if (rect != null) { Window window = SaturnClient.client.getWindow(); - int i = window.getFramebufferHeight(); - double d = window.getScaleFactor(); - double e = (double) rect.getLeft() * d; - double f = (double) i - (double) rect.getBottom() * d; - double g = (double) rect.width() * d; - double h = (double) rect.height() * d; - RenderSystem.enableScissor((int) e, (int) f, Math.max(0, (int) g), Math.max(0, (int) h)); + int framebufferHeight = window.getFramebufferHeight(); + double scaleFactor = window.getScaleFactor(); + RenderSystem.enableScissor( + (int) (rect.getLeft() * scaleFactor), + (int) (framebufferHeight - rect.getBottom() * scaleFactor), + Math.max(0, (int) (rect.width() * scaleFactor)), + Math.max(0, (int) (rect.height() * scaleFactor))); } else { RenderSystem.disableScissor(); } - - } - - @Override - public void draw() { - this.vertexConsumers.draw(); - } - - public void draw(Consumer drawer) { - drawer.accept(this.vertexConsumers); - this.vertexConsumers.draw(); } static class ScissorStack { @@ -371,132 +465,4 @@ public class RenderScopeImpl implements RenderScope { return this.stack.isEmpty() ? true : this.stack.peek().contains(p_329411_, p_333404_); } } - - @Override - public void drawItem(ItemStackRef item, int x, int y) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed, int z) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, (ItemStack) (Object) stack, x, y, seed, z); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y) { - this.drawItemWithoutEntity(stack, x, y, 0); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y, int seed) { - this.drawItem((LivingEntity) null, SaturnClient.client.world, stack, x, y, seed); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, - int seed) { - this.drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); - } - - private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, - int z) { - if (!stack.isEmpty()) { - SaturnClient.client.getItemModelManager().update(this.itemRenderState, stack, ItemDisplayContext.GUI, world, - entity, seed); - this.matrices.push(); - this.matrices.translate((float) (x + 8), (float) (y + 8), - (float) (150 + z)); // always has depth - - try { - this.matrices.scale(16.0F, -16.0F, 16.0F); - boolean bl = !this.itemRenderState.isSideLit(); - if (bl) { - this.draw(); - DiffuseLighting.disableGuiDepthLighting(); - } - - this.itemRenderState.render(this.matrices, this.vertexConsumers, 15728880, OverlayTexture.DEFAULT_UV); - this.draw(); - if (bl) { - DiffuseLighting.enableGuiDepthLighting(); - } - } catch (Throwable var11) { - CrashReport crashReport = CrashReport.create(var11, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> { - return String.valueOf(stack.getItem()); - }); - crashReportSection.add("Item Components", () -> { - return String.valueOf(stack.getComponents()); - }); - crashReportSection.add("Item Foil", () -> { - return String.valueOf(stack.hasGlint()); - }); - throw new CrashException(crashReport); - } - - this.matrices.pop(); - } - } - - @Override - public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - this.drawSpriteStretched(sprite, x, y, width, height, -1); - } - - @Override - public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { - Sprite sprite = (Sprite) saturnSprite; - if (color == 0) - return; - if (width != 0 && height != 0) { - this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), - sprite.getMinV(), sprite.getMaxV(), color); - } - } - - public void fill(int x1, int y1, int x2, int y2, int color) { - this.fill(x1, y1, x2, y2, 0, color); - } - - public void fill(int x1, int y1, int x2, int y2, int z, int color) { - this.fill(RenderLayer.getGui(), x1, y1, x2, y2, z, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int color) { - this.fill(layer, x1, y1, x2, y2, 0, color); - } - - public void fill(RenderLayer layer, int x1, int y1, int x2, int y2, int z, int color) { - Matrix4f matrix4f = this.matrices.peek().getPositionMatrix(); - int i; - if (x1 < x2) { - i = x1; - x1 = x2; - x2 = i; - } - - if (y1 < y2) { - i = y1; - y1 = y2; - y2 = i; - } - - VertexConsumer vertexConsumer = this.vertexConsumers.getBuffer(layer); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y1, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x1, (float) y2, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y2, (float) z).color(color); - vertexConsumer.vertex(matrix4f, (float) x2, (float) y1, (float) z).color(color); - } - - public void drawBorder(int x, int y, int width, int height, int color) { - this.fill(x, y, x + width, y + 1, color); - this.fill(x, y + height - 1, x + width, y + height, color); - this.fill(x, y + 1, x + 1, y + height - 1, color); - this.fill(x + width - 1, y + 1, x + width, y + height - 1, color); - } } From 9424e2ec716c9a0e1507a80900b634b989f57894 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 19:24:02 +0100 Subject: [PATCH 04/12] Refactored RenderScope 1.21.6 #59 --- .../features/mixins/render/RenderMixin.java | 4 +- .../impl/mixins/MatrixStackMixin.java | 45 --- .../impl/ref/Matrix3x2fStackRef.java | 40 +-- .../impl/ui/EntityDrawerImpl.java | 40 +-- .../saturnclient/impl/ui/RenderScopeImpl.java | 334 +++++++----------- .../src/main/resources/impl.mixins.json | 1 - 6 files changed, 163 insertions(+), 301 deletions(-) delete mode 100644 versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java index 0c109d0..f9d59c8 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java @@ -62,8 +62,8 @@ public class RenderMixin { ModLayout dim = hud.getDimensions(); scope.getMatrixStack().push(); - scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0f); - scope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); + scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value); + scope.getMatrixStack().scale(dim.scale.value, dim.scale.value); if (dim.renderBackground) { scope.drawRoundedRectangle(0, 0, dim.width, dim.height, diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java deleted file mode 100644 index 2823f6a..0000000 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/mixins/MatrixStackMixin.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.saturnclient.impl.mixins; -import org.joml.Quaternionfc; -import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.common.ref.render.QuaternionfRef; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.gen.Invoker; -import net.minecraft.client.util.math.MatrixStack; - -@Mixin(MatrixStack.class) -public abstract class MatrixStackMixin implements MatrixStackRef { - @Shadow - public abstract void translate(double x, double y, double z); - @Shadow - public abstract void translate(float x, float y, float z); - @Shadow - public abstract void scale(float x, float y, float z); - @Shadow - public abstract void multiply(Quaternionfc quaternion); - @Shadow - public abstract void multiply(Quaternionfc quaternion, float originX, float originY, float originZ); - @Shadow - public abstract void push(); - @Shadow - public abstract void pop(); - @Invoker("peek") - public abstract MatrixStack.Entry peekM(); - @Shadow - public abstract boolean isEmpty(); - @Shadow - public abstract void loadIdentity(); - - @Override - public void multiply(QuaternionfRef quaternion) { - this.multiply((Quaternionfc) quaternion); - } - @Override - public void multiply(QuaternionfRef quaternion, float originX, float originY, float originZ) { - this.multiply((Quaternionfc) quaternion, originX, originY, originZ); - } - @Override - public Object peek() { - return this.peekM(); - } -} \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java index b6ae6c9..4091120 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java @@ -5,7 +5,6 @@ import java.util.Deque; import org.joml.Matrix3x2fStack; import org.saturnclient.common.ref.render.MatrixStackRef; -import org.saturnclient.common.ref.render.QuaternionfRef; public class Matrix3x2fStackRef implements MatrixStackRef { public final Matrix3x2fStack stack; @@ -33,11 +32,11 @@ public class Matrix3x2fStackRef implements MatrixStackRef { if (t.scaleX != 1 || t.scaleY != 1) stack.scale(1f / t.scaleX, 1f / t.scaleY); stack.translate(-t.translateX, -t.translateY); - // rotation inversion can be added here if needed + stack.rotate(-t.rotation); } @Override - public void scale(float x, float y, float z) { + public void scale(float x, float y) { stack.scale(x, y); if (!customStack.isEmpty()) { Transform t = customStack.peek(); @@ -47,7 +46,7 @@ public class Matrix3x2fStackRef implements MatrixStackRef { } @Override - public void translate(float x, float y, float z) { + public void translate(float x, float y) { stack.translate(x, y); if (!customStack.isEmpty()) { Transform t = customStack.peek(); @@ -57,38 +56,21 @@ public class Matrix3x2fStackRef implements MatrixStackRef { } @Override - public void translate(double x, double y, double z) { - translate((float) x, (float) y, (float) z); + public void rotate(float angle) { + stack.rotate(angle); + if (!customStack.isEmpty()) { + Transform t = customStack.peek(); + t.rotation += angle; + } } @Override - public void multiply(QuaternionfRef quaternion) { - // Not implemented yet - } - - @Override - public void multiply(QuaternionfRef quaternion, float originX, float originY, float originZ) { - // Not implemented yet - } - - @Override - public void loadIdentity() { - customStack.clear(); - } - - @Override - public Object peek() { - return null; - } - - @Override - public boolean isEmpty() { - return customStack.isEmpty(); + public void rotate(float angle, float originX, float originY, float originZ) { } private static class Transform { float scaleX = 1f, scaleY = 1f; float translateX = 0f, translateY = 0f; - // rotation can be added if needed + float rotation = 0f; } } \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index 8fe4914..e1320c4 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -51,27 +51,27 @@ public class EntityDrawerImpl implements EntityDrawer { public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - renderScope.getMatrixStack().push(); - renderScope.getMatrixStack().translate((double) x, (double) y, 50.0); - renderScope.getMatrixStack().scale(size, size, -size); - renderScope.getMatrixStack().translate(vector3f.x, vector3f.y, vector3f.z); - renderScope.getMatrixStack().multiply((QuaternionfRef) quaternionf); - renderScope.draw(); - // DiffuseLighting.disableGuiDepthLighting(); - EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + // if (renderScope instanceof RenderScopeImpl scopeImpl) { + // scopeImpl.matrices.push(); + // scopeImpl.matrices.translate((double) x, (double) y, 0); + // scopeImpl.matrices.scale(size, size, -size); + // scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); + // scopeImpl.matrices.multiply(quaternionf); + // scopeImpl.draw(); + // DiffuseLighting.disableGuiDepthLighting(); + // EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - entityRenderDispatcher.setRenderShadows(false); - if (renderScope instanceof RenderScopeImpl r) { - // r.draw((vertexConsumers) -> { - // entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - // r.matrices, vertexConsumers, - // 15728880); - // }); - } - renderScope.draw(); - entityRenderDispatcher.setRenderShadows(true); - renderScope.getMatrixStack().pop(); - // DiffuseLighting.enableGuiDepthLighting(); + // entityRenderDispatcher.setRenderShadows(false); + // scopeImpl.draw((vertexConsumers) -> { + // entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, + // scopeImpl.matrices, vertexConsumers, 15728880); + // }); + + // scopeImpl.draw(); + // entityRenderDispatcher.setRenderShadows(true); + // scopeImpl.getMatrixStack().pop(); + // DiffuseLighting.enableGuiDepthLighting(); + // } } @Override diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 68f3f93..c0278d0 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -3,15 +3,11 @@ package org.saturnclient.impl.ui; import java.util.ArrayDeque; import java.util.Deque; import java.util.Objects; -import java.util.function.Consumer; import org.jetbrains.annotations.Nullable; import org.joml.Matrix3x2f; import org.joml.Matrix3x2fStack; -import org.joml.Matrix4f; -import com.mojang.blaze3d.pipeline.RenderPipeline; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.textures.GpuTextureView; import org.saturnclient.common.provider.Providers; @@ -35,12 +31,11 @@ import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; import net.minecraft.client.gui.render.state.TextGuiElementRenderState; import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; import net.minecraft.client.render.item.ItemRenderState; -import net.minecraft.client.texture.GuiAtlasManager; import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.TextureSetup; import net.minecraft.entity.LivingEntity; -import net.minecraft.item.ItemStack; import net.minecraft.item.ItemDisplayContext; +import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.crash.CrashException; @@ -49,13 +44,12 @@ import net.minecraft.util.crash.CrashReportSection; import net.minecraft.world.World; public class RenderScopeImpl implements RenderScope { - private final Matrix3x2fStackRef matrices; - private final GuiAtlasManager guiAtlasManager; + + public final Matrix3x2fStackRef matrices; public final GuiRenderState state; private ScissorStack scissorStack; - private int opacity = 255 << 24; - private final ItemRenderState itemRenderState; + private int opacity = 0xFF << 24; public RenderScopeImpl(DrawContext context) { this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); @@ -64,9 +58,7 @@ public class RenderScopeImpl implements RenderScope { public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { this.state = state; this.matrices = new Matrix3x2fStackRef(matrices); - this.guiAtlasManager = SaturnClient.client.getGuiAtlasManager(); this.scissorStack = new ScissorStack(); - this.itemRenderState = new ItemRenderState(); } @Override @@ -76,7 +68,7 @@ public class RenderScopeImpl implements RenderScope { @Override public void setOpacity(float alpha) { - this.opacity = (int) (alpha * 255) << 24; + this.opacity = ((int) (alpha * 255)) << 24; } @Override @@ -90,15 +82,12 @@ public class RenderScopeImpl implements RenderScope { @Override public void fill(int x1, int y1, int x2, int y2, int color) { this.state.addSimpleElement( - new ColoredQuadGuiElementRenderState(RenderPipelines.GUI, TextureSetup.empty(), + new ColoredQuadGuiElementRenderState( + RenderPipelines.GUI, + TextureSetup.empty(), new Matrix3x2f(this.matrices.stack), - x1, y1, x2, - y2, color, color, this.scissorStack.peekLast())); - } - - @Override - public void fill(int x1, int y1, int x2, int y2, int z, int color) { - this.fill(x1, y1, x2, y2, color); + x1, y1, x2, y2, color, color, + this.scissorStack.peekLast())); } @Override @@ -106,22 +95,21 @@ public class RenderScopeImpl implements RenderScope { if (color == 0) return; color = getColor(color); + int x1 = x; int x2 = x + width; int y1 = y; int y2 = y + height; - int i; - if (x1 < x2) { - i = x1; + if (x2 < x1) { + int tmp = x1; x1 = x2; - x2 = i; + x2 = tmp; } - - if (y1 < y2) { - i = y1; + if (y2 < y1) { + int tmp = y1; y1 = y2; - y2 = i; + y2 = tmp; } this.fill(x1, y1, x2, y2, color); @@ -136,64 +124,56 @@ public class RenderScopeImpl implements RenderScope { public void drawText(float scale, String text, int x, int y, int font, int color) { if (color == 0) return; - if (font == 0) { + if (font == 0) scale *= 2; - } - int i = 0; + + int lineIndex = 0; for (String line : text.split("\n")) { - color = getColor(color); - this.state.addText(new TextGuiElementRenderState(SaturnClient.client.textRenderer, - ((Text) Fonts.setFont(line, font)).asOrderedText(), new Matrix3x2f(this.matrices.stack), x, y, - color, 0, false, this.scissorStack.peekLast())); + int finalColor = getColor(color); + this.state.addText( + new TextGuiElementRenderState( + SaturnClient.client.textRenderer, + ((Text) Fonts.setFont(line, font)).asOrderedText(), + new Matrix3x2f(this.matrices.stack), + x, y, + finalColor, 0, false, this.scissorStack.peekLast())); matrices.push(); - matrices.translate(x, y + (i * Fonts.getHeight()), 0); - matrices.scale(scale, scale, 0); - i++; + matrices.translate(x, y + (lineIndex * Fonts.getHeight())); + matrices.scale(scale, scale); + lineIndex++; } } + // Rounded rectangle helpers private void drawRoundedCorner(int width, int height, int radius, int color) { int w = width * 20; int h = height * 20; for (int y = 0; y < h; y++) { int startX = 0; - if (y < radius) { double dy = radius - y - 0.5; double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); startX = radius - (int) dx; } - - this.drawRectangle(startX, y, w - startX, 1, color); + drawRectangle(startX, y, w - startX, 1, color); } } private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - // Top - this.matrices.push(); + matrices.push(); + matrices.scale(0.05f, 0.05f); + drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); + matrices.pop(); - this.matrices.scale(0.05f, 0.05f, 0); - - this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - - this.matrices.pop(); - - // Bottom - this.matrices.push(); - - this.matrices.translate(cornerWidth, cornerHeight * 2, 0); - - this.matrices.stack.rotate((float) Math.toRadians(90)); - - this.matrices.translate(0, -cornerWidth, 0); - - this.matrices.scale(0.05f, 0.05f, 0); - - this.drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - - this.matrices.pop(); + matrices.push(); + matrices.translate(cornerWidth, cornerHeight * 2); + matrices.stack.rotate((float) Math.toRadians(90)); + matrices.translate(0, -cornerWidth); + matrices.scale(0.05f, 0.05f); + drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); + matrices.pop(); } @Override @@ -201,24 +181,18 @@ public class RenderScopeImpl implements RenderScope { if (color == 0) return; radius = Math.min(radius, Math.min(width, height)); + int cornerWidth = width / 2; int cornerHeight = height / 2; - this.matrices.push(); + matrices.push(); + matrices.translate(x, y); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); - this.matrices.translate(x, y, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); - - this.matrices.stack.rotate((float) Math.toRadians(90)); - - this.matrices.translate(0, 0, 0); - - this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - this.matrices.pop(); + matrices.translate(cornerWidth * 2, cornerHeight * 2); + matrices.stack.rotate((float) Math.toRadians(90)); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + matrices.pop(); } @Override @@ -231,212 +205,164 @@ public class RenderScopeImpl implements RenderScope { return SaturnClient.client.getWindow().getScaledHeight(); } - @Override - public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - + // Texture rendering @Override public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); + drawTexture(sprite, x, y, u, v, width, height, -1); + } + + @Override + public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, int color) { + drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); } @Override public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); + int regionWidth, int regionHeight, int textureWidth, int textureHeight) { + drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1); } @Override public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, - int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, - (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); + int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) { + drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, + (u + 0f) / textureWidth, + (u + regionWidth) / textureWidth, + (v + 0f) / textureHeight, + (v + regionHeight) / textureHeight, + color); } - /* Minecraft sprites */ - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int color) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height, color); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height) { - this.drawTexture(sprite, x, y, u, v, width, height, width, height, width, height); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWith, - int regionHeight, int textureWidth, int textureHeight) { - this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1); - } - - public void drawTexture(Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, - int regionHeight, int textureWidth, int textureHeight, int color) { - this.drawTexturedQuad(sprite, x, x + width, y, y + height, (u + 0.0F) / (float) textureWidth, - (u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, - (v + (float) regionHeight) / (float) textureHeight, color); - } - - private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, - float v2, int color) { - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager().getTexture(sprite).getGlTextureView(); - + private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, + float u1, float u2, float v1, float v2, int color) { if (color == 0) return; - - x1 *= 4; - x2 *= 4; - y1 *= 4; - y2 *= 4; color = getColor(color); - if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), + GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() + .getTexture(sprite).getGlTextureView(); + + if (sprite.getPath().endsWith(".svg")) { + sprite = (Identifier) (Object) SvgTexture.getSvg( + Providers.saturn.getClient(), (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); } - this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(RenderPipelines.GUI, - TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, - u2, - v1, v2, - color, this.scissorStack.peekLast())); + this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( + RenderPipelines.GUI, + TextureSetup.withoutGlTexture(gpuTextureView), + new Matrix3x2f(this.matrices.stack), + x1, y1, x2, y2, u1, u2, v1, v2, color, + this.scissorStack.peekLast())); } + // Scissor management @Override public void enableScissor(int x1, int y1, int x2, int y2) { - ScreenRect screenRect = (new ScreenRect(x1, y1, x2 - x1, y2 - y1)).transform(this.matrices.stack); - this.scissorStack.push(screenRect); + ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack); + scissorStack.push(rect); } @Override public void disableScissor() { - this.scissorStack.pop(); + scissorStack.pop(); } @Override public boolean scissorContains(int x, int y) { - return this.scissorStack.contains(x, y); + return scissorStack.contains(x, y); } public static class ScissorStack { - private final Deque stack = new ArrayDeque(); - - ScissorStack() { - } + private final Deque stack = new ArrayDeque<>(); public ScreenRect push(ScreenRect rect) { - ScreenRect screenRect = (ScreenRect) this.stack.peekLast(); - if (screenRect != null) { - ScreenRect screenRect2 = (ScreenRect) Objects.requireNonNullElse(rect.intersection(screenRect), - ScreenRect.empty()); - this.stack.addLast(screenRect2); - return screenRect2; + ScreenRect last = stack.peekLast(); + if (last != null) { + ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty()); + stack.addLast(intersection); + return intersection; } else { - this.stack.addLast(rect); + stack.addLast(rect); return rect; } } @Nullable public ScreenRect pop() { - if (this.stack.isEmpty()) { + if (stack.isEmpty()) throw new IllegalStateException("Scissor stack underflow"); - } else { - this.stack.removeLast(); - return (ScreenRect) this.stack.peekLast(); - } + stack.removeLast(); + return stack.peekLast(); } @Nullable public ScreenRect peekLast() { - return (ScreenRect) this.stack.peekLast(); + return stack.peekLast(); } public boolean contains(int x, int y) { - return this.stack.isEmpty() ? true : ((ScreenRect) this.stack.peek()).contains(x, y); + return stack.isEmpty() || stack.peekLast().contains(x, y); } } + // Item rendering @Override - public void drawItem(ItemStackRef item, int x, int y) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, stack, x, y, seed); - } - - @Override - public void drawItem(ItemStackRef stack, int x, int y, int seed, int z) { - this.drawItem(SaturnClient.client.player, SaturnClient.client.world, (ItemStack) (Object) stack, x, y, seed, z); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y) { - this.drawItemWithoutEntity(stack, x, y, 0); - } - - @Override - public void drawItemWithoutEntity(ItemStackRef stack, int x, int y, int seed) { - this.drawItem((LivingEntity) null, SaturnClient.client.world, stack, x, y, seed); + public void drawItem(ItemStackRef stack, int x, int y) { + drawItem(null, SaturnClient.client.world, stack, x, y, 0); } private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y, int seed) { - this.drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); + drawItem(entity, world, (ItemStack) (Object) stack, x, y, seed, 0); } private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed, int z) { if (!stack.isEmpty()) { - ItemRenderState itemRenderState = new ItemRenderState(); - SaturnClient.client.getItemModelManager().clearAndUpdate(itemRenderState, stack, ItemDisplayContext.GUI, - world, + ItemRenderState state = new ItemRenderState(); + SaturnClient.client.getItemModelManager().clearAndUpdate(state, stack, ItemDisplayContext.GUI, world, entity, seed); try { this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), - new Matrix3x2f(this.matrices.stack), itemRenderState, x, y, this.scissorStack.peekLast())); - } catch (Throwable throwable) { - CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); - CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); - crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); - crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); - crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); - throw new CrashException(crashReport); + new Matrix3x2f(this.matrices.stack), state, x, y, scissorStack.peekLast())); + } catch (Throwable t) { + CrashReport report = CrashReport.create(t, "Rendering item"); + CrashReportSection section = report.addElement("Item being rendered"); + section.add("Item Type", () -> String.valueOf(stack.getItem())); + section.add("Item Components", () -> String.valueOf(stack.getComponents())); + section.add("Item Foil", () -> String.valueOf(stack.hasGlint())); + throw new CrashException(report); } } } - @Override - public void draw() { - } - @Override public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { - this.drawSpriteStretched(sprite, x, y, width, height, -1); + drawSpriteStretched(sprite, x, y, width, height, -1); } @Override - public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { - Sprite sprite = (Sprite) saturnSprite; - if (color == 0) + public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) { + Sprite mcSprite = (Sprite) sprite; + if (color == 0 || width == 0 || height == 0) return; - if (width != 0 && height != 0) { - this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), - sprite.getMinV(), sprite.getMaxV(), color); - } + + drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height, + mcSprite.getMinU(), mcSprite.getMaxU(), mcSprite.getMinV(), mcSprite.getMaxV(), color); + } + + @Override + public void draw() { + // No-op for now } public void drawBorder(int x, int y, int width, int height, int color) { - this.fill(x, y, x + width, y + 1, color); - this.fill(x, y + height - 1, x + width, y + height, color); - this.fill(x, y + 1, x + 1, y + height - 1, color); - this.fill(x + width - 1, y + 1, x + width, y + height - 1, color); + fill(x, y, x + width, y + 1, color); + fill(x, y + height - 1, x + width, y + height, color); + fill(x, y + 1, x + 1, y + height - 1, color); + fill(x + width - 1, y + 1, x + width, y + height - 1, color); } -} +} \ No newline at end of file diff --git a/versions/1.21.6/src/main/resources/impl.mixins.json b/versions/1.21.6/src/main/resources/impl.mixins.json index 094792b..ef9d58f 100644 --- a/versions/1.21.6/src/main/resources/impl.mixins.json +++ b/versions/1.21.6/src/main/resources/impl.mixins.json @@ -6,7 +6,6 @@ "client": [ "IdentifierMixin", "ItemStackMixin", - "MatrixStackMixin", "MinecraftClientMixin", "QuaternionfMixin", "WindowMixin", From 3a71cd5b0259da2c3a33bc7eef0092fbd684b175 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 21:04:53 +0100 Subject: [PATCH 05/12] Fixed MatrixStack leak on RenderScope 1.21.6 #59 --- .../impl/ref/Matrix3x2fStackRef.java | 42 +++---------------- .../saturnclient/impl/ui/RenderScopeImpl.java | 34 ++++++++------- 2 files changed, 25 insertions(+), 51 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java index 4091120..1e08755 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java @@ -1,76 +1,44 @@ package org.saturnclient.impl.ref; -import java.util.ArrayDeque; -import java.util.Deque; - import org.joml.Matrix3x2fStack; import org.saturnclient.common.ref.render.MatrixStackRef; public class Matrix3x2fStackRef implements MatrixStackRef { public final Matrix3x2fStack stack; - // Our custom stack stores the reverse transforms - private final Deque customStack = new ArrayDeque<>(); - public Matrix3x2fStackRef(Matrix3x2fStack stack) { this.stack = stack; } @Override public void push() { - // Push a new empty Transform - customStack.push(new Transform()); + stack.pushMatrix(); } @Override public void pop() { - if (customStack.isEmpty()) - return; - - // Apply inverse transforms in reverse order - Transform t = customStack.pop(); - if (t.scaleX != 1 || t.scaleY != 1) - stack.scale(1f / t.scaleX, 1f / t.scaleY); - stack.translate(-t.translateX, -t.translateY); - stack.rotate(-t.rotation); + stack.popMatrix(); } @Override public void scale(float x, float y) { stack.scale(x, y); - if (!customStack.isEmpty()) { - Transform t = customStack.peek(); - t.scaleX *= x; - t.scaleY *= y; - } } @Override public void translate(float x, float y) { stack.translate(x, y); - if (!customStack.isEmpty()) { - Transform t = customStack.peek(); - t.translateX += x; - t.translateY += y; - } } @Override public void rotate(float angle) { stack.rotate(angle); - if (!customStack.isEmpty()) { - Transform t = customStack.peek(); - t.rotation += angle; - } } @Override public void rotate(float angle, float originX, float originY, float originZ) { - } - - private static class Transform { - float scaleX = 1f, scaleY = 1f; - float translateX = 0f, translateY = 0f; - float rotation = 0f; + translate(originX, originY); + rotate(angle); + translate(-originX, -originY); } } \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index c0278d0..6a34571 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -56,8 +56,8 @@ public class RenderScopeImpl implements RenderScope { } public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { - this.state = state; this.matrices = new Matrix3x2fStackRef(matrices); + this.state = state; this.scissorStack = new ScissorStack(); } @@ -130,17 +130,21 @@ public class RenderScopeImpl implements RenderScope { int lineIndex = 0; for (String line : text.split("\n")) { int finalColor = getColor(color); + + matrices.push(); + matrices.translate(x, y + (lineIndex * Fonts.getHeight())); + matrices.scale(scale, scale); + this.state.addText( new TextGuiElementRenderState( SaturnClient.client.textRenderer, ((Text) Fonts.setFont(line, font)).asOrderedText(), new Matrix3x2f(this.matrices.stack), - x, y, + 0, 0, // IMPORTANT finalColor, 0, false, this.scissorStack.peekLast())); - matrices.push(); - matrices.translate(x, y + (lineIndex * Fonts.getHeight())); - matrices.scale(scale, scale); + matrices.pop(); + lineIndex++; } } @@ -182,17 +186,19 @@ public class RenderScopeImpl implements RenderScope { return; radius = Math.min(radius, Math.min(width, height)); - int cornerWidth = width / 2; - int cornerHeight = height / 2; + fill(x, y, x + width, y + height, color); - matrices.push(); - matrices.translate(x, y); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); + // int cornerWidth = width / 2; + // int cornerHeight = height / 2; - matrices.translate(cornerWidth * 2, cornerHeight * 2); - matrices.stack.rotate((float) Math.toRadians(90)); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - matrices.pop(); + // matrices.push(); + // matrices.translate(x, y); + // drawRoundedSide(cornerWidth, cornerHeight, radius, color); + + // matrices.translate(cornerWidth * 2, cornerHeight * 2); + // matrices.stack.rotate((float) Math.toRadians(90)); + // drawRoundedSide(cornerWidth, cornerHeight, radius, color); + // matrices.pop(); } @Override From 51c6108e35afddf7979a53c1c6314a27c6a75732 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 21:20:14 +0100 Subject: [PATCH 06/12] Fixed soem stuff on RenderScope 1.21.6 #59 --- .../java/org/saturnclient/impl/ui/RenderScopeImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 6a34571..ec0010d 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -140,7 +140,7 @@ public class RenderScopeImpl implements RenderScope { SaturnClient.client.textRenderer, ((Text) Fonts.setFont(line, font)).asOrderedText(), new Matrix3x2f(this.matrices.stack), - 0, 0, // IMPORTANT + 0, font == 0 ? 1 : 8, finalColor, 0, false, this.scissorStack.peekLast())); matrices.pop(); @@ -245,9 +245,6 @@ public class RenderScopeImpl implements RenderScope { return; color = getColor(color); - GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() - .getTexture(sprite).getGlTextureView(); - if (sprite.getPath().endsWith(".svg")) { sprite = (Identifier) (Object) SvgTexture.getSvg( Providers.saturn.getClient(), @@ -255,8 +252,11 @@ public class RenderScopeImpl implements RenderScope { (x2 - x1) * 2, (y2 - y1) * 2); } + GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager() + .getTexture(sprite).getGlTextureView(); + this.state.addSimpleElement(new TexturedQuadGuiElementRenderState( - RenderPipelines.GUI, + RenderPipelines.GUI_TEXTURED, TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, u2, v1, v2, color, From 4f4427411156fd5fbe63c69ac691d65fdbf83c47 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 21:46:34 +0100 Subject: [PATCH 07/12] Fixed rounded corners on RenderScope 1.21.6 #59 --- .../impl/ref/Matrix3x2fStackRef.java | 2 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 25 ++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java index 1e08755..62d92e3 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ref/Matrix3x2fStackRef.java @@ -32,7 +32,7 @@ public class Matrix3x2fStackRef implements MatrixStackRef { @Override public void rotate(float angle) { - stack.rotate(angle); + stack.rotate((float) Math.toRadians(angle)); } @Override diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index ec0010d..86c338c 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -172,9 +172,8 @@ public class RenderScopeImpl implements RenderScope { matrices.pop(); matrices.push(); - matrices.translate(cornerWidth, cornerHeight * 2); - matrices.stack.rotate((float) Math.toRadians(90)); - matrices.translate(0, -cornerWidth); + matrices.rotate(-90); + matrices.translate(-cornerHeight * 2, 0); matrices.scale(0.05f, 0.05f); drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); matrices.pop(); @@ -186,19 +185,17 @@ public class RenderScopeImpl implements RenderScope { return; radius = Math.min(radius, Math.min(width, height)); - fill(x, y, x + width, y + height, color); + int cornerWidth = width / 2; + int cornerHeight = height / 2; - // int cornerWidth = width / 2; - // int cornerHeight = height / 2; + matrices.push(); + matrices.translate(x, y); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); - // matrices.push(); - // matrices.translate(x, y); - // drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - // matrices.translate(cornerWidth * 2, cornerHeight * 2); - // matrices.stack.rotate((float) Math.toRadians(90)); - // drawRoundedSide(cornerWidth, cornerHeight, radius, color); - // matrices.pop(); + matrices.translate(cornerWidth * 2, cornerHeight * 2); + matrices.rotate(180); + drawRoundedSide(cornerWidth, cornerHeight, radius, color); + matrices.pop(); } @Override From b457f070b9a05c26cd9889ffc8046a6fb9697416 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 22:18:26 +0100 Subject: [PATCH 08/12] Improved rounded rectangles #59 --- common | 2 +- .../saturnclient/impl/ui/RenderScopeImpl.java | 60 +------------------ .../saturnclient/impl/ui/RenderScopeImpl.java | 60 +------------------ .../saturnclient/impl/ui/RenderScopeImpl.java | 51 ---------------- 4 files changed, 5 insertions(+), 168 deletions(-) diff --git a/common b/common index fc1500a..b81a4dd 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit fc1500abbdf911987ee3d98ee2015bec7cbc96eb +Subproject commit b81a4dda9812f96cc824b49d2afee77fd89a0998 diff --git a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index ca83041..80061ca 100644 --- a/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.4/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -10,7 +10,6 @@ import org.joml.Matrix4f; import com.mojang.blaze3d.systems.RenderSystem; -import org.saturnclient.common.provider.Providers; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.common.ref.asset.SpriteRef; import org.saturnclient.common.ref.game.ItemStackRef; @@ -42,7 +41,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; public class RenderScopeImpl implements RenderScope { @@ -191,60 +189,6 @@ public class RenderScopeImpl implements RenderScope { fill(x + width - 1, y + 1, x + width, y + height - 1, color); } - @Override - public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { - if (color == 0) - return; - - radius = Math.min(radius, Math.min(width, height)); - int cornerWidth = width / 2; - int cornerHeight = height / 2; - - matrices.push(); - matrices.translate(x, y, 0); - - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); - matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - matrices.pop(); - } - - // Rounded rectangle helpers - private void drawRoundedCorner(int width, int height, int radius, int color) { - int w = width * 20; - int h = height * 20; - - for (int y = 0; y < h; y++) { - int startX = 0; - if (y < radius) { - double dy = radius - y - 0.5; - double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); - startX = radius - (int) dx; - } - drawRectangle(startX, y, w - startX, 1, color); - } - } - - private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - // Top - matrices.push(); - matrices.scale(0.05f, 0.05f, 1.0f); - drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - matrices.pop(); - - // Bottom - matrices.push(); - matrices.translate(cornerWidth, cornerHeight * 2, 0); - matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); - matrices.translate(0, -cornerWidth, 0); - matrices.scale(0.05f, 0.05f, 1.0f); - drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - matrices.pop(); - } - // ---------------------------- // Text // ---------------------------- @@ -320,8 +264,8 @@ public class RenderScopeImpl implements RenderScope { private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, float v2, int color) { if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), - (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); + sprite = (Identifier) (Object) SvgTexture.getSvg((IdentifierRef) (Object) sprite, (x2 - x1) * 2, + (y2 - y1) * 2); } if (color == 0) return; diff --git a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 4124776..b4688d8 100644 --- a/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.5/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -10,7 +10,6 @@ import org.joml.Matrix4f; import com.mojang.blaze3d.systems.RenderSystem; -import org.saturnclient.common.provider.Providers; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.common.ref.asset.SpriteRef; import org.saturnclient.common.ref.game.ItemStackRef; @@ -43,7 +42,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReportSection; -import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; public class RenderScopeImpl implements RenderScope { @@ -192,60 +190,6 @@ public class RenderScopeImpl implements RenderScope { fill(x + width - 1, y + 1, x + width, y + height - 1, color); } - @Override - public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { - if (color == 0) - return; - - radius = Math.min(radius, Math.min(width, height)); - int cornerWidth = width / 2; - int cornerHeight = height / 2; - - matrices.push(); - matrices.translate(x, y, 0); - - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - matrices.translate(cornerWidth * 2, cornerHeight * 2, 0); - matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(180)); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - matrices.pop(); - } - - // Rounded rectangle helpers - private void drawRoundedCorner(int width, int height, int radius, int color) { - int w = width * 20; - int h = height * 20; - - for (int y = 0; y < h; y++) { - int startX = 0; - if (y < radius) { - double dy = radius - y - 0.5; - double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); - startX = radius - (int) dx; - } - drawRectangle(startX, y, w - startX, 1, color); - } - } - - private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - // Top - matrices.push(); - matrices.scale(0.05f, 0.05f, 1.0f); - drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - matrices.pop(); - - // Bottom - matrices.push(); - matrices.translate(cornerWidth, cornerHeight * 2, 0); - matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(90)); - matrices.translate(0, -cornerWidth, 0); - matrices.scale(0.05f, 0.05f, 1.0f); - drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - matrices.pop(); - } - // ---------------------------- // Text // ---------------------------- @@ -321,8 +265,8 @@ public class RenderScopeImpl implements RenderScope { private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2, float u1, float u2, float v1, float v2, int color) { if (sprite.toString().endsWith(".svg")) { - sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), - (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); + sprite = (Identifier) (Object) SvgTexture.getSvg((IdentifierRef) (Object) sprite, (x2 - x1) * 2, + (y2 - y1) * 2); } if (color == 0) return; diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index 86c338c..cd5e0d8 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -10,7 +10,6 @@ import org.joml.Matrix3x2fStack; import com.mojang.blaze3d.textures.GpuTextureView; -import org.saturnclient.common.provider.Providers; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.common.ref.asset.SpriteRef; import org.saturnclient.common.ref.game.ItemStackRef; @@ -149,55 +148,6 @@ public class RenderScopeImpl implements RenderScope { } } - // Rounded rectangle helpers - private void drawRoundedCorner(int width, int height, int radius, int color) { - int w = width * 20; - int h = height * 20; - - for (int y = 0; y < h; y++) { - int startX = 0; - if (y < radius) { - double dy = radius - y - 0.5; - double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); - startX = radius - (int) dx; - } - drawRectangle(startX, y, w - startX, 1, color); - } - } - - private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { - matrices.push(); - matrices.scale(0.05f, 0.05f); - drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); - matrices.pop(); - - matrices.push(); - matrices.rotate(-90); - matrices.translate(-cornerHeight * 2, 0); - matrices.scale(0.05f, 0.05f); - drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color); - matrices.pop(); - } - - @Override - public void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) { - if (color == 0) - return; - radius = Math.min(radius, Math.min(width, height)); - - int cornerWidth = width / 2; - int cornerHeight = height / 2; - - matrices.push(); - matrices.translate(x, y); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - - matrices.translate(cornerWidth * 2, cornerHeight * 2); - matrices.rotate(180); - drawRoundedSide(cornerWidth, cornerHeight, radius, color); - matrices.pop(); - } - @Override public int getScaledWindowWidth() { return SaturnClient.client.getWindow().getScaledWidth(); @@ -244,7 +194,6 @@ public class RenderScopeImpl implements RenderScope { if (sprite.getPath().endsWith(".svg")) { sprite = (Identifier) (Object) SvgTexture.getSvg( - Providers.saturn.getClient(), (IdentifierRef) (Object) sprite, (x2 - x1) * 2, (y2 - y1) * 2); } From ebe7200d65aca1a365bad12c6c8659dc939665e8 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 23:26:33 +0100 Subject: [PATCH 09/12] Improved rounded rectangles #59 --- common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common b/common index b81a4dd..53dfa37 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit b81a4dda9812f96cc824b49d2afee77fd89a0998 +Subproject commit 53dfa37b642b4b8770b1e47c68d28e0f54abd782 From 3705afb5938ee9dd6c907c3d54829070d9da43e9 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Wed, 25 Mar 2026 23:36:00 +0100 Subject: [PATCH 10/12] Saturn Screen 1.21.6 small patches --- .../impl/ui/SaturnScreenFabric.java | 27 +++---------------- .../saturnclient/event/KeyInputHandler.java | 1 - 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index 2541142..435003c 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -3,21 +3,17 @@ package org.saturnclient.impl.ui; import java.time.Duration; import java.time.Instant; -import org.saturnclient.saturnclient.mixin.DrawContextAccessor; import org.saturnclient.ui.RenderScope; import org.saturnclient.ui.SaturnScreen; import org.saturnclient.ui.SaturnScreen.ScreenProvider; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.PostEffectProcessor; import net.minecraft.client.gui.CubeMapRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.RotatingCubeMapRenderer; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.render.DefaultFramebufferSet; import net.minecraft.client.texture.ResourceTexture; import net.minecraft.client.texture.TextureManager; -import net.minecraft.client.util.Pool; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -32,7 +28,6 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { ROTATING_PANORAMA_RENDERER = new RotatingCubeMapRenderer(PANORAMA_RENDERER); } - private final Pool pool = new Pool(3); public final SaturnScreen screen; public static void preload(MinecraftClient client) { @@ -56,7 +51,6 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { screen.init(); } - @SuppressWarnings("deprecation") @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { if (screen.start == null) { @@ -67,24 +61,9 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { mouseX *= 2; mouseY *= 2; - // if (client.world == null && client.getCurrentServerEntry() == null) { - // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, - // screen.backgroundOpacity, delta); - // } - - // PostEffectProcessor postEffectProcessor = - // this.client.getShaderLoader().loadPostEffect( - // Identifier.ofVanilla("blur"), - // DefaultFramebufferSet.MAIN_ONLY); - - // if (postEffectProcessor != null) { - // float radius = screen.backgroundBlur * Math.min((float) elapsed / 700, 1.0f); - // postEffectProcessor.render( - // this.client.getFramebuffer(), - // this.pool, - // pass -> pass.setUniform("Radius", radius) - // ); - // } + if (client.world == null && client.getCurrentServerEntry() == null) { + ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); + } RenderScope renderScope = new RenderScopeImpl(context); diff --git a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index 8e289e2..b1bae03 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -7,7 +7,6 @@ import net.minecraft.client.util.InputUtil; import org.saturnclient.config.Config; import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.client.ServiceClient; import org.saturnclient.common.provider.Providers; import org.saturnclient.ui.screens.EmoteWheel; import org.saturnclient.ui.screens.ShiftMenu; From 69698c16f7fcc1392eba3cb1c28608e2ece95b4a Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 26 Mar 2026 02:16:57 +0100 Subject: [PATCH 11/12] Fixed EntityDrawer --- .../impl/provider/SaturnProviderImpl.java | 3 - .../impl/ui/EntityDrawerImpl.java | 115 ++++++++---------- .../saturnclient/impl/ui/RenderScopeImpl.java | 25 ++++ .../impl/ui/SaturnScreenFabric.java | 2 +- 4 files changed, 77 insertions(+), 68 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java index 607b35e..8ac2333 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java @@ -9,9 +9,6 @@ import org.saturnclient.common.ref.game.MinecraftClientRef; import org.saturnclient.impl.cosmetics.utils.IdentifierUtils; import org.saturnclient.saturnclient.SaturnClient; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.util.Identifier; - public class SaturnProviderImpl implements SaturnProvider { @Override public MinecraftClientRef getClient() { diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index e1320c4..4712414 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -3,83 +3,70 @@ package org.saturnclient.impl.ui; import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; -import org.saturnclient.common.ref.render.QuaternionfRef; import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.ui.ElementContext; import org.saturnclient.ui.RenderScope; import org.saturnclient.ui.components.SkinPreview.EntityDrawer; -import net.minecraft.client.render.DiffuseLighting; import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.entity.LivingEntity; public class EntityDrawerImpl implements EntityDrawer { - public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float f, - float mouseX, - float mouseY, LivingEntity entity, float angle, boolean negativeAngle) { - float g = (float) (x1 + x2) / 2.0F; - float h = (float) (y1 + y2) / 2.0F; - renderScope.enableScissor(0, 6, x2, y2); - float i = (float) Math.atan((double) ((g - mouseX) / 40.0F)); - float j = (float) Math.atan((double) ((h - mouseY) / 40.0F)); - Quaternionf quaternionf = (new Quaternionf()).rotateZ(3.1415927F); - float k = entity.bodyYaw; - float l = entity.getYaw(); - float m = entity.getPitch(); - float n = entity.lastHeadYaw; - float o = entity.headYaw; - entity.setYaw(angle); - entity.bodyYaw = angle; - entity.setPitch(-(j * 20.0F)); - entity.headYaw = negativeAngle ? (i * 40.0F) + 180f : -(i * 40.0F); - entity.lastHeadYaw = entity.getHeadYaw(); - entity.setCustomNameVisible(false); - - float p = entity.getScale(); - Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + f * p, 0.0F); - float q = (float) size / p; - drawEntity(renderScope, g, h, q, vector3f, quaternionf, null, entity); - - entity.setCustomNameVisible(true); - entity.bodyYaw = k; - entity.setYaw(l); - entity.setPitch(m); - entity.lastHeadYaw = n; - entity.headYaw = o; - renderScope.disableScissor(); - } - - public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, - Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { - // if (renderScope instanceof RenderScopeImpl scopeImpl) { - // scopeImpl.matrices.push(); - // scopeImpl.matrices.translate((double) x, (double) y, 0); - // scopeImpl.matrices.scale(size, size, -size); - // scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z); - // scopeImpl.matrices.multiply(quaternionf); - // scopeImpl.draw(); - // DiffuseLighting.disableGuiDepthLighting(); - // EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); - - // entityRenderDispatcher.setRenderShadows(false); - // scopeImpl.draw((vertexConsumers) -> { - // entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, - // scopeImpl.matrices, vertexConsumers, 15728880); - // }); - - // scopeImpl.draw(); - // entityRenderDispatcher.setRenderShadows(true); - // scopeImpl.getMatrixStack().pop(); - // DiffuseLighting.enableGuiDepthLighting(); - // } - } - @Override public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { LivingEntity entity = SaturnClient.client.player; + + System.out.println(scale); + if (entity != null) { - drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, entity, angle, - negativeAngle); + drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, + SaturnClient.client.player); } } + + public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, int size, float scale, + float mouseX, float mouseY, LivingEntity entity) { + float f = (float) (x1 + x2) / 2.0F; + float g = (float) (y1 + y2) / 2.0F; + renderScope.enableScissor(x1, y1, x2, y2); + float h = (float) Math.atan((double) ((f - mouseX) / 40.0F)); + float i = (float) Math.atan((double) ((g - mouseY) / 40.0F)); + Quaternionf quaternionf = (new Quaternionf()).rotateZ((float) Math.PI); + Quaternionf quaternionf2 = (new Quaternionf()).rotateX(i * 20.0F * ((float) Math.PI / 180F)); + quaternionf.mul(quaternionf2); + float j = entity.bodyYaw; + float k = entity.getYaw(); + float l = entity.getPitch(); + float m = entity.lastHeadYaw; + float n = entity.headYaw; + entity.bodyYaw = 180.0F + h * 20.0F; + entity.setYaw(180.0F + h * 40.0F); + entity.setPitch(-i * 20.0F); + entity.headYaw = entity.getYaw(); + entity.lastHeadYaw = entity.getYaw(); + float o = entity.getScale(); + Vector3f vector3f = new Vector3f(0.0F, entity.getHeight() / 2.0F + scale * o, 0.0F); + float p = (float) size / o; + drawEntity(renderScope, x1, y1, x2, y2, p, vector3f, quaternionf, quaternionf2, entity); + entity.bodyYaw = j; + entity.setYaw(k); + entity.setPitch(l); + entity.lastHeadYaw = m; + entity.headYaw = n; + renderScope.disableScissor(); + } + + public static void drawEntity(RenderScope renderScope, int x1, int y1, int x2, int y2, float scale, + Vector3f translation, Quaternionf rotation, @Nullable Quaternionf overrideCameraAngle, + LivingEntity entity) { + EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); + EntityRenderer entityRenderer = entityRenderDispatcher.getRenderer(entity); + EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F); + entityRenderState.hitbox = null; + + if (renderScope instanceof RenderScopeImpl i) + i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2); + } } diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java index cd5e0d8..17f78e9 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/RenderScopeImpl.java @@ -7,6 +7,8 @@ import java.util.Objects; import org.jetbrains.annotations.Nullable; import org.joml.Matrix3x2f; import org.joml.Matrix3x2fStack; +import org.joml.Quaternionf; +import org.joml.Vector3f; import com.mojang.blaze3d.textures.GpuTextureView; @@ -29,6 +31,8 @@ import net.minecraft.client.gui.render.state.GuiRenderState; import net.minecraft.client.gui.render.state.ItemGuiElementRenderState; import net.minecraft.client.gui.render.state.TextGuiElementRenderState; import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; +import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.item.ItemRenderState; import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.TextureSetup; @@ -317,4 +321,25 @@ public class RenderScopeImpl implements RenderScope { fill(x, y + 1, x + 1, y + height - 1, color); fill(x + width - 1, y + 1, x + width, y + height - 1, color); } + + public void addEntity(EntityRenderState entityState, float scale, Vector3f translation, Quaternionf rotation, + @Nullable Quaternionf overrideCameraAngle, int x1, int y1, int x2, int y2) { + + Matrix3x2f mat = this.matrices.stack; + float offsetX = mat.m20; + float offsetY = mat.m21; + float scaleX = mat.m00; // current matrix X scale + float scaleY = mat.m11; // current matrix Y scale + + int adjustedX1 = (int) (x1 * scaleX + offsetX); + int adjustedY1 = (int) (y1 * scaleY + offsetY); + int adjustedX2 = (int) (x2 * scaleX + offsetX); + int adjustedY2 = (int) (y2 * scaleY + offsetY); + + float adjustedScale = scale * scaleX; // apply matrix scale to entity scale too + + this.state.addSpecialElement(new EntityGuiElementRenderState(entityState, translation, rotation, + overrideCameraAngle, adjustedX1, adjustedY1, adjustedX2, adjustedY2, adjustedScale, + this.scissorStack.peekLast())); + } } \ No newline at end of file diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index 435003c..3717c6f 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -62,7 +62,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { mouseY *= 2; if (client.world == null && client.getCurrentServerEntry() == null) { - ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); + // ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); } RenderScope renderScope = new RenderScopeImpl(context); From 7caff2025530744a0bf00c068b37e6d69988c2f5 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 26 Mar 2026 02:27:04 +0100 Subject: [PATCH 12/12] Fixed EntityDrawer --- .../main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java index 4712414..c2bfe84 100644 --- a/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java +++ b/versions/1.21.6/src/main/java/org/saturnclient/impl/ui/EntityDrawerImpl.java @@ -18,8 +18,6 @@ public class EntityDrawerImpl implements EntityDrawer { public void render(RenderScope renderScope, boolean negativeAngle, float angle, float scale, ElementContext ctx) { LivingEntity entity = SaturnClient.client.player; - System.out.println(scale); - if (entity != null) { drawEntity(renderScope, 0, 0, 75, 78, 30, 0.0625F, ctx.mouseX / scale, ctx.mouseY / scale, SaturnClient.client.player);