Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rounding in UIs #619

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2cef7d6
First attempt at rounding, not quite perfect
JFronny May 1, 2021
e8600bc
Custom drawing for background outline (fix transparency)
JFronny May 1, 2021
14eba34
Round top bar
JFronny May 1, 2021
2aac4aa
Make TopBarButton with edges default case
JFronny May 1, 2021
b74f5bb
Round Combat and PlayerModel HUD element backgrounds
JFronny May 1, 2021
a218d20
Round flat inventory HUD
JFronny May 11, 2021
9f5540c
Merge branch 'MeteorDevelopment:master' into rounded-ui
JFronny May 11, 2021
f5e847f
Merge branch 'MeteorDevelopment:master' into rounded-ui
JFronny May 20, 2021
186a89d
Expose logic for drawing partial circles
May 20, 2021
db8a9db
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 1, 2021
ad58388
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 7, 2021
0c4f1aa
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 10, 2021
d07e057
Fix
JFronny Jun 10, 2021
543c97f
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 11, 2021
c5f98a4
Optimize circlePartOutline
JFronny Jun 11, 2021
fb7c593
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 14, 2021
cb0ca2d
Fix
JFronny Jun 14, 2021
b65c5e7
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 17, 2021
0a0ec41
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jun 19, 2021
dfc9230
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jul 19, 2021
37cc259
Fix Mesh addition
JFronny Jul 19, 2021
9281345
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Jul 24, 2021
f3fdb37
Remove seams in MeteorWidget.renderBackground
JFronny Jul 24, 2021
8093f10
Merge branch 'master' into rounded-ui
JFronny Jul 26, 2021
9c1cfd3
Merge remote-tracking branch 'origin/master' into rounded-ui
JFronny Aug 21, 2021
1c42070
Update mesh patch for DMA
JFronny Aug 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ public WidgetScreen proxiesScreen() {

public abstract int blur();

public abstract int roundAmount();

public abstract boolean hideHUD();

public double textWidth(String text, int length, boolean title) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,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, int 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, int round) {
quadRounded(x, y, width, height, color, round, true);
}
public void quadRounded(WWidget widget, Color color, int 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, int round, double s) {
r.quadRoundedOutline(x, y, width, height, color, round, s);
}
public void quadOutlineRounded(WWidget widget, Color color, int 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, int r, boolean right) {
this.r.quadRoundedSide(x, y, width, height, color, r, right);
}
public void quadRoundedSide(WWidget widget, Color color, int 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ public class MeteorGuiTheme extends GuiTheme {
.build()
);

public final Setting<Integer> 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<SettingColor> accentColor = color("accent", "Main color of the GUI.", new SettingColor(135, 0, 255));
Expand Down Expand Up @@ -310,6 +321,11 @@ public boolean hideHUD() {
return hideHUD.get();
}

@Override
public int roundAmount() {
return round.get();
}

public class ThreeStateColorSetting {
private final Setting<SettingColor> normal, hovered, pressed;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
renderer.quadOutlineRounded(widget, outlineColor, r, s);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -66,7 +75,21 @@ 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);
//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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,15 @@ public void quad(int i1, int i2, int i3, int i4) {
growIfNeeded();
}

public void triangle(int i1, int i2, int i3) {
indices.put(i1);
indices.put(i2);
indices.put(i3);

indicesCount += 3;
growIfNeeded();
}

private void growIfNeeded() {
// Vertices
if ((vertexI + 1) * primitiveVerticesSize >= vertices.capacity()) {
Expand Down
122 changes: 122 additions & 0 deletions src/main/java/meteordevelopment/meteorclient/renderer/Renderer2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -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, int 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, int 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, int 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 int getR(int 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -46,4 +47,8 @@ public double textHeight() {
public void addPostTask(Runnable runnable) {
postTasks.add(runnable);
}

public int roundAmount() {
return GuiThemes.get().roundAmount();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package meteordevelopment.meteorclient.systems.modules.render.hud.modules;

import meteordevelopment.meteorclient.gui.GuiThemes;
import meteordevelopment.meteorclient.renderer.Renderer2D;
import meteordevelopment.meteorclient.settings.*;
import meteordevelopment.meteorclient.systems.modules.render.hud.HUD;
Expand Down Expand Up @@ -99,7 +100,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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,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);
}

Expand Down