diff --git a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java index 790dd46344..d11547a6e9 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java @@ -212,6 +212,8 @@ public WidgetScreen proxiesScreen() { public abstract boolean categoryIcons(); + public abstract int roundAmount(); + public abstract boolean hideHUD(); public double textWidth(String text, int length, boolean title) { diff --git a/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java b/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java index bb41fbf949..21ca769dc9 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java @@ -206,6 +206,34 @@ public void quad(double x, double y, double width, double height, GuiTexture tex rTex.texQuad(x, y, width, height, texture.get(width, height), color); } + public void quadRounded(double x, double y, double width, double height, Color color, double round, boolean roundTop) { + r.quadRounded(x, y, width, height, color, round, roundTop); + } + public void quadRounded(double x, double y, double width, double height, Color color, double round) { + quadRounded(x, y, width, height, color, round, true); + } + public void quadRounded(WWidget widget, Color color, double round) { + quadRounded(widget.x, widget.y, widget.width, widget.height, color, round); + } + public void quadOutlineRounded(double x, double y, double width, double height, Color color, double round, double s) { + r.quadRoundedOutline(x, y, width, height, color, round, s); + } + public void quadOutlineRounded(WWidget widget, Color color, double round, double s) { + quadOutlineRounded(widget.x, widget.y, widget.width, widget.height, color, round, s); + } + public void quadRoundedSide(double x, double y, double width, double height, Color color, double r, boolean right) { + this.r.quadRoundedSide(x, y, width, height, color, r, right); + } + public void quadRoundedSide(WWidget widget, Color color, double round, boolean right) { + quadRoundedSide(widget.x, widget.y, widget.width, widget.height, color, round, right); + } + public void circlePart(double x, double y, double r, double startAngle, double angle, Color color) { + this.r.circlePart(x, y, r, startAngle, angle, color); + } + public void circlePartOutline(double x, double y, double r, double startAngle, double angle, Color color, double outlineWidth) { + this.r.circlePartOutline(x, y, r, startAngle, angle, color, outlineWidth); + } + public void rotatedQuad(double x, double y, double width, double height, double rotation, GuiTexture texture, Color color) { rTex.texQuad(x, y, width, height, rotation, texture.get(width, height), color); } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java index abd892ea46..77d74b0e40 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java @@ -82,6 +82,17 @@ public class MeteorGuiTheme extends GuiTheme { .build() ); + public final Setting round = sgGeneral.add(new IntSetting.Builder() + .name("round") + .description("How much windows should be rounded") + .defaultValue(0) + .min(0) + .max(20) + .sliderMin(0) + .sliderMax(15) + .build() + ); + // Colors public final Setting accentColor = color("accent", "Main color of the GUI.", new SettingColor(135, 0, 255)); @@ -297,6 +308,11 @@ public boolean hideHUD() { return hideHUD.get(); } + @Override + public int roundAmount() { + return round.get(); + } + public class ThreeStateColorSetting { private final Setting normal, hovered, pressed; diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorWidget.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorWidget.java index 7cf58ad1d6..7b472a778a 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorWidget.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorWidget.java @@ -19,12 +19,9 @@ default void renderBackground(GuiRenderer renderer, WWidget widget, boolean pres MeteorGuiTheme theme = theme(); double s = theme.scale(2); - renderer.quad(widget.x + s, widget.y + s, widget.width - s * 2, widget.height - s * 2, theme.backgroundColor.get(pressed, mouseOver)); - + int r = theme.roundAmount(); Color outlineColor = theme.outlineColor.get(pressed, mouseOver); - renderer.quad(widget.x, widget.y, widget.width, s, outlineColor); - renderer.quad(widget.x, widget.y + widget.height - s, widget.width, s, outlineColor); - renderer.quad(widget.x, widget.y + s, s, widget.height - s * 2, outlineColor); - renderer.quad(widget.x + widget.width - s, widget.y + s, s, widget.height - s * 2, outlineColor); + renderer.quadRounded(widget.x + s, widget.y + s, widget.width - s * 2, widget.height - s * 2, theme.backgroundColor.get(pressed, mouseOver), r - s); + renderer.quadOutlineRounded(widget, outlineColor, r, s); } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorQuad.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorQuad.java index 601fe7bc19..f540aaa8af 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorQuad.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorQuad.java @@ -16,6 +16,6 @@ public WMeteorQuad(Color color) { @Override protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, double delta) { - renderer.quad(x, y, width, height, color); + renderer.quadRounded(x, y, width, height, color, theme.roundAmount()); } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorWindow.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorWindow.java index d667ca22fe..7d70961848 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorWindow.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/WMeteorWindow.java @@ -22,14 +22,14 @@ protected WHeader header() { @Override protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, double delta) { if (expanded || animProgress > 0) { - renderer.quad(x, y + header.height, width, height - header.height, theme().backgroundColor.get()); + renderer.quadRounded(x, y + header.height / 2, width, height - header.height / 2, theme().backgroundColor.get(), theme.roundAmount(), false); } } private class WMeteorHeader extends WHeader { @Override protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, double delta) { - renderer.quad(this, theme().accentColor.get()); + renderer.quadRounded(this, theme().accentColor.get(), theme.roundAmount()); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorCheckbox.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorCheckbox.java index dee4ed192c..12248f40e4 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorCheckbox.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorCheckbox.java @@ -30,7 +30,7 @@ protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, doub if (animProgress > 0) { double cs = (width - theme.scale(2)) / 1.75 * animProgress; - renderer.quad(x + (width - cs) / 2, y + (height - cs) / 2, cs, cs, theme.checkboxColor.get()); + renderer.quadRounded(x + (width - cs) / 2, y + (height - cs) / 2, cs, cs, theme.checkboxColor.get(), theme.roundAmount()); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java index 1c45c50e0a..b024c47c1b 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WTopBar.java @@ -33,6 +33,15 @@ public void init() { } } + protected int getState(WTopBarButton btn) { + int a = 0; + if (btn.equals(cells.get(0).widget())) + a |= 1; + if (btn.equals(cells.get(cells.size() - 1).widget())) + a |= 2; + return a; + } + protected class WTopBarButton extends WPressable { private final Tab tab; @@ -66,7 +75,20 @@ protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, doub double pad = pad(); Color color = getButtonColor(pressed || (mc.currentScreen instanceof TabScreen && ((TabScreen) mc.currentScreen).tab == tab), mouseOver); - renderer.quad(x, y, width, height, color); + switch (getState(this)) { + case 1: + renderer.quadRoundedSide(this, color, theme.roundAmount(), false); + break; + case 2: + renderer.quadRoundedSide(this, color, theme.roundAmount(), true); + break; + case 3: + renderer.quadRounded(this, color, theme.roundAmount()); + break; + default: + renderer.quad(this, color); + break; + } renderer.text(tab.name, x + pad, y + pad, getNameColor(), false); } } diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/Mesh.java b/src/main/java/meteordevelopment/meteorclient/renderer/Mesh.java index 41673f344c..603f937fa7 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/Mesh.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/Mesh.java @@ -174,6 +174,17 @@ public void quad(int i1, int i2, int i3, int i4) { growIfNeeded(); } + public void triangle(int i1, int i2, int i3) { + long p = indicesPointer + indicesCount * 4L; + + memPutInt(p, i1); + memPutInt(p + 4, i2); + memPutInt(p + 8, i3); + + indicesCount += 3; + growIfNeeded(); + } + public void growIfNeeded() { // Vertices if ((vertexI + 1) * primitiveVerticesSize >= vertices.capacity()) { diff --git a/src/main/java/meteordevelopment/meteorclient/renderer/Renderer2D.java b/src/main/java/meteordevelopment/meteorclient/renderer/Renderer2D.java index 999b766ad5..402c31dcf1 100644 --- a/src/main/java/meteordevelopment/meteorclient/renderer/Renderer2D.java +++ b/src/main/java/meteordevelopment/meteorclient/renderer/Renderer2D.java @@ -136,4 +136,126 @@ public void texQuad(double x, double y, double width, double height, double rota public void texQuad(double x, double y, double width, double height, double rotation, TextureRegion region, Color color) { texQuad(x, y, width, height, rotation, region.x1, region.y1, region.x2, region.y2, color); } + + // Rounded quad + + private final double circleNone = 0; + private final double circleQuarter = Math.PI / 2; + private final double circleHalf = circleQuarter * 2; + private final double circleThreeQuarter = circleQuarter * 3; + + public void quadRoundedOutline(double x, double y, double width, double height, Color color, double r, double s) { + r = getR(r, width, height); + if (r <= 0) { + quad(x, y, width, s, color); + quad(x, y + height - s, width, s, color); + quad(x, y + s, s, height - s * 2, color); + quad(x + width - s, y + s, s, height - s * 2, color); + } + else { + //top + circlePartOutline(x + r, y + r, r, circleThreeQuarter, circleQuarter, color, s); + quad(x + r, y, width - r * 2, s, color); + circlePartOutline(x + width - r, y + r, r, circleNone, circleQuarter, color, s); + //middle + quad(x, y + r, s, height - r * 2, color); + quad(x + width - s, y + r, s, height - r * 2, color); + //bottom + circlePartOutline(x + width - r, y + height - r, r, circleQuarter, circleQuarter, color, s); + quad(x + r, y + height - s, width - r * 2, s, color); + circlePartOutline(x + r, y + height - r, r, circleHalf, circleQuarter, color, s); + } + } + + public void quadRounded(double x, double y, double width, double height, Color color, double r, boolean roundTop) { + r = getR(r, width, height); + if (r <= 0) + quad(x, y, width, height, color); + else { + if (roundTop) { + //top + circlePart(x + r, y + r, r, circleThreeQuarter, circleQuarter, color); + quad(x + r, y, width - 2 * r, r, color); + circlePart(x + width - r, y + r, r, circleNone, circleQuarter, color); + //middle + quad(x, y + r, width, height - 2 * r, color); + } + else { + //middle + quad(x, y, width, height - r, color); + } + //bottom + circlePart(x + width - r, y + height - r, r, circleQuarter, circleQuarter, color); + quad(x + r, y + height - r, width - 2 * r, r, color); + circlePart(x + r, y + height - r, r, circleHalf, circleQuarter, color); + } + } + + public void quadRoundedSide(double x, double y, double width, double height, Color color, double r, boolean right) { + r = getR(r, width, height); + if (r <= 0) + quad(x, y, width, height, color); + else { + if (right) { + circlePart(x + width - r, y + r, r, circleNone, circleQuarter, color); + circlePart(x + width - r, y + height - r, r, circleQuarter, circleQuarter, color); + quad(x, y, width - r, height, color); + quad(x + width - r, y + r, r, height - r * 2, color); + } + else { + circlePart(x + r, y + r, r, circleThreeQuarter, circleQuarter, color); + circlePart(x + r, y + height - r, r, circleHalf, circleQuarter, color); + quad(x + r, y, width - r, height, color); + quad(x, y + r, r, height - r * 2, color); + } + } + } + + private double getR(double r, double w, double h) { + if (r * 2 > h) { + r = (int)h / 2; + } + if (r * 2 > w) { + r = (int)w / 2; + } + return r; + } + + private int getCirDepth(double r, double angle) { + return Math.max(1, (int)(angle * r / circleQuarter)); + } + + public void circlePart(double x, double y, double r, double startAngle, double angle, Color color) { + int cirDepth = getCirDepth(r, angle); + double cirPart = angle / cirDepth; + int center = triangles.vec2(x, y).color(color).next(); + int prev = vecOnCircle(x, y, r, startAngle, color); + for (int i = 1; i < cirDepth + 1; i++) { + int next = vecOnCircle(x, y, r, startAngle + cirPart * i, color); + triangles.triangle(prev, center, next); + prev = next; + } + } + + public void circlePartOutline(double x, double y, double r, double startAngle, double angle, Color color, double outlineWidth) { + if (outlineWidth >= r) { + circlePart(x, y, r, startAngle, angle, color); + return; + } + int cirDepth = getCirDepth(r, angle); + double cirPart = angle / cirDepth; + int innerPrev = vecOnCircle(x, y, r - outlineWidth, startAngle, color); + int outerPrev = vecOnCircle(x, y, r, startAngle, color); + for (int i = 1; i < cirDepth + 1; i++) { + int inner = vecOnCircle(x, y, r - outlineWidth, startAngle + cirPart * i, color); + int outer = vecOnCircle(x, y, r, startAngle + cirPart * i, color); + triangles.quad(inner, innerPrev, outerPrev, outer); + innerPrev = inner; + outerPrev = outer; + } + } + + private int vecOnCircle(double x, double y, double r, double angle, Color color) { + return triangles.vec2(x + Math.sin(angle) * r, y - Math.cos(angle) * r).color(color).next(); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/HudRenderer.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/HudRenderer.java index 170f7bbd51..5d93b2d86a 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/HudRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/HudRenderer.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.systems.modules.render.hud; +import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.utils.render.color.Color; @@ -46,4 +47,8 @@ public double textHeight() { public void addPostTask(Runnable runnable) { postTasks.add(runnable); } + + public int roundAmount() { + return GuiThemes.get().roundAmount(); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/CombatHud.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/CombatHud.java index ac8968c6bf..399ff9b65d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/CombatHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/CombatHud.java @@ -191,7 +191,7 @@ public void render(HudRenderer renderer) { // Background Renderer2D.COLOR.begin(); - Renderer2D.COLOR.quad(x, y, box.width, box.height, backgroundColor.get()); + Renderer2D.COLOR.quadRounded(x, y, box.width, box.height, backgroundColor.get(), renderer.roundAmount(), true); Renderer2D.COLOR.render(null); // Player Model diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/InventoryViewerHud.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/InventoryViewerHud.java index 51212f2427..4a36684c13 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/InventoryViewerHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/InventoryViewerHud.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.systems.modules.render.hud.modules; +import meteordevelopment.meteorclient.gui.GuiThemes; import meteordevelopment.meteorclient.renderer.GL; import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.settings.*; @@ -104,7 +105,7 @@ private void drawBackground(int x, int y) { } case Flat -> { Renderer2D.COLOR.begin(); - Renderer2D.COLOR.quad(x, y, w, h, color.get()); + Renderer2D.COLOR.quadRounded(x, y, w, h, color.get(), GuiThemes.get().roundAmount(), true); Renderer2D.COLOR.render(null); } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/PlayerModelHud.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/PlayerModelHud.java index cbd1adb5cd..261968ee1b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/PlayerModelHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/hud/modules/PlayerModelHud.java @@ -96,7 +96,7 @@ public void render(HudRenderer renderer) { if (background.get()) { Renderer2D.COLOR.begin(); - Renderer2D.COLOR.quad(x, y, box.width, box.height, backgroundColor.get()); + Renderer2D.COLOR.quadRounded(x, y, box.width, box.height, backgroundColor.get(), renderer.roundAmount(), true); Renderer2D.COLOR.render(null); }