Refactored RenderScope 1.21.6 #59

This commit is contained in:
2026-03-25 19:24:02 +01:00
parent d50d19b609
commit 9424e2ec71
6 changed files with 163 additions and 301 deletions
@@ -62,8 +62,8 @@ public class RenderMixin {
ModLayout dim = hud.getDimensions(); ModLayout dim = hud.getDimensions();
scope.getMatrixStack().push(); scope.getMatrixStack().push();
scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value, 0f); scope.getMatrixStack().translate(dim.x.value, (float) dim.y.value);
scope.getMatrixStack().scale(dim.scale.value, dim.scale.value, 1.0f); scope.getMatrixStack().scale(dim.scale.value, dim.scale.value);
if (dim.renderBackground) { if (dim.renderBackground) {
scope.drawRoundedRectangle(0, 0, dim.width, dim.height, scope.drawRoundedRectangle(0, 0, dim.width, dim.height,
@@ -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();
}
}
@@ -5,7 +5,6 @@ import java.util.Deque;
import org.joml.Matrix3x2fStack; import org.joml.Matrix3x2fStack;
import org.saturnclient.common.ref.render.MatrixStackRef; import org.saturnclient.common.ref.render.MatrixStackRef;
import org.saturnclient.common.ref.render.QuaternionfRef;
public class Matrix3x2fStackRef implements MatrixStackRef { public class Matrix3x2fStackRef implements MatrixStackRef {
public final Matrix3x2fStack stack; public final Matrix3x2fStack stack;
@@ -33,11 +32,11 @@ public class Matrix3x2fStackRef implements MatrixStackRef {
if (t.scaleX != 1 || t.scaleY != 1) if (t.scaleX != 1 || t.scaleY != 1)
stack.scale(1f / t.scaleX, 1f / t.scaleY); stack.scale(1f / t.scaleX, 1f / t.scaleY);
stack.translate(-t.translateX, -t.translateY); stack.translate(-t.translateX, -t.translateY);
// rotation inversion can be added here if needed stack.rotate(-t.rotation);
} }
@Override @Override
public void scale(float x, float y, float z) { public void scale(float x, float y) {
stack.scale(x, y); stack.scale(x, y);
if (!customStack.isEmpty()) { if (!customStack.isEmpty()) {
Transform t = customStack.peek(); Transform t = customStack.peek();
@@ -47,7 +46,7 @@ public class Matrix3x2fStackRef implements MatrixStackRef {
} }
@Override @Override
public void translate(float x, float y, float z) { public void translate(float x, float y) {
stack.translate(x, y); stack.translate(x, y);
if (!customStack.isEmpty()) { if (!customStack.isEmpty()) {
Transform t = customStack.peek(); Transform t = customStack.peek();
@@ -57,38 +56,21 @@ public class Matrix3x2fStackRef implements MatrixStackRef {
} }
@Override @Override
public void translate(double x, double y, double z) { public void rotate(float angle) {
translate((float) x, (float) y, (float) z); stack.rotate(angle);
if (!customStack.isEmpty()) {
Transform t = customStack.peek();
t.rotation += angle;
}
} }
@Override @Override
public void multiply(QuaternionfRef quaternion) { public void rotate(float angle, float originX, float originY, float originZ) {
// 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();
} }
private static class Transform { private static class Transform {
float scaleX = 1f, scaleY = 1f; float scaleX = 1f, scaleY = 1f;
float translateX = 0f, translateY = 0f; float translateX = 0f, translateY = 0f;
// rotation can be added if needed float rotation = 0f;
} }
} }
@@ -51,27 +51,27 @@ public class EntityDrawerImpl implements EntityDrawer {
public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f, public static void drawEntity(RenderScope renderScope, float x, float y, float size, Vector3f vector3f,
Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) { Quaternionf quaternionf, @Nullable Quaternionf quaternionf2, LivingEntity entity) {
renderScope.getMatrixStack().push(); // if (renderScope instanceof RenderScopeImpl scopeImpl) {
renderScope.getMatrixStack().translate((double) x, (double) y, 50.0); // scopeImpl.matrices.push();
renderScope.getMatrixStack().scale(size, size, -size); // scopeImpl.matrices.translate((double) x, (double) y, 0);
renderScope.getMatrixStack().translate(vector3f.x, vector3f.y, vector3f.z); // scopeImpl.matrices.scale(size, size, -size);
renderScope.getMatrixStack().multiply((QuaternionfRef) quaternionf); // scopeImpl.matrices.translate(vector3f.x, vector3f.y, vector3f.z);
renderScope.draw(); // scopeImpl.matrices.multiply(quaternionf);
// DiffuseLighting.disableGuiDepthLighting(); // scopeImpl.draw();
EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher(); // DiffuseLighting.disableGuiDepthLighting();
// EntityRenderDispatcher entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
entityRenderDispatcher.setRenderShadows(false); // entityRenderDispatcher.setRenderShadows(false);
if (renderScope instanceof RenderScopeImpl r) { // scopeImpl.draw((vertexConsumers) -> {
// r.draw((vertexConsumers) -> { // entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F,
// entityRenderDispatcher.render(entity, 0.0, 0.0, 0.0, 1.0F, // scopeImpl.matrices, vertexConsumers, 15728880);
// r.matrices, vertexConsumers, // });
// 15728880);
// }); // scopeImpl.draw();
} // entityRenderDispatcher.setRenderShadows(true);
renderScope.draw(); // scopeImpl.getMatrixStack().pop();
entityRenderDispatcher.setRenderShadows(true); // DiffuseLighting.enableGuiDepthLighting();
renderScope.getMatrixStack().pop(); // }
// DiffuseLighting.enableGuiDepthLighting();
} }
@Override @Override
@@ -3,15 +3,11 @@ package org.saturnclient.impl.ui;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.joml.Matrix3x2f; import org.joml.Matrix3x2f;
import org.joml.Matrix3x2fStack; 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 com.mojang.blaze3d.textures.GpuTextureView;
import org.saturnclient.common.provider.Providers; 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.TextGuiElementRenderState;
import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState; import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState;
import net.minecraft.client.render.item.ItemRenderState; import net.minecraft.client.render.item.ItemRenderState;
import net.minecraft.client.texture.GuiAtlasManager;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.TextureSetup; import net.minecraft.client.texture.TextureSetup;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemDisplayContext; import net.minecraft.item.ItemDisplayContext;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashException;
@@ -49,13 +44,12 @@ import net.minecraft.util.crash.CrashReportSection;
import net.minecraft.world.World; import net.minecraft.world.World;
public class RenderScopeImpl implements RenderScope { public class RenderScopeImpl implements RenderScope {
private final Matrix3x2fStackRef matrices;
private final GuiAtlasManager guiAtlasManager; public final Matrix3x2fStackRef matrices;
public final GuiRenderState state; public final GuiRenderState state;
private ScissorStack scissorStack; private ScissorStack scissorStack;
private int opacity = 255 << 24; private int opacity = 0xFF << 24;
private final ItemRenderState itemRenderState;
public RenderScopeImpl(DrawContext context) { public RenderScopeImpl(DrawContext context) {
this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState()); this(context.getMatrices(), ((DrawContextAccessor) (Object) context).getState());
@@ -64,9 +58,7 @@ public class RenderScopeImpl implements RenderScope {
public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) { public RenderScopeImpl(Matrix3x2fStack matrices, GuiRenderState state) {
this.state = state; this.state = state;
this.matrices = new Matrix3x2fStackRef(matrices); this.matrices = new Matrix3x2fStackRef(matrices);
this.guiAtlasManager = SaturnClient.client.getGuiAtlasManager();
this.scissorStack = new ScissorStack(); this.scissorStack = new ScissorStack();
this.itemRenderState = new ItemRenderState();
} }
@Override @Override
@@ -76,7 +68,7 @@ public class RenderScopeImpl implements RenderScope {
@Override @Override
public void setOpacity(float alpha) { public void setOpacity(float alpha) {
this.opacity = (int) (alpha * 255) << 24; this.opacity = ((int) (alpha * 255)) << 24;
} }
@Override @Override
@@ -90,15 +82,12 @@ public class RenderScopeImpl implements RenderScope {
@Override @Override
public void fill(int x1, int y1, int x2, int y2, int color) { public void fill(int x1, int y1, int x2, int y2, int color) {
this.state.addSimpleElement( this.state.addSimpleElement(
new ColoredQuadGuiElementRenderState(RenderPipelines.GUI, TextureSetup.empty(), new ColoredQuadGuiElementRenderState(
RenderPipelines.GUI,
TextureSetup.empty(),
new Matrix3x2f(this.matrices.stack), new Matrix3x2f(this.matrices.stack),
x1, y1, x2, x1, y1, x2, y2, color, color,
y2, color, color, this.scissorStack.peekLast())); 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);
} }
@Override @Override
@@ -106,22 +95,21 @@ public class RenderScopeImpl implements RenderScope {
if (color == 0) if (color == 0)
return; return;
color = getColor(color); color = getColor(color);
int x1 = x; int x1 = x;
int x2 = x + width; int x2 = x + width;
int y1 = y; int y1 = y;
int y2 = y + height; int y2 = y + height;
int i; if (x2 < x1) {
if (x1 < x2) { int tmp = x1;
i = x1;
x1 = x2; x1 = x2;
x2 = i; x2 = tmp;
} }
if (y2 < y1) {
if (y1 < y2) { int tmp = y1;
i = y1;
y1 = y2; y1 = y2;
y2 = i; y2 = tmp;
} }
this.fill(x1, y1, x2, y2, color); 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) { public void drawText(float scale, String text, int x, int y, int font, int color) {
if (color == 0) if (color == 0)
return; return;
if (font == 0) { if (font == 0)
scale *= 2; scale *= 2;
}
int i = 0; int lineIndex = 0;
for (String line : text.split("\n")) { for (String line : text.split("\n")) {
color = getColor(color); int finalColor = getColor(color);
this.state.addText(new TextGuiElementRenderState(SaturnClient.client.textRenderer, this.state.addText(
((Text) Fonts.setFont(line, font)).asOrderedText(), new Matrix3x2f(this.matrices.stack), x, y, new TextGuiElementRenderState(
color, 0, false, this.scissorStack.peekLast())); 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.push();
matrices.translate(x, y + (i * Fonts.getHeight()), 0); matrices.translate(x, y + (lineIndex * Fonts.getHeight()));
matrices.scale(scale, scale, 0); matrices.scale(scale, scale);
i++; lineIndex++;
} }
} }
// Rounded rectangle helpers
private void drawRoundedCorner(int width, int height, int radius, int color) { private void drawRoundedCorner(int width, int height, int radius, int color) {
int w = width * 20; int w = width * 20;
int h = height * 20; int h = height * 20;
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
int startX = 0; int startX = 0;
if (y < radius) { if (y < radius) {
double dy = radius - y - 0.5; double dy = radius - y - 0.5;
double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy)); double dx = Math.sqrt(Math.max(0, radius * radius - dy * dy));
startX = radius - (int) dx; startX = radius - (int) dx;
} }
drawRectangle(startX, y, w - startX, 1, color);
this.drawRectangle(startX, y, w - startX, 1, color);
} }
} }
private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) { private void drawRoundedSide(int cornerWidth, int cornerHeight, int radius, int color) {
// Top matrices.push();
this.matrices.push(); matrices.scale(0.05f, 0.05f);
drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color);
matrices.pop();
this.matrices.scale(0.05f, 0.05f, 0); matrices.push();
matrices.translate(cornerWidth, cornerHeight * 2);
this.drawRoundedCorner(cornerWidth, cornerHeight, radius * 10, color); matrices.stack.rotate((float) Math.toRadians(90));
matrices.translate(0, -cornerWidth);
this.matrices.pop(); matrices.scale(0.05f, 0.05f);
drawRoundedCorner(cornerHeight, cornerWidth, radius * 10, color);
// Bottom matrices.pop();
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();
} }
@Override @Override
@@ -201,24 +181,18 @@ public class RenderScopeImpl implements RenderScope {
if (color == 0) if (color == 0)
return; return;
radius = Math.min(radius, Math.min(width, height)); radius = Math.min(radius, Math.min(width, height));
int cornerWidth = width / 2; int cornerWidth = width / 2;
int cornerHeight = height / 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); matrices.translate(cornerWidth * 2, cornerHeight * 2);
matrices.stack.rotate((float) Math.toRadians(90));
this.drawRoundedSide(cornerWidth, cornerHeight, radius, color); drawRoundedSide(cornerWidth, cornerHeight, radius, color);
matrices.pop();
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();
} }
@Override @Override
@@ -231,212 +205,164 @@ public class RenderScopeImpl implements RenderScope {
return SaturnClient.client.getWindow().getScaledHeight(); return SaturnClient.client.getWindow().getScaledHeight();
} }
@Override // Texture rendering
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 @Override
public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height) { 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 @Override
public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height,
int regionWith, int regionWidth, int regionHeight, int textureWidth, int textureHeight) {
int regionHeight, int textureWidth, int textureHeight) { drawTexture(sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, -1);
this.drawTexture(sprite, x, y, u, v, width, height, regionWith, regionHeight, textureWidth, textureHeight, -1);
} }
@Override @Override
public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height, public void drawTexture(IdentifierRef sprite, int x, int y, float u, float v, int width, int height,
int regionWidth, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color) {
int regionHeight, int textureWidth, int textureHeight, int color) { drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height,
this.drawTexturedQuad((Identifier) (Object) sprite, x, x + width, y, y + height, (u + 0f) / textureWidth,
(u + 0.0F) / (float) textureWidth, (u + regionWidth) / textureWidth,
(u + (float) regionWidth) / (float) textureWidth, (v + 0.0F) / (float) textureHeight, (v + 0f) / textureHeight,
(v + (float) regionHeight) / (float) textureHeight, color); (v + regionHeight) / textureHeight,
color);
} }
/* Minecraft sprites */ private void drawTexturedQuad(Identifier sprite, int x1, int x2, int y1, int y2,
float u1, float u2, float v1, float v2, int color) {
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();
if (color == 0) if (color == 0)
return; return;
x1 *= 4;
x2 *= 4;
y1 *= 4;
y2 *= 4;
color = getColor(color); color = getColor(color);
if (sprite.toString().endsWith(".svg")) { GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager()
sprite = (Identifier) (Object) SvgTexture.getSvg(Providers.saturn.getClient(), .getTexture(sprite).getGlTextureView();
if (sprite.getPath().endsWith(".svg")) {
sprite = (Identifier) (Object) SvgTexture.getSvg(
Providers.saturn.getClient(),
(IdentifierRef) (Object) sprite, (IdentifierRef) (Object) sprite,
(x2 - x1) * 2, (y2 - y1) * 2); (x2 - x1) * 2, (y2 - y1) * 2);
} }
this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(RenderPipelines.GUI, this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(
TextureSetup.withoutGlTexture(gpuTextureView), new Matrix3x2f(this.matrices.stack), x1, y1, x2, y2, u1, RenderPipelines.GUI,
u2, TextureSetup.withoutGlTexture(gpuTextureView),
v1, v2, new Matrix3x2f(this.matrices.stack),
color, this.scissorStack.peekLast())); x1, y1, x2, y2, u1, u2, v1, v2, color,
this.scissorStack.peekLast()));
} }
// Scissor management
@Override @Override
public void enableScissor(int x1, int y1, int x2, int y2) { 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); ScreenRect rect = new ScreenRect(x1, y1, x2 - x1, y2 - y1).transform(this.matrices.stack);
this.scissorStack.push(screenRect); scissorStack.push(rect);
} }
@Override @Override
public void disableScissor() { public void disableScissor() {
this.scissorStack.pop(); scissorStack.pop();
} }
@Override @Override
public boolean scissorContains(int x, int y) { public boolean scissorContains(int x, int y) {
return this.scissorStack.contains(x, y); return scissorStack.contains(x, y);
} }
public static class ScissorStack { public static class ScissorStack {
private final Deque<ScreenRect> stack = new ArrayDeque(); private final Deque<ScreenRect> stack = new ArrayDeque<>();
ScissorStack() {
}
public ScreenRect push(ScreenRect rect) { public ScreenRect push(ScreenRect rect) {
ScreenRect screenRect = (ScreenRect) this.stack.peekLast(); ScreenRect last = stack.peekLast();
if (screenRect != null) { if (last != null) {
ScreenRect screenRect2 = (ScreenRect) Objects.requireNonNullElse(rect.intersection(screenRect), ScreenRect intersection = Objects.requireNonNullElse(rect.intersection(last), ScreenRect.empty());
ScreenRect.empty()); stack.addLast(intersection);
this.stack.addLast(screenRect2); return intersection;
return screenRect2;
} else { } else {
this.stack.addLast(rect); stack.addLast(rect);
return rect; return rect;
} }
} }
@Nullable @Nullable
public ScreenRect pop() { public ScreenRect pop() {
if (this.stack.isEmpty()) { if (stack.isEmpty())
throw new IllegalStateException("Scissor stack underflow"); throw new IllegalStateException("Scissor stack underflow");
} else { stack.removeLast();
this.stack.removeLast(); return stack.peekLast();
return (ScreenRect) this.stack.peekLast();
}
} }
@Nullable @Nullable
public ScreenRect peekLast() { public ScreenRect peekLast() {
return (ScreenRect) this.stack.peekLast(); return stack.peekLast();
} }
public boolean contains(int x, int y) { 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 @Override
public void drawItem(ItemStackRef item, int x, int y) { public void drawItem(ItemStackRef stack, int x, int y) {
this.drawItem(SaturnClient.client.player, SaturnClient.client.world, item, x, y, 0); drawItem(null, SaturnClient.client.world, stack, 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, private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStackRef stack, int x, int y,
int seed) { 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, private void drawItem(@Nullable LivingEntity entity, @Nullable World world, ItemStack stack, int x, int y, int seed,
int z) { int z) {
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
ItemRenderState itemRenderState = new ItemRenderState(); ItemRenderState state = new ItemRenderState();
SaturnClient.client.getItemModelManager().clearAndUpdate(itemRenderState, stack, ItemDisplayContext.GUI, SaturnClient.client.getItemModelManager().clearAndUpdate(state, stack, ItemDisplayContext.GUI, world,
world,
entity, seed); entity, seed);
try { try {
this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(), this.state.addItem(new ItemGuiElementRenderState(stack.getItem().getName().toString(),
new Matrix3x2f(this.matrices.stack), itemRenderState, x, y, this.scissorStack.peekLast())); new Matrix3x2f(this.matrices.stack), state, x, y, scissorStack.peekLast()));
} catch (Throwable throwable) { } catch (Throwable t) {
CrashReport crashReport = CrashReport.create(throwable, "Rendering item"); CrashReport report = CrashReport.create(t, "Rendering item");
CrashReportSection crashReportSection = crashReport.addElement("Item being rendered"); CrashReportSection section = report.addElement("Item being rendered");
crashReportSection.add("Item Type", () -> String.valueOf(stack.getItem())); section.add("Item Type", () -> String.valueOf(stack.getItem()));
crashReportSection.add("Item Components", () -> String.valueOf(stack.getComponents())); section.add("Item Components", () -> String.valueOf(stack.getComponents()));
crashReportSection.add("Item Foil", () -> String.valueOf(stack.hasGlint())); section.add("Item Foil", () -> String.valueOf(stack.hasGlint()));
throw new CrashException(crashReport); throw new CrashException(report);
} }
} }
} }
@Override
public void draw() {
}
@Override @Override
public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height) { 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 @Override
public void drawSpriteStretched(SpriteRef saturnSprite, int x, int y, int width, int height, int color) { public void drawSpriteStretched(SpriteRef sprite, int x, int y, int width, int height, int color) {
Sprite sprite = (Sprite) saturnSprite; Sprite mcSprite = (Sprite) sprite;
if (color == 0) if (color == 0 || width == 0 || height == 0)
return; return;
if (width != 0 && height != 0) {
this.drawTexturedQuad(sprite.getAtlasId(), x, x + width, y, y + height, sprite.getMinU(), sprite.getMaxU(), drawTexturedQuad(mcSprite.getAtlasId(), x, x + width, y, y + height,
sprite.getMinV(), sprite.getMaxV(), color); 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) { public void drawBorder(int x, int y, int width, int height, int color) {
this.fill(x, y, x + width, y + 1, color); fill(x, y, x + width, y + 1, color);
this.fill(x, y + height - 1, x + width, y + height, color); fill(x, y + height - 1, x + width, y + height, color);
this.fill(x, y + 1, x + 1, y + height - 1, color); 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 + width - 1, y + 1, x + width, y + height - 1, color);
} }
} }
@@ -6,7 +6,6 @@
"client": [ "client": [
"IdentifierMixin", "IdentifierMixin",
"ItemStackMixin", "ItemStackMixin",
"MatrixStackMixin",
"MinecraftClientMixin", "MinecraftClientMixin",
"QuaternionfMixin", "QuaternionfMixin",
"WindowMixin", "WindowMixin",