diff --git a/build.gradle b/build.gradle index ac1ac6e..b6f4027 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,20 @@ plugins { - id 'fabric-loom' version '1.9-SNAPSHOT' + id 'fabric-loom' version '1.10-SNAPSHOT' id 'maven-publish' } +version = project.mod_version +group = project.maven_group + +base { + archivesName = project.archives_base_name +} + allprojects { apply plugin: "java" apply plugin: "maven-publish" archivesBaseName = rootProject.archives_base_name - version = rootProject.mod_version - group = rootProject.maven_group } repositories { @@ -23,7 +28,6 @@ repositories { name 'Xander Maven' url 'https://maven.isxander.dev/releases' } - maven { url "https://maven.terraformersmc.com/releases" } } dependencies { @@ -38,14 +42,17 @@ dependencies { processResources { inputs.property "version", project.version - inputs.property "minecraft_version", project.minecraft_version inputs.property "loader_version", project.loader_version - filteringCharset "UTF-8" + inputs.property "minecraft_version", project.minecraft_version + inputs.property "yacl_version", project.yacl_version filesMatching("fabric.mod.json") { - expand "version": project.version, - "minecraft_version": project.minecraft_version, - "loader_version": project.loader_version + expand([ + "version": inputs.properties.version, + "loader_version": inputs.properties.loader_version, + "minecraft_version": inputs.properties.minecraft_version, + "yacl_version": inputs.properties.yacl_version + ]) } } @@ -65,8 +72,10 @@ java { } jar { + inputs.property "archivesName", project.base.archivesName + from("LICENSE") { - rename { "${it}_${project.archivesBaseName}"} + rename { "${it}_${inputs.properties.archivesName}"} } } diff --git a/gradle.properties b/gradle.properties index df1ba47..d78b830 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,16 +4,16 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21.4 -yarn_mappings=1.21.4+build.1 -loader_version=0.16.9 +minecraft_version=1.21.5 +yarn_mappings=1.21.5+build.1 +loader_version=0.16.10 # Mod Properties # need versioning system -mod_version = 3.0.0 +mod_version = 3.1.0 maven_group = com.tanishisherewith archives_base_name = dynamichud # Dependencies -fabric_version=0.111.0+1.21.4 -yacl_version=3.6.6+1.21.4-fabric \ No newline at end of file +fabric_version=0.119.5+1.21.5 +yacl_version=3.6.6+1.21.5-fabric \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4eaec46..9bf7bd3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68..0e21a34 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -83,10 +85,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +133,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +147,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +200,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -241,4 +248,4 @@ eval "set -- $( tr '\n' ' ' )" '"$@"' -exec "$JAVACMD" "$@" +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..f46bb52 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -89,4 +91,4 @@ exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega +:omega \ No newline at end of file diff --git a/src/main/java/com/tanishisherewith/dynamichud/DynamicHUD.java b/src/main/java/com/tanishisherewith/dynamichud/DynamicHUD.java index ef01878..7021a07 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/DynamicHUD.java +++ b/src/main/java/com/tanishisherewith/dynamichud/DynamicHUD.java @@ -1,11 +1,14 @@ package com.tanishisherewith.dynamichud; import com.tanishisherewith.dynamichud.config.GlobalConfig; +import com.tanishisherewith.dynamichud.helpers.MouseColorQuery; import com.tanishisherewith.dynamichud.integration.IntegrationManager; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; import net.minecraft.client.MinecraftClient; import org.slf4j.Logger; @@ -35,6 +38,7 @@ public void onInitializeClient() { IntegrationManager.integrate(); //In game screen render. - HudRenderCallback.EVENT.register(new HudRender()); + HudLayerRegistrationCallback.EVENT.register(new HudRender()); + ClientTickEvents.END_CLIENT_TICK.register(mc-> MouseColorQuery.processIfPending()); } } diff --git a/src/main/java/com/tanishisherewith/dynamichud/HudRender.java b/src/main/java/com/tanishisherewith/dynamichud/HudRender.java index 63ae883..f7abd75 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/HudRender.java +++ b/src/main/java/com/tanishisherewith/dynamichud/HudRender.java @@ -2,20 +2,29 @@ import com.tanishisherewith.dynamichud.integration.IntegrationManager; import com.tanishisherewith.dynamichud.widget.WidgetRenderer; +import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer; +import net.fabricmc.fabric.api.client.rendering.v1.LayeredDrawerWrapper; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.util.Identifier; /** - * Using the fabric event {@link HudRenderCallback} to render widgets in the game HUD. + * Using the fabric event {@link HudLayerRegistrationCallback} to render widgets in the game HUD. * Mouse positions are passed in the negatives even though theoretically it's in the centre of the screen. */ -public class HudRender implements HudRenderCallback { - +public class HudRender implements HudLayerRegistrationCallback { @Override - public void onHudRender(DrawContext drawContext, RenderTickCounter tickCounter) { - for (WidgetRenderer widgetRenderer : IntegrationManager.getWidgetRenderers()) { - widgetRenderer.renderWidgets(drawContext, -120, -120); - } + public void register(LayeredDrawerWrapper layeredDrawer) { + layeredDrawer.attachLayerAfter( + IdentifiedLayer.MISC_OVERLAYS, + IdentifiedLayer.of(Identifier.of("dynamichud","hudrender_callback"), + (context, tickCounter) -> { + for (WidgetRenderer widgetRenderer : IntegrationManager.getWidgetRenderers()) { + widgetRenderer.renderWidgets(context, -120, -120); + } + }) + ); } } diff --git a/src/main/java/com/tanishisherewith/dynamichud/helpers/ColorHelper.java b/src/main/java/com/tanishisherewith/dynamichud/helpers/ColorHelper.java index a564ad9..3e39197 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/helpers/ColorHelper.java +++ b/src/main/java/com/tanishisherewith/dynamichud/helpers/ColorHelper.java @@ -1,9 +1,11 @@ package com.tanishisherewith.dynamichud.helpers; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gl.Framebuffer; import net.minecraft.client.util.Window; import net.minecraft.util.math.MathHelper; +import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL30; @@ -174,47 +176,8 @@ public static Color changeAlpha(Color color, int alpha) { return new Color(0); } - public static int[] getMousePixelColor(double mouseX, double mouseY) { - MinecraftClient client = MinecraftClient.getInstance(); - Framebuffer framebuffer = client.getFramebuffer(); - Window window = client.getWindow(); - - // Get the window and framebuffer dimensions - int windowWidth = window.getWidth(); - int windowHeight = window.getHeight(); - int framebufferWidth = framebuffer.textureWidth; - int framebufferHeight = framebuffer.textureHeight; - - // Calculate scaling factors - double scaleX = (double) framebufferWidth / windowWidth; - double scaleY = (double) framebufferHeight / windowHeight; - - // Convert mouse coordinates to framebuffer coordinates - int x = (int) (mouseX * scaleX); - int y = (int) ((windowHeight - mouseY) * scaleY); - - // Ensure the coordinates are within the framebuffer bounds - if (x < 0 || x >= framebufferWidth || y < 0 || y >= framebufferHeight) { - System.err.println("Mouse coordinates are out of bounds"); - return null; - } - - // Allocate a buffer to store the pixel data - ByteBuffer buffer = ByteBuffer.allocateDirect(4); // 4 bytes for RGBA - - // Bind the framebuffer for reading - GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.fbo); - - // Read the pixel at the mouse position - GL11.glReadPixels(x, y, 1, 1, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); - - // Extract the color components from the buffer - int red = buffer.get(0) & 0xFF; - int green = buffer.get(1) & 0xFF; - int blue = buffer.get(2) & 0xFF; - int alpha = buffer.get(3) & 0xFF; - - return new int[]{red, green, blue, alpha}; + public static Color changeAlpha(int color, int alpha) { + return changeAlpha(new Color(color),alpha); } public static int fromRGBA(int r, int g, int b, int a) { diff --git a/src/main/java/com/tanishisherewith/dynamichud/helpers/DrawHelper.java b/src/main/java/com/tanishisherewith/dynamichud/helpers/DrawHelper.java index bbf0b4a..0d26f32 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/helpers/DrawHelper.java +++ b/src/main/java/com/tanishisherewith/dynamichud/helpers/DrawHelper.java @@ -1,21 +1,22 @@ package com.tanishisherewith.dynamichud.helpers; -import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.ProjectionType; import com.mojang.blaze3d.systems.RenderSystem; import com.tanishisherewith.dynamichud.DynamicHUD; +import com.tanishisherewith.dynamichud.internal.IRenderLayer; +import com.tanishisherewith.dynamichud.utils.CustomRenderLayers; import com.tanishisherewith.dynamichud.widget.WidgetBox; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gl.ShaderProgramKeys; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.*; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.util.math.Vector2f; import net.minecraft.text.Text; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL40; +import org.joml.Vector4f; import org.lwjgl.opengl.GL40C; import java.awt.*; @@ -31,7 +32,6 @@ public class DrawHelper { /** * Draws a singular gradient rectangle on screen with the given parameters * - * @param matrix4f Matrix4f object to draw the gradient * @param x X position of the gradient * @param y Y position of the gradient * @param width Width of the gradient @@ -40,55 +40,38 @@ public class DrawHelper { * @param endColor end color of the gradient * @param direction Draws the gradient in the given direction */ - public static void drawGradient(Matrix4f matrix4f, float x, float y, float width, float height, int startColor, int endColor, Direction direction) { - float startRed = (float) (startColor >> 16 & 255) / 255.0F; - float startGreen = (float) (startColor >> 8 & 255) / 255.0F; - float startBlue = (float) (startColor & 255) / 255.0F; - float startAlpha = (float) (startColor >> 24 & 255) / 255.0F; - - float endRed = (float) (endColor >> 16 & 255) / 255.0F; - float endGreen = (float) (endColor >> 8 & 255) / 255.0F; - float endBlue = (float) (endColor & 255) / 255.0F; - float endAlpha = (float) (endColor >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); - - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - - switch (direction) { - case LEFT_RIGHT: - bufferBuilder.vertex(matrix4f, x, y + height, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x + width, y + height, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x + width, y, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x, y, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - break; - case TOP_BOTTOM: - bufferBuilder.vertex(matrix4f, x, y + height, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x + width, y + height, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x + width, y, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x, y, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - break; - case RIGHT_LEFT: - bufferBuilder.vertex(matrix4f, x, y + height, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x + width, y + height, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x + width, y, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x, y, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - break; - case BOTTOM_TOP: - bufferBuilder.vertex(matrix4f, x, y + height, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x + width, y + height, 0.0F).color(startRed, startGreen, startBlue, startAlpha); - bufferBuilder.vertex(matrix4f, x + width, y, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - bufferBuilder.vertex(matrix4f, x, y, 0.0F).color(endRed, endGreen, endBlue, endAlpha); - break; - } - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - - RenderSystem.disableBlend(); + public static void drawGradient(DrawContext drawContext, float x, float y, float width, float height, int startColor, int endColor, Direction direction) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugQuads()); + + switch (direction) { + case LEFT_RIGHT: + consumer.vertex(matrix4f, x, y + height, 0.0F).color(startColor); + consumer.vertex(matrix4f, x + width, y + height, 0.0F).color(endColor); + consumer.vertex(matrix4f, x + width, y, 0.0F).color(endColor); + consumer.vertex(matrix4f, x, y, 0.0F).color(startColor); + break; + case TOP_BOTTOM: + consumer.vertex(matrix4f, x, y + height, 0.0F).color(endColor); + consumer.vertex(matrix4f, x + width, y + height, 0.0F).color(endColor); + consumer.vertex(matrix4f, x + width, y, 0.0F).color(startColor); + consumer.vertex(matrix4f, x, y, 0.0F).color(startColor); + break; + case RIGHT_LEFT: + consumer.vertex(matrix4f, x, y + height, 0.0F).color(endColor); + consumer.vertex(matrix4f, x + width, y + height, 0.0F).color(startColor); + consumer.vertex(matrix4f, x + width, y, 0.0F).color(startColor); + consumer.vertex(matrix4f, x, y, 0.0F).color(endColor); + break; + case BOTTOM_TOP: + consumer.vertex(matrix4f, x, y + height, 0.0F).color(startColor); + consumer.vertex(matrix4f, x + width, y + height, 0.0F).color(startColor); + consumer.vertex(matrix4f, x + width, y, 0.0F).color(endColor); + consumer.vertex(matrix4f, x, y, 0.0F).color(endColor); + break; + } + }); } public static void enableScissor(int x, int y, int width, int height) { @@ -115,37 +98,22 @@ public static void disableScissor() { /** * Draws a singular rectangle on screen with the given parameters * - * @param matrix4f Matrix4f object to draw the rectangle * @param x X position of the rectangle * @param y Y position of the rectangle * @param width Width of the rectangle * @param height Height of the rectangle * @param color Color of the rectangle */ - public static void drawRectangle(Matrix4f matrix4f, float x, float y, float width, float height, int color) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); - - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - - tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); - - bufferBuilder.vertex(matrix4f, x, y + height, 0.0F).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x + width, y + height, 0.0F).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x + width, y, 0.0F).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x, y, 0.0F).color(red, green, blue, alpha); + public static void drawRectangle(DrawContext drawContext, float x, float y, float width, float height, int color) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugQuads()); - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - - RenderSystem.disableBlend(); + consumer.vertex(matrix4f, x, y + height, 0.0F).color(color); + consumer.vertex(matrix4f, x + width, y + height, 0.0F).color(color); + consumer.vertex(matrix4f, x + width, y, 0.0F).color(color); + consumer.vertex(matrix4f, x, y, 0.0F).color(color); + }); } /* ==== Drawing Rectangles ==== */ @@ -153,25 +121,23 @@ public static void drawRectangle(Matrix4f matrix4f, float x, float y, float widt /** * Draws a singular outline rectangle on screen with the given parameters * - * @param matrix4f Matrix4f object to draw the rectangle * @param x X position of the rectangle * @param y Y position of the rectangle * @param width Width of the rectangle * @param height Height of the rectangle * @param color Color of the rectangle */ - public static void drawOutlineBox(Matrix4f matrix4f, float x, float y, float width, float height, float thickness, int color) { - drawRectangle(matrix4f, x, y, width, thickness, color); - drawRectangle(matrix4f, x, y + height - thickness, width, thickness, color); - drawRectangle(matrix4f, x, y + thickness, thickness, height - thickness * 2, color); - drawRectangle(matrix4f, x + width - thickness, y + thickness, thickness, height - thickness * 2, color); + public static void drawOutlineBox(DrawContext drawContext, float x, float y, float width, float height, float thickness, int color) { + drawRectangle(drawContext, x, y, width, thickness, color); + drawRectangle(drawContext, x, y + height - thickness, width, thickness, color); + drawRectangle(drawContext, x, y + thickness, thickness, height - thickness * 2, color); + drawRectangle(drawContext, x + width - thickness, y + thickness, thickness, height - thickness * 2, color); } /** * Draws a singular rectangle with a dark shadow on screen with the given parameters * Bad way because there is a better way * - * @param matrix4f Matrix4f object to draw the rectangle and shadow * @param x X position of the rectangle * @param y Y position of the rectangle * @param width Width of the rectangle @@ -181,79 +147,47 @@ public static void drawOutlineBox(Matrix4f matrix4f, float x, float y, float wid * @param shadowOffsetX X position Offset of the shadow from the main rectangle X pos * @param shadowOffsetY Y position Offset of the shadow from the main rectangle Y pos */ - public static void drawRectangleWithShadowBadWay(Matrix4f matrix4f, float x, float y, float width, float height, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { + public static void drawRectangleWithShadowBadWay(DrawContext drawContext, float x, float y, float width, float height, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { // First, render the shadow - drawRectangle(matrix4f, x + shadowOffsetX, y + shadowOffsetY, width, height, ColorHelper.getColor(0, 0, 0, shadowOpacity)); + drawRectangle(drawContext, x + shadowOffsetX, y + shadowOffsetY, width, height, ColorHelper.getColor(0, 0, 0, shadowOpacity)); // Then, render the rectangle - drawRectangle(matrix4f, x, y, width, height, color); + drawRectangle(drawContext, x, y, width, height, color); } /** - * Draws an outline rounded rectangle by drawing 4 side rectangles, and 4 arcs + * Draws an outline rounded rectangle * - * @param matrix4f Matrix4f object to draw the rounded rectangle * @param x X pos * @param y Y pos - * @param width Width of rounded rectangle - * @param height Height of rounded rectangle - * @param radius Radius of the quadrants / the rounded rectangle - * @param color Color of the rounded rectangle + * @param width Width of rounded.fsh rectangle + * @param height Height of rounded.fsh rectangle + * @param radius Radius of the quadrants / the rounded.fsh rectangle + * @param color Color of the rounded.fsh rectangle * @param thickness thickness of the outline */ - public static void drawOutlineRoundedBox(Matrix4f matrix4f, float x, float y, float width, float height, float radius, float thickness, int color) { - // Draw the rectangles for the outline - drawRectangle(matrix4f, x + radius, y, width - radius * 2, thickness, color); // Top rectangle - drawRectangle(matrix4f, x + radius, y + height - thickness, width - radius * 2, thickness, color); // Bottom rectangle - drawRectangle(matrix4f, x, y + radius, thickness, height - radius * 2, color); // Left rectangle - drawRectangle(matrix4f, x + width - thickness, y + radius, thickness, height - radius * 2, color); // Right rectangle - - // Draw the arcs at the corners for the outline - drawArc(matrix4f, x + radius, y + radius, radius, thickness, color, 180, 270); // Top-left arc - drawArc(matrix4f, x + width - radius, y + radius, radius, thickness, color, 90, 180); // Top-right arc - drawArc(matrix4f, x + width - radius, y + height - radius, radius, thickness, color, 0, 90); // Bottom-right arc - drawArc(matrix4f, x + radius, y + height - radius, radius, thickness, color, 270, 360); // Bottom-left arc - } - - public static void drawRainbowGradientRectangle(Matrix4f matrix4f, float x, float y, float width, float height, float alpha) { - BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); - - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - - for (int i = 0; i <= width; i++) { - float hue = (float) i / width; - int color = Color.HSBtoRGB(hue, 1.0f, 1.0f); - color = (color & 0x00FFFFFF) | ((int) (alpha * 255) << 24); - - float red = (color >> 16 & 255) / 255.0F; - float green = (color >> 8 & 255) / 255.0F; - float blue = (color & 255) / 255.0F; - float alphaVal = (color >> 24 & 255) / 255.0F; - - bufferBuilder.vertex(matrix4f, x + i, y, 0.0f).color(red, green, blue, alphaVal); - bufferBuilder.vertex(matrix4f, x + i, y + height, 0.0f).color(red, green, blue, alphaVal); - } - - for (int i = (int) width; i >= 0; i--) { - float hue = (float) i / width; - int color = Color.HSBtoRGB(hue, 1.0f, 1.0f); - color = (color & 0x00FFFFFF) | ((int) (alpha * 255) << 24); - - float red = (color >> 16 & 255) / 255.0F; - float green = (color >> 8 & 255) / 255.0F; - float blue = (color & 255) / 255.0F; - float alphaVal = (color >> 24 & 255) / 255.0F; - - bufferBuilder.vertex(matrix4f, x + i, y + height, 0.0f).color(red, green, blue, alphaVal); - bufferBuilder.vertex(matrix4f, x + i, y, 0.0f).color(red, green, blue, alphaVal); - } - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - - RenderSystem.disableBlend(); + public static void drawOutlineRoundedBox(DrawContext drawContext, float x, float y, float width, float height, float radius, float thickness, int color) { + Color c = new Color(color, true); + drawOutlineRoundedBox(drawContext,x,y,width,height,new Vector4f(radius),thickness,c,c,c,c); + } + + public static void drawOutlineRoundedBox(DrawContext drawContext, float x, float y, float width, float height, Vector4f radii, float thickness, Color tl, Color tr, Color br, Color bl) { + if (width <= 0 || height <= 0) return; + float maxRadius = Math.min(width, height) / 2; + radii.set(Math.min(radii.x, maxRadius), // top-left + Math.min(radii.y, maxRadius), // top-right + Math.min(radii.z, maxRadius), // bottom-right + Math.min(radii.w, maxRadius) // bottom-left + ); + drawContext.draw(vcp -> { + VertexConsumer dvc = vcp.getBuffer(CustomRenderLayers.ROUNDED_RECT_OUTLINE.apply(new CustomRenderLayers.OutlineParameters(radii, thickness ,new float[]{width, height}))); + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + + dvc.vertex(matrix4f, x, y + height, 0).texture(0, 0).color(bl.getRGB()); + dvc.vertex(matrix4f, x + width, y + height, 0).texture(width, 0).color(br.getRGB()); + dvc.vertex(matrix4f, x + width, y, 0).texture(width, height).color(tr.getRGB()); + dvc.vertex(matrix4f, x, y, 0).texture(0, height).color(tl.getRGB()); + }); } /** @@ -286,115 +220,59 @@ public static void drawChromaText(@NotNull DrawContext drawContext, String text, } - public static void drawRainbowGradient(float x, float y, float width, float height) { - Matrix4f matrix4f = RenderSystem.getModelViewMatrix(); - - RenderSystem.enableBlend(); - RenderSystem.colorMask(false, false, false, true); - RenderSystem.clearColor(0.0F, 0.0F, 0.0F, 0.0F); - RenderSystem.clear(GL40C.GL_COLOR_BUFFER_BIT); - RenderSystem.colorMask(true, true, true, true); - - drawRectangle(matrix4f, x, y, width, height, Color.BLACK.getRGB()); - - RenderSystem.blendFunc(GL40C.GL_DST_ALPHA, GL40C.GL_ONE_MINUS_DST_ALPHA); - - RenderSystem.enableBlend(); - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - - BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); - for (float i = 0; i < width; i += 1.0f) { - float hue = (i / width); // Multiply by 1 to go through the whole color spectrum once (red to red) - Color color = Color.getHSBColor(hue, 1.0f, 1.0f); // Full saturation and brightness - - bufferBuilder.vertex(matrix4f, x + i, y, 0.0F).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); - bufferBuilder.vertex(matrix4f, x + i + 1.0f, y, 0.0F).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); - bufferBuilder.vertex(matrix4f, x + i + 1.0f, y + height, 0.0F).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); - bufferBuilder.vertex(matrix4f, x + i, y + height, 0.0F).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); - } - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); - - RenderSystem.defaultBlendFunc(); - } - /* ==== Drawing filled and outline circles ==== */ /** * Draws an outline of a circle * - * @param matrix4f Matrix4f object to draw the circle outline * @param xCenter X position of the circle outline * @param yCenter Y position of the circle outline * @param radius radius of the circle outline * @param color color of the circle outline */ - public static void drawOutlineCircle(Matrix4f matrix4f, float xCenter, float yCenter, float radius, float lineWidth, int color) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - - for (int i = 0; i <= 360; i++) { - double x = xCenter + Math.sin(Math.toRadians(i)) * radius; - double y = yCenter + Math.cos(Math.toRadians(i)) * radius; - double x2 = xCenter + Math.sin(Math.toRadians(i)) * (radius + lineWidth); - double y2 = yCenter + Math.cos(Math.toRadians(i)) * (radius + lineWidth); - bufferBuilder.vertex(matrix4f, (float) x, (float) y, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, (float) x2, (float) y2, 0).color(red, green, blue, alpha); - } - - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); + public static void drawOutlineCircle(DrawContext drawContext, float xCenter, float yCenter, float radius, float lineWidth, int color) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugLineStrip(lineWidth)); + + for (int i = 0; i <= 360; i++) { + double x = xCenter + Math.sin(Math.toRadians(i)) * radius; + double y = yCenter + Math.cos(Math.toRadians(i)) * radius; + double x2 = xCenter + Math.sin(Math.toRadians(i)) * (radius + lineWidth); + double y2 = yCenter + Math.cos(Math.toRadians(i)) * (radius + lineWidth); + consumer.vertex(matrix4f, (float) x, (float) y, 0).color(color); + consumer.vertex(matrix4f, (float) x2, (float) y2, 0).color(color); + } + }); } /** * Draws a filled circle * - * @param matrix4f Matrix4f object to draw the circle outline * @param xCenter X position of the circle outline * @param yCenter Y position of the circle outline * @param radius radius of the circle outline * @param color color of the circle outline */ - public static void drawFilledCircle(Matrix4f matrix4f, float xCenter, float yCenter, float radius, int color) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); - - - bufferBuilder.vertex(matrix4f, xCenter, yCenter, 0).color(red, green, blue, alpha); + public static void drawFilledCircle(DrawContext drawContext, float xCenter, float yCenter, float radius, int color) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugTriangleFan()); - for (int i = 0; i <= 360; i++) { - double x = xCenter + Math.sin(Math.toRadians(i)) * radius; - double y = yCenter + Math.cos(Math.toRadians(i)) * radius; - bufferBuilder.vertex(matrix4f, (float) x, (float) y, 0).color(red, green, blue, alpha); - } + consumer.vertex(matrix4f, xCenter, yCenter, 0).color(color); - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + for (int i = 0; i <= 360; i++) { + double x = xCenter + Math.sin(Math.toRadians(i)) * radius; + double y = yCenter + Math.cos(Math.toRadians(i)) * radius; + consumer.vertex(matrix4f, (float) x, (float) y, 0).color(color); + } + }); } /** * Draws a filled circle with a shadow bad way * - * @param matrix4f Matrix4f object to draw the circle * @param xCenter X position of the circle * @param yCenter Y position of the circle * @param radius Radius of the circle @@ -403,18 +281,17 @@ public static void drawFilledCircle(Matrix4f matrix4f, float xCenter, float yCen * @param shadowOffsetY X position of the circle shadow offset from main circle * @param shadowOpacity Opacity of the circle shadow offset from main circle */ - public static void drawCircleWithShadow(Matrix4f matrix4f, float xCenter, float yCenter, float radius, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { + public static void drawCircleWithShadow(DrawContext drawContext, float xCenter, float yCenter, float radius, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { // First, render the shadow - drawFilledCircle(matrix4f, xCenter + shadowOffsetX, yCenter + shadowOffsetY, radius, ColorHelper.getColor(0, 0, 0, shadowOpacity)); + drawFilledCircle(drawContext, xCenter + shadowOffsetX, yCenter + shadowOffsetY, radius, ColorHelper.getColor(0, 0, 0, shadowOpacity)); // Then, render the circle - drawFilledCircle(matrix4f, xCenter, yCenter, radius, color); + drawFilledCircle(drawContext, xCenter, yCenter, radius, color); } /** * Not Tested * - * @param matrix4f * @param x * @param y * @param radius @@ -423,38 +300,28 @@ public static void drawCircleWithShadow(Matrix4f matrix4f, float xCenter, float * @param color */ @Deprecated - public static void drawFilledArc(Matrix4f matrix4f, float x, float y, float radius, float startAngle, float endAngle, int color) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - RenderSystem.enableBlend(); - - for (float angle = startAngle; angle <= endAngle; angle += 1.0F) { - float x1 = x + MathHelper.cos(angle * 0.017453292F) * radius; - float y1 = y + MathHelper.sin(angle * 0.017453292F) * radius; - float x2 = x + MathHelper.cos((angle + 1.0F) * 0.017453292F) * radius; - float y2 = y + MathHelper.sin((angle + 1.0F) * 0.017453292F) * radius; - - bufferBuilder.vertex(matrix4f, x, y, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x1, y1, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x2, y2, 0).color(red, green, blue, alpha); - } - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + public static void drawFilledArc(DrawContext drawContext, float x, float y, float radius, float startAngle, float endAngle, int color) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugLineStrip(1.0f)); + + for (float angle = startAngle; angle <= endAngle; angle += 1.0F) { + float x1 = x + MathHelper.cos(angle * 0.017453292F) * radius; + float y1 = y + MathHelper.sin(angle * 0.017453292F) * radius; + float x2 = x + MathHelper.cos((angle + 1.0F) * 0.017453292F) * radius; + float y2 = y + MathHelper.sin((angle + 1.0F) * 0.017453292F) * radius; + + consumer.vertex(matrix4f, x, y, 0).color(color); + consumer.vertex(matrix4f, x1, y1, 0).color(color); + consumer.vertex(matrix4f, x2, y2, 0).color(color); + } + }); } /* ==== Drawing Quadrants, Arcs, and Triangles ==== */ /** * Draws a filled Gradient quadrant * - * @param matrix4f Matrix4f object to draw the quadrant * @param xCenter X position of the quadrant * @param yCenter Y position of the quadrant * @param radius Radius of the quadrant @@ -462,7 +329,7 @@ public static void drawFilledArc(Matrix4f matrix4f, float x, float y, float radi * @param endColor end color of the gradient * @param quadrant Integer value of the quadrant of the circle. 1 == Top Right, 2 == Top Left, 3 == Bottom Right, 4 == Bottom Left */ - public static void drawFilledGradientQuadrant(Matrix4f matrix4f, float xCenter, float yCenter, float radius, int startColor, int endColor, int quadrant) { + public static void drawFilledGradientQuadrant(DrawContext drawContext, float xCenter, float yCenter, float radius, int startColor, int endColor, int quadrant) { float startRed = (float) (startColor >> 16 & 255) / 255.0F; float startGreen = (float) (startColor >> 8 & 255) / 255.0F; float startBlue = (float) (startColor & 255) / 255.0F; @@ -473,36 +340,31 @@ public static void drawFilledGradientQuadrant(Matrix4f matrix4f, float xCenter, float endBlue = (float) (endColor & 255) / 255.0F; float endAlpha = (float) (endColor >> 24 & 255) / 255.0F; - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - RenderSystem.enableBlend(); + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugTriangleFan()); - bufferBuilder.vertex(matrix4f, xCenter, yCenter, 0).color(startRed, startGreen, startBlue, startAlpha); + consumer.vertex(matrix4f, xCenter, yCenter, 0).color(startColor); - for (int i = quadrant * 90; i <= quadrant * 90 + 90; i++) { - double x = xCenter + Math.sin(Math.toRadians(i)) * radius; - double y = yCenter + Math.cos(Math.toRadians(i)) * radius; + for (int i = quadrant * 90; i <= quadrant * 90 + 90; i++) { + double x = xCenter + Math.sin(Math.toRadians(i)) * radius; + double y = yCenter + Math.cos(Math.toRadians(i)) * radius; - // Interpolate the color based on the angle - float t = (float) (i - quadrant * 90) / 90.0f; - float red = startRed * (1 - t) + endRed * t; - float green = startGreen * (1 - t) + endGreen * t; - float blue = startBlue * (1 - t) + endBlue * t; - float alpha = startAlpha * (1 - t) + endAlpha * t; + // Interpolate the color based on the angle + float t = (float) (i - quadrant * 90) / 90.0f; + float red = startRed * (1 - t) + endRed * t; + float green = startGreen * (1 - t) + endGreen * t; + float blue = startBlue * (1 - t) + endBlue * t; + float alpha = startAlpha * (1 - t) + endAlpha * t; - bufferBuilder.vertex(matrix4f, (float) x, (float) y, 0).color(red, green, blue, alpha); - } - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + consumer.vertex(matrix4f, (float) x, (float) y, 0).color(red,green,blue,alpha); + } + }); } /** * Draws an arc * - * @param matrix4f Matrix4f object to draw the arc * @param xCenter X position of the arc's center * @param yCenter Y position of the arc's center * @param radius Radius of the arc's center circle @@ -510,72 +372,50 @@ public static void drawFilledGradientQuadrant(Matrix4f matrix4f, float xCenter, * @param endAngle end Angle of the arc * @param thickness Thickness of the arc (width of the arc) */ - public static void drawArc(Matrix4f matrix4f, float xCenter, float yCenter, float radius, float thickness, int color, int startAngle, int endAngle) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - RenderSystem.enableBlend(); - - for (int i = startAngle; i <= endAngle; i++) { - double innerX = xCenter + Math.sin(Math.toRadians(i)) * (radius - thickness); - double innerY = yCenter + Math.cos(Math.toRadians(i)) * (radius - thickness); - double outerX = xCenter + Math.sin(Math.toRadians(i)) * radius; - double outerY = yCenter + Math.cos(Math.toRadians(i)) * radius; - - bufferBuilder.vertex(matrix4f, (float) innerX, (float) innerY, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, (float) outerX, (float) outerY, 0).color(red, green, blue, alpha); - } + public static void drawArc(DrawContext drawContext, float xCenter, float yCenter, float radius, float thickness, int color, int startAngle, int endAngle) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugTriangleFan()); - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); + for (int i = startAngle; i <= endAngle; i++) { + double innerX = xCenter + Math.sin(Math.toRadians(i)) * (radius - thickness); + double innerY = yCenter + Math.cos(Math.toRadians(i)) * (radius - thickness); + double outerX = xCenter + Math.sin(Math.toRadians(i)) * radius; + double outerY = yCenter + Math.cos(Math.toRadians(i)) * radius; - RenderSystem.disableBlend(); + consumer.vertex(matrix4f, (float) innerX, (float) innerY, 0).color(color); + consumer.vertex(matrix4f, (float) outerX, (float) outerY, 0).color(color); + } + }); } /** * Draws a filled quadrant * - * @param matrix4f Matrix4f object to draw the quadrant * @param xCenter X position of the quadrant * @param yCenter Y position of the quadrant * @param radius Radius of the quadrant * @param color color of the quadrant * @param quadrant Integer value of the quadrant of the circle. 1 == Top Right, 2 == Top Left, 3 == Bottom Right, 4 == Bottom Left */ - public static void drawFilledQuadrant(Matrix4f matrix4f, float xCenter, float yCenter, float radius, int color, int quadrant) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; + public static void drawFilledQuadrant(DrawContext drawContext, float xCenter, float yCenter, float radius, int color, int quadrant) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getDebugTriangleFan()); - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR); - - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - RenderSystem.enableBlend(); - - bufferBuilder.vertex(matrix4f, xCenter, yCenter, 0).color(red, green, blue, alpha); - - for (int i = quadrant * 90; i <= quadrant * 90 + 90; i++) { - double x = xCenter + Math.sin(Math.toRadians(i)) * radius; - double y = yCenter + Math.cos(Math.toRadians(i)) * radius; - bufferBuilder.vertex(matrix4f, (float) x, (float) y, 0).color(red, green, blue, alpha); - } - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + consumer.vertex(matrix4f, xCenter, yCenter, 0).color(color); + for (int i = quadrant * 90; i <= quadrant * 90 + 90; i++) { + double x = xCenter + Math.sin(Math.toRadians(i)) * radius; + double y = yCenter + Math.cos(Math.toRadians(i)) * radius; + consumer.vertex(matrix4f, (float) x, (float) y, 0).color(color); + } + }); } /** * Draws a Triangle with the given coordinates * - * @param matrix4f * @param x1 * @param y1 * @param x2 @@ -584,34 +424,28 @@ public static void drawFilledQuadrant(Matrix4f matrix4f, float xCenter, float yC * @param y3 * @param color */ - public static void drawOutlineTriangle(Matrix4f matrix4f, int x1, int y1, int x2, int y2, int x3, int y3, int color) { - float red = (float) (color >> 16 & 255) / 255.0F; - float green = (float) (color >> 8 & 255) / 255.0F; - float blue = (float) (color & 255) / 255.0F; - float alpha = (float) (color >> 24 & 255) / 255.0F; - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINES, VertexFormats.POSITION_COLOR); + public static void drawOutlineTriangle(DrawContext drawContext, int x1, int y1, int x2, int y2, int x3, int y3, int color) { + drawContext.draw(vcp -> { + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(RenderLayer.getLines()); - bufferBuilder.vertex(matrix4f, x1, y1, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x2, y2, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x3, y3, 0).color(red, green, blue, alpha); - bufferBuilder.vertex(matrix4f, x1, y1, 0).color(red, green, blue, alpha); - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); + consumer.vertex(matrix4f, x1, y1, 0).color(color); + consumer.vertex(matrix4f, x2, y2, 0).color(color); + consumer.vertex(matrix4f, x3, y3, 0).color(color); + consumer.vertex(matrix4f, x1, y1, 0).color(color); + }); } /** * Draws a outline quadrant * - * @param matrix4f Matrix4f object to draw the quadrant * @param xCenter X position of the quadrant * @param yCenter Y position of the quadrant * @param radius Radius of the quadrant * @param color color of the quadrant * @param quadrant Integer value of the quadrant of the circle. 1 == Top Right, 2 == Top Left, 3 == Bottom Right, 4 == Bottom Left */ - public static void drawOutlineQuadrant(Matrix4f matrix4f, float xCenter, float yCenter, float radius, int quadrant, int color) { + public static void drawOutlineQuadrant(DrawContext drawContext, float xCenter, float yCenter, float radius, int quadrant, int color) { int startAngle = 0; int endAngle = 0; @@ -628,100 +462,93 @@ public static void drawOutlineQuadrant(Matrix4f matrix4f, float xCenter, float y endAngle = 90; } - drawArc(matrix4f, xCenter, yCenter, radius, 1f, color, startAngle, endAngle); + drawArc(drawContext, xCenter, yCenter, radius, 1f, color, startAngle, endAngle); } /** - * Draws a filled rounded rectangle by drawing 1 main rectangle, 4 side rectangles, and 4 filled quadrants + * Draws a filled rounded.fsh rectangle by drawing 1 main rectangle, 4 side rectangles, and 4 filled quadrants * - * @param matrix4f Matrix4f object to draw the rounded rectangle * @param x X pos * @param y Y pos - * @param width Width of rounded rectangle - * @param height Height of rounded rectangle - * @param radius Radius of the quadrants / the rounded rectangle - * @param color Color of the rounded rectangle + * @param width Width of rounded.fsh rectangle + * @param height Height of rounded.fsh rectangle + * @param radius Radius of the quadrants / the rounded.fsh rectangle + * @param color Color of the rounded.fsh rectangle */ - public static void drawRoundedRectangle(Matrix4f matrix4f, float x, float y, float width, float height, float radius, int color) { - drawRoundedRectangle(matrix4f, x, y, true, true, true, true, width, height, radius, color); + public static void drawRoundedRectangle(DrawContext drawContext, float x, float y, float width, float height, float radius, int color) { + drawRoundedRectangle(drawContext, x, y, true, true, true, true, width, height, radius, color); } /* ==== Drawing Rounded Rectangles ==== */ /** - * Draws a filled rounded rectangle by drawing 1 main rectangle, 4 side rectangles, and specified filled quadrants + * Draws a filled rounded.fsh rectangle by drawing 1 main rectangle, 4 side rectangles, and specified filled quadrants * - * @param matrix4f Matrix4f object to draw the rounded rectangle * @param x X pos * @param y Y pos * @param TL Whether to draw the top left quadrant * @param TR Whether to draw the top right quadrant * @param BL Whether to draw the bottom left quadrant * @param BR Whether to draw the bottom right quadrant - * @param width Width of rounded rectangle - * @param height Height of rounded rectangle - * @param radius Radius of the quadrants / the rounded rectangle - * @param color Color of the rounded rectangle + * @param width Width of rounded.fsh rectangle + * @param height Height of rounded.fsh rectangle + * @param radius Radius of the quadrants / the rounded.fsh rectangle + * @param color Color of the rounded.fsh rectangle */ - public static void drawRoundedRectangle(Matrix4f matrix4f, float x, float y, boolean TL, boolean TR, boolean BL, boolean BR, float width, float height, float radius, int color) { - // Draw the main rectangle - drawRectangle(matrix4f, x + radius, y + radius, width - 2 * radius, height - 2 * radius, color); - - // Draw rectangles at the sides - drawRectangle(matrix4f, x + radius, y, width - 2 * radius, radius, color); // top - drawRectangle(matrix4f, x + radius, y + height - radius, width - 2 * radius, radius, color); // bottom - drawRectangle(matrix4f, x, y + radius, radius, height - 2 * radius, color); // left - drawRectangle(matrix4f, x + width - radius, y + radius, radius, height - 2 * radius, color); // right - - if (TL) { - drawFilledQuadrant(matrix4f, x + radius, y + radius, radius, color, 2); - } else { - drawRectangle(matrix4f, x, y, radius, radius, color); - } - if (TR) { - drawFilledQuadrant(matrix4f, x + width - radius, y + radius, radius, color, 1); - } else { - drawRectangle(matrix4f, x + width - radius, y, radius, radius, color); - } - if (BL) { - drawFilledQuadrant(matrix4f, x + radius, y + height - radius, radius, color, 3); - } else { - drawRectangle(matrix4f, x, y + height - radius, radius, radius, color); - } - if (BR) { - drawFilledQuadrant(matrix4f, x + width - radius, y + height - radius, radius, color, 4); - } else { - drawRectangle(matrix4f, x + width - radius, y + height - radius, radius, radius, color); - } + public static void drawRoundedRectangle(DrawContext drawContext, float x, float y, boolean TL, boolean TR, boolean BL, boolean BR, float width, float height, float radius, int color) { + Vector4f radii = new Vector4f(TR ? radius : 0.0f, BR ? radius : 0.0f, TL ? radius : 0.0f, BL ? radius : 0.0f); + + // Turns out Color class takes rgb by default not rgba + Color c = new Color(color, true); + drawRoundedRectangle(drawContext,x,y,width, height, radii, c,c,c,c); + } + + /** + * Draws a rounded rectangle with customizable corner radii, corner colors, and selective corner rounding. + * @param drawContext DrawContext for rendering + * @param x X position + * @param y Y position + * + * + * @param width Width of the rectangle + * @param height Height of the rectangle + * @param radii Vector4f specifying radii for top-left, top-right, bottom-right, bottom-left corners + */ + public static void drawRoundedRectangle(DrawContext drawContext, float x, float y, float width, float height, + Vector4f radii, Color tl, Color tr, Color br, Color bl) { + if (width <= 0 || height <= 0) return; + float maxRadius = Math.min(width, height) / 2; + radii.set(Math.min(radii.x, maxRadius), // top-left + Math.min(radii.y, maxRadius), // top-right + Math.min(radii.z, maxRadius), // bottom-right + Math.min(radii.w, maxRadius) // bottom-left + ); + drawContext.draw(vcp -> { + VertexConsumer dvc = vcp.getBuffer(CustomRenderLayers.ROUNDED_RECT.apply(new CustomRenderLayers.RoundedParameters(radii, new float[]{width, height}))); + Matrix4f matrix4f = drawContext.getMatrices().peek().getPositionMatrix(); + + dvc.vertex(matrix4f, x, y + height, 0).texture(0, 0).color(bl.getRGB()); + dvc.vertex(matrix4f, x + width, y + height, 0).texture(width, 0).color(br.getRGB()); + dvc.vertex(matrix4f, x + width, y, 0).texture(width, height).color(tr.getRGB()); + dvc.vertex(matrix4f, x, y, 0).texture(0, height).color(tl.getRGB()); + }); } /** - * Draws an outline rounded gradient rectangle + * Draws an outline rounded.fsh gradient rectangle * - * @param matrix4f Matrix4f object to draw the rounded gradient rectangle - * @param color1 is applied to the bottom-left vertex (x, y + height). - * @param color2 is applied to the bottom-right vertex (x + width, y + height). - * @param color3 is applied to the top-right vertex (x + width, y). - * @param color4 is applied to the top-left vertex (x, y). + * @param tl is applied to the top-left vertex (x, y). + * @param tr is applied to the top-right vertex (x + width, y). + * @param br is applied to the bottom-right vertex (x + width, y + height). + * @param bl is applied to the bottom-left vertex (x, y + height). * @param x X pos * @param y Y pos - * @param width Width of rounded gradient rectangle - * @param height Height of rounded gradient rectangle - * @param radius Radius of the quadrants / the rounded gradient rectangle + * @param width Width of rounded.fsh gradient rectangle + * @param height Height of rounded.fsh gradient rectangle + * @param radius Radius of the quadrants / the rounded.fsh gradient rectangle */ - public static void drawOutlineGradientRoundedBox(Matrix4f matrix4f, float x, float y, float width, float height, float radius, float thickness, Color color1, Color color2, Color color3, Color color4) { - // Draw the rectangles for the outline with gradient - drawGradient(matrix4f, x + radius, y, width - radius * 2, thickness, color1.getRGB(), color2.getRGB(), Direction.LEFT_RIGHT); // Top rectangle - drawGradient(matrix4f, x + radius, y + height - thickness, width - radius * 2, thickness, color3.getRGB(), color4.getRGB(), Direction.RIGHT_LEFT); // Bottom rectangle - - drawGradient(matrix4f, x, y + radius, thickness, height - radius * 2, color4.getRGB(), color1.getRGB(), Direction.BOTTOM_TOP); // Left rectangle - drawGradient(matrix4f, x + width - thickness, y + radius, thickness, height - radius * 2, color2.getRGB(), color3.getRGB(), Direction.TOP_BOTTOM); // Right rectangle - - // Draw the arcs at the corners for the outline with gradient - drawArc(matrix4f, x + radius, y + radius, radius, thickness, color1.getRGB(), 180, 270); // Top-left arc - drawArc(matrix4f, x + width - radius, y + radius, radius, thickness, color2.getRGB(), 90, 180); // Top-right arc - drawArc(matrix4f, x + width - radius, y + height - radius, radius, thickness, color3.getRGB(), 0, 90); // Bottom-right arc - drawArc(matrix4f, x + radius, y + height - radius, radius, thickness, color4.getRGB(), 270, 360); // Bottom-left arc + public static void drawOutlineGradientRoundedBox(DrawContext drawContext, float x, float y, float width, float height, float radius, float thickness, Color tl, Color tr, Color br, Color bl) { + drawOutlineRoundedBox(drawContext,x,y,width,height,new Vector4f(radius),thickness,tl, tr, br,bl); } public static void drawCutRectangle(DrawContext drawContext, int x1, int y1, int x2, int y2, int z, int color, int cornerRadius) { @@ -732,94 +559,69 @@ public static void drawCutRectangle(DrawContext drawContext, int x1, int y1, int } /** - * Draws a rounded rectangle with a shadow in a bad way + * Draws a rounded.fsh rectangle with a shadow in a bad way * - * @param matrix4f Matrix4f object to draw the rounded rectangle * @param x X pos * @param y Y pos - * @param width Width of rounded rectangle - * @param height Height of rounded rectangle - * @param radius Radius of the quadrants / the rounded rectangle - * @param color Color of the rounded rectangle + * @param width Width of rounded.fsh rectangle + * @param height Height of rounded.fsh rectangle + * @param radius Radius of the quadrants / the rounded.fsh rectangle + * @param color Color of the rounded.fsh rectangle * @param shadowOpacity opacity of the shadow * @param shadowOffsetX X offset of the shadow * @param shadowOffsetY Y offset of the shadow */ - public static void drawRoundedRectangleWithShadowBadWay(Matrix4f matrix4f, float x, float y, float width, float height, float radius, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { + public static void drawRoundedRectangleWithShadowBadWay(DrawContext drawContext, float x, float y, float width, float height, float radius, int color, int shadowOpacity, float shadowOffsetX, float shadowOffsetY) { // First, render the shadow - drawRoundedRectangle(matrix4f, x + shadowOffsetX, y + shadowOffsetY, width, height, radius, ColorHelper.getColor(0, 0, 0, shadowOpacity)); + drawRoundedRectangle(drawContext, x + shadowOffsetX, y + shadowOffsetY, width, height, radius, ColorHelper.getColor(0, 0, 0, shadowOpacity)); - // Then, render the rounded rectangle - drawRoundedRectangle(matrix4f, x, y, width, height, radius, color); + // Then, render the rounded.fsh rectangle + drawRoundedRectangle(drawContext, x, y, width, height, radius, color); } /** - * Draws a rounded gradient rectangle + * Draws a rounded.fsh gradient rectangle * - * @param matrix Matrix4f object to draw the rounded gradient rectangle - * @param color1 is applied to the bottom-left vertex (x, y + height). - * @param color2 is applied to the bottom-right vertex (x + width, y + height). - * @param color3 is applied to the top-right vertex (x + width, y). - * @param color4 is applied to the top-left vertex (x, y). + * @param tl is applied to the top-left vertex (x, y). + * @param tr is applied to the top-right vertex (x + width, y). + * @param br is applied to the bottom-right vertex (x + width, y + height). + * @param bl is applied to the bottom-left vertex (x, y + height). * @param x X pos * @param y Y pos - * @param width Width of rounded gradient rectangle - * @param height Height of rounded gradient rectangle - * @param radius Radius of the quadrants / the rounded gradient rectangle + * @param width Width of rounded.fsh gradient rectangle + * @param height Height of rounded.fsh gradient rectangle + * @param radius Radius of the quadrants / the rounded.fsh gradient rectangle */ - public static void drawRoundedGradientRectangle(Matrix4f matrix, Color color1, Color color2, Color color3, Color color4, float x, float y, float width, float height, float radius) { - drawRoundedGradientRectangle(matrix, color1, color2, color3, color4, x, y, width, height, radius, true, true, true, true); + public static void drawRoundedGradientRectangle(DrawContext drawContext, Color tl, Color tr, Color br, Color bl, float x, float y, float width, float height, float radius) { + drawRoundedGradientRectangle(drawContext, tl,tr,br,bl, x, y, width, height, radius, true, true, true, true); } /** - * Draws a rounded gradient rectangle + * Draws a rounded.fsh gradient rectangle * - * @param matrix Matrix4f object to draw the rounded gradient rectangle - * @param color1 is applied to the bottom-left vertex (x, y + height). - * @param color2 is applied to the bottom-right vertex (x + width, y + height). - * @param color3 is applied to the top-right vertex (x + width, y). - * @param color4 is applied to the top-left vertex (x, y). + * @param tl is applied to the top-left vertex (x, y). + * @param tr is applied to the top-right vertex (x + width, y). + * @param br is applied to the bottom-right vertex (x + width, y + height). + * @param bl is applied to the bottom-left vertex (x, y + height). * @param x X pos * @param y Y pos - * @param width Width of rounded gradient rectangle - * @param height Height of rounded gradient rectangle - * @param radius Radius of the quadrants / the rounded gradient rectangle + * @param width Width of rounded.fsh gradient rectangle + * @param height Height of rounded.fsh gradient rectangle + * @param radius Radius of the quadrants / the rounded.fsh gradient rectangle */ - public static void drawRoundedGradientRectangle(Matrix4f matrix, Color color1, Color color2, Color color3, Color color4, float x, float y, float width, float height, float radius, boolean TL, boolean TR, boolean BL, boolean BR) { - RenderSystem.enableBlend(); - RenderSystem.colorMask(false, false, false, true); - RenderSystem.clearColor(0.0F, 0.0F, 0.0F, 0.0F); - RenderSystem.clear(GL40C.GL_COLOR_BUFFER_BIT); - RenderSystem.colorMask(true, true, true, true); - - drawRoundedRectangle(matrix, x, y, TL, TR, BL, BR, width, height, (int) radius, color1.getRGB()); - - RenderSystem.blendFunc(GL40C.GL_DST_ALPHA, GL40C.GL_ONE_MINUS_DST_ALPHA); - - RenderSystem.enableBlend(); - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - - BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR); - - bufferBuilder.vertex(matrix, x, y + height, 0.0F).color(color1.getRGB()); - bufferBuilder.vertex(matrix, x + width, y + height, 0.0F).color(color2.getRGB()); - bufferBuilder.vertex(matrix, x + width, y, 0.0F).color(color3.getRGB()); - bufferBuilder.vertex(matrix, x, y, 0.0F).color(color4.getRGB()); - - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - - RenderSystem.disableBlend(); - - RenderSystem.defaultBlendFunc(); + public static void drawRoundedGradientRectangle(DrawContext drawContext, Color tl, Color tr, Color br, Color bl, float x, float y, float width, float height, float radius, boolean TL, boolean TR, boolean BL, boolean BR) { + drawRoundedRectangle(drawContext, x, y, width, height, + new Vector4f(TR ? radius : 0.0f, BR ? radius : 0.0f, TL ? radius : 0.0f, BL ? radius : 0.0f), + tl,tr,br,bl); } /* ==== Drawing Lines ==== */ - public static void drawVerticalLine(Matrix4f matrix4f, float x, float y1, float height, float thickness, int color) { - drawRectangle(matrix4f, x, y1, thickness, height, color); + public static void drawVerticalLine(DrawContext drawContext, float x, float y1, float height, float thickness, int color) { + drawRectangle(drawContext, x, y1, thickness, height, color); } - public static void drawHorizontalLine(Matrix4f matrix4f, float x1, float width, float y, float thickness, int color) { - drawRectangle(matrix4f, x1, y, width, thickness, color); + public static void drawHorizontalLine(DrawContext drawContext, float x1, float width, float y, float thickness, int color) { + drawRectangle(drawContext, x1, y, width, thickness, color); } /** diff --git a/src/main/java/com/tanishisherewith/dynamichud/helpers/MouseColorQuery.java b/src/main/java/com/tanishisherewith/dynamichud/helpers/MouseColorQuery.java new file mode 100644 index 0000000..095bbf9 --- /dev/null +++ b/src/main/java/com/tanishisherewith/dynamichud/helpers/MouseColorQuery.java @@ -0,0 +1,70 @@ +package com.tanishisherewith.dynamichud.helpers; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.Framebuffer; +import net.minecraft.client.util.Window; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; + +import java.nio.ByteBuffer; +import java.util.function.Consumer; + +/** + * Color query of the screen should be done when rendering is completed (i.e. at the end of the render tick), + * so this is a helper class to make it easier to query color data + */ +public class MouseColorQuery { + private static SampleRequest pendingRequest = null; + + public static void request(double mouseX, double mouseY, Consumer callback) { + if (pendingRequest == null) { + pendingRequest = new SampleRequest(mouseX, mouseY, callback); + } + } + + public static void processIfPending() { + if (pendingRequest == null) return; + + MinecraftClient client = MinecraftClient.getInstance(); + Framebuffer framebuffer = client.getFramebuffer(); + Window window = client.getWindow(); + + int windowWidth = window.getWidth(); + int windowHeight = window.getHeight(); + int framebufferWidth = framebuffer.textureWidth; + int framebufferHeight = framebuffer.textureHeight; + + double scaleX = (double) framebufferWidth / windowWidth; + double scaleY = (double) framebufferHeight / windowHeight; + + int x = (int) (pendingRequest.mouseX * scaleX); + int y = (int) ((windowHeight - pendingRequest.mouseY) * scaleY); + + if (x < 0 || x >= framebufferWidth || y < 0 || y >= framebufferHeight) { + pendingRequest.callback.accept(null); + pendingRequest = null; + return; + } + + // Make sure rendering is complete + RenderSystem.assertOnRenderThread(); + + + // buffer to store the pixel data + ByteBuffer buffer = BufferUtils.createByteBuffer(4); + + + GL11.glReadPixels(x, y, 1, 1, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); + + int red = buffer.get(0) & 0xFF; + int green = buffer.get(1) & 0xFF; + int blue = buffer.get(2) & 0xFF; + int alpha = buffer.get(3) & 0xFF; + + pendingRequest.callback.accept(new int[]{red, green, blue, alpha}); + pendingRequest = null; + } + + private record SampleRequest(double mouseX, double mouseY, Consumer callback) {} +} diff --git a/src/main/java/com/tanishisherewith/dynamichud/internal/IRenderLayer.java b/src/main/java/com/tanishisherewith/dynamichud/internal/IRenderLayer.java new file mode 100644 index 0000000..3dbc1a2 --- /dev/null +++ b/src/main/java/com/tanishisherewith/dynamichud/internal/IRenderLayer.java @@ -0,0 +1,22 @@ +package com.tanishisherewith.dynamichud.internal; + +import org.joml.Vector4f; + +public interface IRenderLayer { + /** + * Set uniform u to the value described by v4f, formatted as a vec4 (4 floats) + * @param u Name + * @param v4f Value + */ + default void dynamichud$setUniform(String u, Vector4f v4f) { + float[] v = new float[]{v4f.x, v4f.y, v4f.z, v4f.w}; + dynamichud$setUniform(u, v); + } + + /** + * Set uniform u to the value of v, should be an int[], float[] or Matrix4f + * @param u Name + * @param v Value + */ + void dynamichud$setUniform(String u, Object v); +} \ No newline at end of file diff --git a/src/main/java/com/tanishisherewith/dynamichud/mixins/RenderLayerMixin.java b/src/main/java/com/tanishisherewith/dynamichud/mixins/RenderLayerMixin.java new file mode 100644 index 0000000..cc4795f --- /dev/null +++ b/src/main/java/com/tanishisherewith/dynamichud/mixins/RenderLayerMixin.java @@ -0,0 +1,41 @@ +package com.tanishisherewith.dynamichud.mixins; + + +import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.systems.RenderPass; +import com.tanishisherewith.dynamichud.internal.IRenderLayer; +import net.minecraft.client.render.BuiltBuffer; +import net.minecraft.client.render.RenderLayer; +import org.joml.Matrix4f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.HashMap; +import java.util.Map; + +@Mixin(RenderLayer.MultiPhase.class) +public class RenderLayerMixin implements IRenderLayer { + @Unique + private final Map uniforms = new HashMap<>(); + + @Override + public void dynamichud$setUniform(String u, Object v) { + if (v == null) uniforms.remove(u); + else uniforms.put(u, v); + } + + @Inject(method = "draw", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderPass;drawIndexed(II)V")) + void beforeDraw(BuiltBuffer par1, CallbackInfo ci, @Local(ordinal = 0) RenderPass pass) { + uniforms.forEach((k, v) -> { + switch (v) { + case float[] fa -> pass.setUniform(k, fa); + case int[] ia -> pass.setUniform(k, ia); + case Matrix4f mat -> pass.setUniform(k, mat); + default -> throw new IllegalStateException("Unknown uniform type " + v.getClass() + " (" + v + ")"); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/CustomRenderLayers.java b/src/main/java/com/tanishisherewith/dynamichud/utils/CustomRenderLayers.java new file mode 100644 index 0000000..df17c3d --- /dev/null +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/CustomRenderLayers.java @@ -0,0 +1,142 @@ +package com.tanishisherewith.dynamichud.utils; + +import com.mojang.blaze3d.pipeline.BlendFunction; +import com.mojang.blaze3d.pipeline.RenderPipeline; +import com.mojang.blaze3d.platform.DestFactor; +import com.mojang.blaze3d.platform.LogicOp; +import com.mojang.blaze3d.platform.SourceFactor; +import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.blaze3d.vertex.VertexFormatElement; +import com.tanishisherewith.dynamichud.internal.IRenderLayer; +import net.minecraft.client.gl.RenderPipelines; +import net.minecraft.client.gl.UniformType; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.math.Vector2f; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import org.joml.Vector4f; + +import java.awt.*; +import java.util.function.Function; + +public class CustomRenderLayers { + public static RenderLayer QUADS_CUSTOM_BLEND = RenderLayer.of( + "dynamichud/quads_custom_blend", + 1536, + false, + true, + RenderPipelines.register(RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET) + .withLocation(Identifier.of("dynamichud", "pipeline/quad_custom_blend_func")) + .withVertexFormat(VertexFormats.POSITION_COLOR, VertexFormat.DrawMode.QUADS) + .withBlend(new BlendFunction(SourceFactor.DST_ALPHA, DestFactor.ONE_MINUS_DST_ALPHA)) + .build() + ), + RenderLayer.MultiPhaseParameters.builder().build(false) + ); + + public static RenderLayer TRIANGLE_FAN_CUSTOM_BLEND = RenderLayer.of( + "dynamichud/triangle_fan_custom_blend", + 1536, + false, + true, + RenderPipelines.register(RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET) + .withLocation(Identifier.of("dynamichud", "pipeline/triangle_fan_custom_blend_func")) + .withVertexFormat(VertexFormats.POSITION_COLOR, VertexFormat.DrawMode.TRIANGLE_FAN) + .withBlend(new BlendFunction(SourceFactor.DST_ALPHA, DestFactor.ONE_MINUS_DST_ALPHA)) + .build() + ), + RenderLayer.MultiPhaseParameters.builder().build(false) + ); + public static RenderLayer TRIANGLE_STRIP = RenderLayer.of( + "dynamichud/triangle_strip", + 1536, + false, + true, + RenderPipelines.register(RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET) + .withLocation(Identifier.of("dynamichud", "pipeline/triangle_strip")) + .withVertexFormat(VertexFormats.POSITION_COLOR, VertexFormat.DrawMode.TRIANGLE_STRIP) + .withBlend(BlendFunction.TRANSLUCENT) + .build() + ), + RenderLayer.MultiPhaseParameters.builder().build(false) + ); + + private static final RenderPipeline ROUNDED = RenderPipelines.register(RenderPipeline.builder(RenderPipelines.MATRICES_COLOR_SNIPPET) + .withBlend(BlendFunction.TRANSLUCENT) + .withVertexFormat(VertexFormat.builder() + .add("Position", VertexFormatElement.POSITION) + .add("UV0", VertexFormatElement.UV0) + .add("Color", VertexFormatElement.COLOR) + .build(), VertexFormat.DrawMode.QUADS) + .withCull(true) + .withColorLogic(LogicOp.NONE) + .withFragmentShader(Identifier.of("dynamichud", "core/rounded")) + .withVertexShader(Identifier.of("dynamichud", "core/rounded")) + .withLocation(Identifier.of("dynamichud", "pipeline/rounded")) + .withUniform("Roundness", UniformType.VEC4) + .withUniform("widthHeight", UniformType.VEC2) + .build()); + + private static final RenderPipeline ROUNDED_OUTLINE = RenderPipelines.register(RenderPipeline.builder(RenderPipelines.MATRICES_COLOR_SNIPPET) + .withBlend(BlendFunction.TRANSLUCENT) + .withVertexFormat(VertexFormat.builder() + .add("Position", VertexFormatElement.POSITION) + .add("UV0", VertexFormatElement.UV0) + .add("Color", VertexFormatElement.COLOR) + .build(), VertexFormat.DrawMode.QUADS) + .withCull(true) + .withColorLogic(LogicOp.NONE) + .withFragmentShader(Identifier.of("dynamichud", "core/rounded_outline")) + .withVertexShader(Identifier.of("dynamichud", "core/rounded")) + .withLocation(Identifier.of("dynamichud", "pipeline/rounded_outline")) + .withUniform("Thickness", UniformType.VEC4) + .withUniform("Roundness", UniformType.VEC4) + .withUniform("widthHeight", UniformType.VEC2) + .build()); + + public static final Function ROUNDED_RECT = Util.memoize(params -> { + RenderLayer rl = RenderLayer.of( + "dynamichud/rounded", + 1024, + false, + false, + ROUNDED, + RenderLayer.MultiPhaseParameters.builder() + .build(false) + ); + ((IRenderLayer) rl).dynamichud$setUniform("Roundness", params.roundness); + ((IRenderLayer) rl).dynamichud$setUniform("widthHeight", params.widthHeight); + return rl; + }); + + public static final Function ROUNDED_RECT_OUTLINE = Util.memoize(params -> { + RenderLayer rl = RenderLayer.of( + "neverdies/2d/rounded_rect_outline", + 1024, + false, + false, + ROUNDED_OUTLINE, + RenderLayer.MultiPhaseParameters.builder() + .build(false) + ); + ((IRenderLayer) rl).dynamichud$setUniform("Roundness", params.roundness); + ((IRenderLayer) rl).dynamichud$setUniform("Thickness", new Vector4f(params.thickness,0f,0f,0f)); + ((IRenderLayer) rl).dynamichud$setUniform("widthHeight", params.widthHeight); + return rl; + }); + + + private static int getNewVertexFormatElementsId() { + for(int id = 0; id < 32; id++) { + if (VertexFormatElement.byId(id) == null) { + return id; + } + } + throw new RuntimeException("Too many registered VertexFormatElements"); + } + + + public record RoundedParameters(Vector4f roundness, float[] widthHeight){} + public record OutlineParameters(Vector4f roundness, float thickness, float[] widthHeight){} +} diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/ContextMenuProperties.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/ContextMenuProperties.java index 1b75f56..3e45992 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/ContextMenuProperties.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/ContextMenuProperties.java @@ -17,7 +17,7 @@ public class ContextMenuProperties { protected boolean drawBorder = true; protected boolean shadow = true; protected boolean roundedCorners = true; - protected int cornerRadius = 3; + protected int cornerRadius = 4; protected boolean hoverEffect = true; protected Color hoverColor = new Color(42, 42, 42, 150); protected boolean enableAnimations = true; diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/DoubleOption.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/DoubleOption.java index 5f0e2ac..27d8ec6 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/DoubleOption.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/DoubleOption.java @@ -32,9 +32,9 @@ public DoubleOption(Text name, double minValue, double maxValue, float step, Sup } public void drawSlider(DrawContext drawContext, int sliderX, int sliderY, int sliderWidth, double handleX) { - DrawHelper.drawRectangle(drawContext.getMatrices().peek().getPositionMatrix(), sliderX, sliderY, sliderWidth, 2, 0xFFFFFFFF); + DrawHelper.drawRectangle(drawContext, sliderX, sliderY, sliderWidth, 2, 0xFFFFFFFF); if (handleX - sliderX > 0) { - DrawHelper.drawRectangle(drawContext.getMatrices().peek().getPositionMatrix(), (float) sliderX, (float) sliderY, (float) ((value - minValue) / (maxValue - minValue) * (width - 3)), 2, Color.ORANGE.getRGB()); + DrawHelper.drawRectangle(drawContext, (float) sliderX, (float) sliderY, (float) ((value - minValue) / (maxValue - minValue) * (width - 3)), 2, Color.ORANGE.getRGB()); } } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/AlphaSlider.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/AlphaSlider.java index 69d8ece..ef71488 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/AlphaSlider.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/AlphaSlider.java @@ -30,7 +30,7 @@ public void render(DrawContext drawContext, int x, int y) { this.y = y; DrawHelper.drawOutlinedBox(drawContext, x - 2, y - 2, x + width + 2, y + height + 2, Color.WHITE.getRGB()); - DrawHelper.drawGradient(drawContext.getMatrices().peek().getPositionMatrix(), x, y, width, height, color.getRGB(), ColorHelper.changeAlpha(color, 0).getRGB(), DrawHelper.Direction.TOP_BOTTOM); + DrawHelper.drawGradient(drawContext, x, y, width, height, color.getRGB(), ColorHelper.changeAlpha(color, 0).getRGB(), DrawHelper.Direction.TOP_BOTTOM); drawContext.fill(x - 2, y + alphaHandleY - 1, x + width + 2, y + alphaHandleY + 1, Color.WHITE.getRGB()); } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/ColorGradient.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/ColorGradient.java index a035bdc..067c45c 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/ColorGradient.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/ColorGradient.java @@ -2,6 +2,7 @@ import com.tanishisherewith.dynamichud.config.GlobalConfig; import com.tanishisherewith.dynamichud.helpers.ColorHelper; +import com.tanishisherewith.dynamichud.helpers.MouseColorQuery; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; @@ -62,19 +63,20 @@ public void render(DrawContext drawContext, int x1, int y1, int mouseX, int mous alphaSlider.render(drawContext, x + 10 + boxSize, y + client.textRenderer.fontHeight + gradientSlider.getHeight() + 10); if (colorPickerButton.isPicking() && GlobalConfig.get().showColorPickerPreview()) { - int[] colors = ColorHelper.getMousePixelColor(mouseX, mouseY); - if (colors != null) { - int red = colors[0]; - int green = colors[1]; - int blue = colors[2]; - - //Draw the preview box near the mouse pointer - drawContext.getMatrices().push(); - drawContext.getMatrices().translate(0, 0, 2500); - drawContext.fill(mouseX + 10, mouseY, mouseX + 26, mouseY + 16, -1); - drawContext.fill(mouseX + 11, mouseY + 1, mouseX + 25, mouseY + 15, (red << 16) | (green << 8) | blue | 0xFF000000); - drawContext.getMatrices().pop(); - } + MouseColorQuery.request(mouseX, mouseY, colors -> { + if (colors != null) { + int red = colors[0]; + int green = colors[1]; + int blue = colors[2]; + + //Draw the preview box near the mouse pointer + drawContext.getMatrices().push(); + drawContext.getMatrices().translate(0, 0, 2500); + drawContext.fill(mouseX + 10, mouseY, mouseX + 26, mouseY + 16, -1); + drawContext.fill(mouseX + 11, mouseY + 1, mouseX + 25, mouseY + 15, (red << 16) | (green << 8) | blue | 0xFF000000); + drawContext.getMatrices().pop(); + } + }); } } @@ -105,7 +107,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { } } */ - alphaSlider.setColor(new Color(gradientBox.getColor())); + alphaSlider.setColor(new Color(gradientBox.getColor(), true)); alphaSlider.onClick(mouseX, mouseY, button); onColorSelected.accept(alphaSlider.getColor()); @@ -125,7 +127,7 @@ public void mouseDragged(double mouseX, double mouseY, int button) { gradientSlider.onDrag(mouseX, mouseY, button); gradientBox.setHue(gradientSlider.getHue()); gradientBox.onDrag(mouseX, mouseY, button); - alphaSlider.setColor(new Color(gradientBox.getColor())); + alphaSlider.setColor(new Color(gradientBox.getColor(), true)); alphaSlider.onDrag(mouseX, mouseY, button); onColorSelected.accept(alphaSlider.getColor()); } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/HueSlider.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/HueSlider.java index 7f8298c..1c5097d 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/HueSlider.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/HueSlider.java @@ -53,7 +53,7 @@ public void render(DrawContext drawContext, int x, int y) { float handleX = x + hue * width - handleWidth / 2.0f; float handleY = y - (handleHeight - height) / 2.0f; - DrawHelper.drawRectangle(drawContext.getMatrices().peek().getPositionMatrix(), handleX, handleY, handleWidth, handleHeight, -1); + DrawHelper.drawRectangle(drawContext, handleX, handleY, handleWidth, handleHeight, -1); drawContext.getMatrices().pop(); } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/SaturationHueBox.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/SaturationHueBox.java index e0eca23..53b8238 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/SaturationHueBox.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/options/coloroption/SaturationHueBox.java @@ -28,14 +28,14 @@ public void render(DrawContext drawContext, int x, int y) { DrawHelper.drawOutlinedBox(drawContext, x - 2, y - 2, x + size + 2, y + size + 2, -1); // Draw the gradient - DrawHelper.drawRoundedGradientRectangle(drawContext.getMatrices().peek().getPositionMatrix(), Color.BLACK, Color.BLACK, Color.getHSBColor(hue, 1.0f, 1.0f), Color.WHITE, x, y, size, size, 2); + DrawHelper.drawRoundedGradientRectangle(drawContext, Color.WHITE, Color.getHSBColor(hue, 1.0f, 1.0f),Color.BLACK, Color.BLACK, x, y, size, size, 3); // Draw the handle float handleSize = 1f; float handleX = x + 2 + saturation * size - handleSize / 2.0f; float handleY = y + 2 + (1.0f - value) * size - handleSize / 2.0f; - DrawHelper.drawFilledCircle(drawContext.getMatrices().peek().getPositionMatrix(), handleX, handleY, handleSize, -1); + DrawHelper.drawFilledCircle(drawContext, handleX, handleY, handleSize, -1); drawContext.getMatrices().pop(); } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ClassicSkin.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ClassicSkin.java index fec9a29..36ec017 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ClassicSkin.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ClassicSkin.java @@ -39,7 +39,7 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen ContextMenuProperties properties = contextMenu.getProperties(); // Draw the background - drawBackground(matrices, contextMenu, properties); + drawBackground(drawContext, contextMenu, properties); int yOffset = contextMenu.y + 3; int width = 10; @@ -48,7 +48,7 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen // Adjust mouse coordinates based on the scale if (contextMenu.getProperties().hoverEffect() && contextMenu.isMouseOver(mouseX, mouseY, contextMenu.x + 1, yOffset - 1, contextMenu.getWidth() - 2, option.getHeight())) { - drawBackground(matrices, contextMenu, properties, yOffset - 1, contextMenu.getWidth(), option.getHeight() + 1, contextMenu.getProperties().getHoverColor().getRGB(), false); + drawBackground(drawContext, contextMenu, properties, yOffset - 1, contextMenu.getWidth(), option.getHeight() + 1, contextMenu.getProperties().getHoverColor().getRGB(), false); } option.render(drawContext, contextMenu.x + 4, yOffset, mouseX, mouseY); @@ -60,19 +60,19 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen // Draw the border if needed if (properties.shouldDrawBorder()) { - drawBorder(matrices, contextMenu, properties); + drawBorder(drawContext, contextMenu, properties); } } - private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, ContextMenuProperties properties) { - drawBackground(matrices, contextMenu, properties, contextMenu.y, contextMenu.getWidth(), contextMenu.getHeight(), properties.getBackgroundColor().getRGB(), properties.shadow()); + private void drawBackground(DrawContext drawContext, ContextMenu contextMenu, ContextMenuProperties properties) { + drawBackground(drawContext, contextMenu, properties, contextMenu.y, contextMenu.getWidth(), contextMenu.getHeight(), properties.getBackgroundColor().getRGB(), properties.shadow()); } - private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, ContextMenuProperties properties, int yOffset, int width, int height, int color, boolean shadow) { + private void drawBackground(DrawContext drawContext, ContextMenu contextMenu, ContextMenuProperties properties, int yOffset, int width, int height, int color, boolean shadow) { if (properties.roundedCorners()) { // Rounded if (shadow) { - DrawHelper.drawRoundedRectangleWithShadowBadWay(matrices.peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, contextMenu.x, yOffset, width, @@ -84,7 +84,7 @@ private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, Co 1 ); } else { - DrawHelper.drawRoundedRectangle(matrices.peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangle(drawContext, contextMenu.x, yOffset, width, @@ -96,7 +96,7 @@ private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, Co } else { // Normal if (shadow) { - DrawHelper.drawRectangleWithShadowBadWay(matrices.peek().getPositionMatrix(), + DrawHelper.drawRectangleWithShadowBadWay(drawContext, contextMenu.x, yOffset, width, @@ -107,7 +107,7 @@ private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, Co 1 ); } else { - DrawHelper.drawRectangle(matrices.peek().getPositionMatrix(), + DrawHelper.drawRectangle(drawContext, contextMenu.x, yOffset, width, @@ -118,9 +118,9 @@ private void drawBackground(MatrixStack matrices, ContextMenu contextMenu, Co } } - private void drawBorder(MatrixStack matrices, ContextMenu contextMenu, ContextMenuProperties properties) { + private void drawBorder(DrawContext drawContext, ContextMenu contextMenu, ContextMenuProperties properties) { if (properties.roundedCorners()) { - DrawHelper.drawOutlineRoundedBox(matrices.peek().getPositionMatrix(), + DrawHelper.drawOutlineRoundedBox(drawContext, contextMenu.x, contextMenu.y, contextMenu.getWidth(), @@ -130,7 +130,7 @@ private void drawBorder(MatrixStack matrices, ContextMenu contextMenu, Contex properties.getBorderColor().getRGB() ); } else { - DrawHelper.drawOutlineBox(matrices.peek().getPositionMatrix(), + DrawHelper.drawOutlineBox(drawContext, contextMenu.x, contextMenu.y, contextMenu.getWidth(), @@ -165,12 +165,12 @@ public void render(DrawContext drawContext, ColorOption option, int x, int y, in option.setWidth(mc.textRenderer.getWidth(option.name) + 10); int shadowOpacity = Math.min(option.value.getAlpha(), 90); - DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, x + option.getWidth() - 10 + 1, y - 1, 8, 8, - 2, + 3, option.value.getRGB(), shadowOpacity, 1, @@ -244,12 +244,12 @@ public void render(DrawContext drawContext, DoubleOption option, int x, int y, i option.drawSlider(drawContext, x, y + textRenderer.fontHeight + 1, option.getWidth(), handleX); // Draw the handle - DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, (float) handleX, (float) handleY, handleWidth, handleHeight, - 1, + 3, 0xFFFFFFFF, 90, 0.6f, diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/MinecraftSkin.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/MinecraftSkin.java index ed49960..0593ed0 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/MinecraftSkin.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/MinecraftSkin.java @@ -2,7 +2,6 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.tanishisherewith.dynamichud.DynamicHUD; -import com.tanishisherewith.dynamichud.helpers.ColorHelper; import com.tanishisherewith.dynamichud.helpers.DrawHelper; import com.tanishisherewith.dynamichud.utils.contextmenu.ContextMenu; import com.tanishisherewith.dynamichud.utils.contextmenu.layout.LayoutContext; @@ -10,7 +9,6 @@ import com.tanishisherewith.dynamichud.utils.contextmenu.skinsystem.interfaces.GroupableSkin; import com.tanishisherewith.dynamichud.utils.contextmenu.skinsystem.interfaces.SkinRenderer; import com.tanishisherewith.dynamichud.utils.handlers.ScrollHandler; -import net.minecraft.client.gl.ShaderProgramKeys; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ButtonTextures; import net.minecraft.client.render.RenderLayer; @@ -123,16 +121,11 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen imageX = (screenWidth - panelWidth + 25) / 2; imageY = (screenHeight - panelHeight) / 2; - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); - drawContext.drawTexture(RenderLayer::getGuiTextured, BACKGROUND_PANEL, imageX, imageY, 0, 0, panelWidth, panelHeight, 256, 254,panelColor.getColor()); drawSingularButton(drawContext, "X", mouseX, mouseY, imageX + 3, imageY + 3, 14, 14); //Up and down arrows near the group panel - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); int size = (int) (groupPanelWidth * 0.5f); drawSingularButton(drawContext, "^", mouseX, mouseY, groupPanelX.getAsInt() + groupPanelWidth / 2 - size / 2, imageY - 14, size, 14, groupScrollHandler.isOffsetWithinBounds(-10)); @@ -173,8 +166,6 @@ private void renderOptionGroups(DrawContext drawContext, int mouseX, int mouseY) int groupX = groupPanelX.getAsInt(); int groupY = imageY; - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); drawContext.drawTexture(RenderLayer::getGuiTextured, GROUP_BACKGROUND, groupX - 10, groupY + 2, 0,0,groupPanelWidth + 20, panelHeight, 80, 158); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -197,8 +188,6 @@ private void renderOptionGroups(DrawContext drawContext, int mouseX, int mouseY) groupScrollHandler.updateScrollOffset(yOffset - groupY - 12 + groupScrollHandler.getScrollOffset() - panelHeight); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); } private int renderSelectedGroupOptions(DrawContext drawContext, int mouseX, int mouseY) { @@ -222,10 +211,8 @@ private void drawScrollbar(DrawContext drawContext) { double handleHeight = panelHeight * ratio; int handleY = (int) (scrollbarY + (panelHeight - handleHeight) * ((double) scrollHandler.getScrollOffset() / getMaxScrollOffset())); - RenderSystem.enableBlend(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, SCROLL_BAR_BACKGROUND, scrollbarX, scrollbarY, DEFAULT_SCROLLBAR_WIDTH, panelHeight); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, SCROLLER_TEXTURE, scrollbarX, handleY, DEFAULT_SCROLLBAR_WIDTH, (int) handleHeight); - RenderSystem.disableBlend(); } } @@ -408,11 +395,7 @@ public void render(DrawContext drawContext, BooleanOption option, int x, int y, int width = 50; RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(true, option.isMouseOver(mouseX, mouseY)), option.getX(), y, width, 20); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); Text text = option.getBooleanType().getText(option.value); @@ -440,14 +423,12 @@ public void render(DrawContext drawContext, ColorOption option, int x, int y, in int width = 20; RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(!option.isVisible, option.isMouseOver(mouseX, mouseY)), option.getX(), y, width, 20); - RenderSystem.disableBlend(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); int shadowOpacity = Math.min(option.value.getAlpha(), 45); drawContext.draw(); - DrawHelper.drawRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRectangleWithShadowBadWay(drawContext, option.getX() + 4, y + 4, width - 8, @@ -502,17 +483,11 @@ public void render(DrawContext drawContext, DoubleOption option, int x, int y, i double sliderX = option.getX() + ((option.value - option.minValue) / (option.maxValue - option.minValue)) * (option.getWidth() - 8); boolean isMouseOverHandle = isMouseOver(mouseX, mouseY, sliderX, y, 10, 20); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, option.isMouseOver(mouseX, mouseY) ? HIGHLIGHTED_TEXTURE : TEXTURE, option.getX(), y, option.getWidth(), 20); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, isMouseOverHandle ? HANDLE_HIGHLIGHTED_TEXTURE : HANDLE_TEXTURE, (int) Math.round(sliderX), y, 8, 20); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); - // Determine the number of decimal places in option.step + // Determine the number of decimal places in option.step int decimalPlaces = String.valueOf(option.step).split("\\.")[1].length(); // Format option.value to the determined number of decimal places @@ -549,13 +524,9 @@ public void render(DrawContext drawContext, EnumOption option, int x, int y, option.setPosition(x + panelWidth - maxWidth - 25, y); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(true, option.isMouseOver(mouseX, mouseY)), option.getX(), y, maxWidth, 20); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); String text = option.get().toString(); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); drawContext.drawText(mc.textRenderer, text, option.getX() + maxWidth / 2 - mc.textRenderer.getWidth(text) / 2, y + 5, Color.CYAN.getRGB(), true); } } @@ -583,13 +554,9 @@ public void render(DrawContext drawContext, ListOption option, int x, int y, option.setPosition(x + panelWidth - maxWidth - 25, y); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(true, option.isMouseOver(mouseX, mouseY)), option.getX(), y, maxWidth, 20); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); String text = option.get().toString(); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); drawContext.drawText(mc.textRenderer, text, option.getX() + maxWidth / 2 - mc.textRenderer.getWidth(text) / 2, y + 5, Color.CYAN.getRGB(), true); } } @@ -605,12 +572,10 @@ public void render(DrawContext drawContext, SubMenuOption option, int x, int y, option.setPosition(x + panelWidth - 55, y); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(true, option.isMouseOver(mouseX, mouseY)), option.getX(), y, option.getWidth(), 20); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); String text = "Open"; drawContext.drawText(mc.textRenderer, text, option.getX() + option.getWidth() / 2 - mc.textRenderer.getWidth(text) / 2, y + 5, Color.YELLOW.getRGB(), true); - RenderSystem.disableBlend(); option.getSubMenu().render(drawContext, x + option.getParentMenu().getWidth(), y, mouseX, mouseY); } @@ -630,13 +595,9 @@ public void render(DrawContext drawContext, RunnableOption option, int x, int y, option.setPosition(x + panelWidth - 51, y); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); - RenderSystem.enableDepthTest(); drawContext.drawGuiTexture(RenderLayer::getGuiTextured, TEXTURES.get(!option.value, option.isMouseOver(mouseX, mouseY)), option.getX(), y, option.getWidth(), 20); drawContext.drawText(mc.textRenderer, "Run", option.getX() + option.getWidth() / 2 - mc.textRenderer.getWidth("Run") / 2, y + 5, option.value ? DARK_GREEN.getRGB() : DARK_RED.getRGB(), true); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.disableBlend(); - RenderSystem.disableDepthTest(); } } diff --git a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ModernSkin.java b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ModernSkin.java index df1203e..17fc98d 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ModernSkin.java +++ b/src/main/java/com/tanishisherewith/dynamichud/utils/contextmenu/skinsystem/ModernSkin.java @@ -91,13 +91,13 @@ public void renderGroup(DrawContext drawContext, OptionGroup group, int groupX, mouseY = (int) (mc.mouse.getY() / SCALE_FACTOR); if (group.isExpanded() && group.getHeight() > 20) { - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangle(drawContext, groupX + 1, groupY + 14, width - groupX - 8 + contextMenuX, group.getHeight() - 16, radius, DARKER_GRAY_2.getRGB()); } Text groupText = group.name.copy().append(" " + (group.isExpanded() ? "-" : "+")); - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangle(drawContext, groupX + 1, groupY + 1, true, true, !group.isExpanded(), !group.isExpanded(), mc.textRenderer.getWidth(groupText) + 6, 16, radius, DARKER_GRAY_2.getRGB()); drawContext.drawText(mc.textRenderer, groupText, groupX + 4, groupY + 4, -1, true); @@ -124,8 +124,8 @@ private void drawScrollbar(DrawContext drawContext) { int handleHeight = (int) ((float) (height - 23) * ((height - 23) / (float) contextMenu.getHeight())); int handleY = scrollbarY + (int) ((float) ((height - 23) - handleHeight) * ((float) scrollHandler.getScrollOffset() / getMaxScrollOffset())); - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), scrollbarX, scrollbarY, 2, height - 23, 1, DARKER_GRAY.getRGB()); - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), scrollbarX, handleY, 2, handleHeight, 1, Color.LIGHT_GRAY.getRGB()); + DrawHelper.drawRoundedRectangle(drawContext, scrollbarX, scrollbarY, 2, height - 23, 1, DARKER_GRAY.getRGB()); + DrawHelper.drawRoundedRectangle(drawContext, scrollbarX, handleY, 2, handleHeight, 1, Color.LIGHT_GRAY.getRGB()); } } @@ -144,7 +144,7 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen contextMenu.set(contextMenuX, contextMenuY, 0); //Background - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangle(drawContext, contextMenuX, contextMenuY, width, height, radius, DARKER_GRAY.getRGB()); drawBackButton(drawContext, mouseX, mouseY); @@ -153,7 +153,7 @@ public void renderContextMenu(DrawContext drawContext, ContextMenu contextMen int optionStartX = contextMenu.x + (int) (width * 0.2f) + 10; //Background behind the options - DrawHelper.drawRoundedRectangle(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangle(drawContext, optionStartX, contextMenuY + 19, width * 0.8f - 14, height - 23, radius, DARK_GRAY.getRGB()); enableSkinScissor(); @@ -205,7 +205,7 @@ public void drawBackButton(DrawContext drawContext, int mouseX, int mouseY) { boolean isHoveringOver = isMouseOver(mouseX, mouseY, contextMenuX + 2, contextMenuY + 2, textWidth + 8, 14); int color = isHoveringOver ? themeColor.darker().getRGB() : themeColor.getRGB(); - DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, contextMenuX + 2, contextMenuY + 2, textWidth + 8, 14, radius, color, 125, 2, 2); drawContext.drawText(mc.textRenderer, backText, contextMenuX + 6, contextMenuY + 5, -1, true); @@ -226,7 +226,7 @@ public void renderToolTipText(DrawContext drawContext, int mouseX, int mouseY) { // Draw background DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, contextMenuX + 2, tooltipY, toolTipWidth, @@ -235,7 +235,7 @@ public void renderToolTipText(DrawContext drawContext, int mouseX, int mouseY) { DARK_GRAY.getRGB() ); DrawHelper.drawHorizontalLine( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, contextMenuX + 2, toolTipWidth, tooltipY + 16, @@ -374,7 +374,7 @@ public void render(DrawContext drawContext, BooleanOption option, int x, int y, Color hoveredColor = isMouseOver(mouseX, mouseY, toggleBgX, y + 2, 14, 7) ? backgroundColor.darker() : backgroundColor; DrawHelper.drawRoundedRectangleWithShadowBadWay( - matrices.peek().getPositionMatrix(), + drawContext, toggleBgX, y + 2, 14, 7, 3, hoveredColor.getRGB(), @@ -387,7 +387,7 @@ public void render(DrawContext drawContext, BooleanOption option, int x, int y, EasingType easingType = active ? EasingType.EASE_IN_CUBIC : EasingType.EASE_OUT_QUAD; float toggleX = MathAnimations.lerp(startX, endX, animationStartTime, 200f, easingType); - DrawHelper.drawFilledCircle(matrices.peek().getPositionMatrix(), toggleX, y + 2 + 3.3f, 2.8f, Color.WHITE.getRGB()); + DrawHelper.drawFilledCircle(drawContext, toggleX, y + 2 + 3.3f, 2.8f, Color.WHITE.getRGB()); // Draw option name drawContext.drawText( @@ -461,7 +461,7 @@ public void render(DrawContext drawContext, ColorOption option, int x, int y, in //The shape behind the preview Color behindColor = isMouseOver(mouseX, mouseY, x + backgroundWidth - width - 17, y + 1, width + 2, 14) ? getThemeColor().darker().darker() : getThemeColor(); - DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, x + backgroundWidth - width - 17, y + 1, width + 2, @@ -483,7 +483,7 @@ public void render(DrawContext drawContext, ColorOption option, int x, int y, in ); //Preview - DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRoundedRectangleWithShadowBadWay(drawContext, x + backgroundWidth - width - 15, y + 2, width - 8, @@ -577,7 +577,7 @@ public void render(DrawContext drawContext, DoubleOption option, int x, int y, i // Background DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, sliderX, y, sliderBackgroundWidth, sliderBackgroundHeight, 1, DARKER_GRAY.getRGB() ); @@ -585,13 +585,13 @@ public void render(DrawContext drawContext, DoubleOption option, int x, int y, i int activeFillWidth = (int) ((displayValue - option.minValue) / (option.maxValue - option.minValue) * option.getWidth()); Color fillColor = isMouseOver(mouseX, mouseY, sliderX, y, sliderBackgroundWidth, sliderBackgroundHeight + 4) ? getThemeColor().darker().darker() : getThemeColor(); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), - sliderX, y, activeFillWidth, sliderBackgroundHeight, 1, fillColor.getRGB() + drawContext, + sliderX, y, activeFillWidth, sliderBackgroundHeight, 2, fillColor.getRGB() ); // Draw slider handle float sliderHandleX = sliderX + activeFillWidth - 5; - DrawHelper.drawFilledCircle(drawContext.getMatrices().peek().getPositionMatrix(), sliderHandleX + 5, y + 1, 2, Color.WHITE.getRGB()); + DrawHelper.drawFilledCircle(drawContext, sliderHandleX + 5, y + 1, 2, Color.WHITE.getRGB()); // Draw value text String text = String.format("%.2f", displayValue); @@ -653,7 +653,7 @@ public void render(DrawContext drawContext, EnumOption option, int x, int y, drawContext.drawText(mc.textRenderer, mainLabel, x + 4, y + 2, -1, false); Color fillColor = isMouseOver(mouseX, mouseY, x + 4 + mc.textRenderer.getWidth(mainLabel), y, mc.textRenderer.getWidth(selectedOption) + 5, mc.textRenderer.fontHeight + 2) ? getThemeColor().darker().darker() : getThemeColor(); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, x + 4 + mc.textRenderer.getWidth(mainLabel), y, mc.textRenderer.getWidth(selectedOption) + 5, mc.textRenderer.fontHeight + 2, 2, fillColor.getRGB() ); @@ -664,27 +664,27 @@ public void render(DrawContext drawContext, EnumOption option, int x, int y, boolean hoveredOverRight = isMouseOver(mouseX, mouseY, leftX + mc.textRenderer.getWidth("<") + 6, y, mc.textRenderer.getWidth(">") + 5, mc.textRenderer.fontHeight); // Shadow DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + 1, y + 3, (mc.textRenderer.getWidth("<") * 2) + 10, mc.textRenderer.fontHeight, 2, ColorHelper.changeAlpha(Color.BLACK, 128).getRGB() ); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX, y + 2, true, false, true, false, mc.textRenderer.getWidth("<") + 5, mc.textRenderer.fontHeight, 2, hoveredOverLeft ? getThemeColor().darker().darker().getRGB() : getThemeColor().getRGB() ); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + mc.textRenderer.getWidth("<") + 6, y + 2, false, true, false, true, mc.textRenderer.getWidth(">") + 5, mc.textRenderer.fontHeight, 2, hoveredOverRight ? getThemeColor().darker().darker().getRGB() : getThemeColor().getRGB() ); DrawHelper.drawVerticalLine( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + mc.textRenderer.getWidth("<") + 5, y + 2, mc.textRenderer.fontHeight, @@ -752,7 +752,7 @@ public void render(DrawContext drawContext, ListOption option, int x, int y, drawContext.drawText(mc.textRenderer, mainLabel, x + 4, y + 2, -1, false); Color fillColor = isMouseOver(mouseX, mouseY, x + 4 + mc.textRenderer.getWidth(mainLabel), y, mc.textRenderer.getWidth(selectedOption) + 5, mc.textRenderer.fontHeight + 2) ? getThemeColor().darker().darker() : getThemeColor(); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, x + 4 + mc.textRenderer.getWidth(mainLabel), y, mc.textRenderer.getWidth(selectedOption) + 5, mc.textRenderer.fontHeight + 2, 2, fillColor.getRGB() ); @@ -764,27 +764,27 @@ public void render(DrawContext drawContext, ListOption option, int x, int y, boolean hoveredOverRight = isMouseOver(mouseX, mouseY, leftX + mc.textRenderer.getWidth("<") + 6, y, mc.textRenderer.getWidth(">") + 5, mc.textRenderer.fontHeight); // Shadow DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + 1, y + 3, (mc.textRenderer.getWidth("<") * 2) + 10, mc.textRenderer.fontHeight, 2, ColorHelper.changeAlpha(Color.BLACK, 128).getRGB() ); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX, y + 2, true, false, true, false, mc.textRenderer.getWidth("<") + 5, mc.textRenderer.fontHeight, 2, hoveredOverLeft ? getThemeColor().darker().darker().getRGB() : getThemeColor().getRGB() ); DrawHelper.drawRoundedRectangle( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + mc.textRenderer.getWidth("<") + 6, y + 2, false, true, false, true, mc.textRenderer.getWidth(">") + 5, mc.textRenderer.fontHeight, 2, hoveredOverRight ? getThemeColor().darker().darker().getRGB() : getThemeColor().getRGB() ); DrawHelper.drawVerticalLine( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, leftX + mc.textRenderer.getWidth("<") + 5, y + 2, mc.textRenderer.fontHeight, @@ -862,7 +862,7 @@ public void render(DrawContext drawContext, SubMenuOption option, int x, int y, Color fillColor = isMouseOver(mouseX, mouseY, xPos + 2, y + 4, mc.textRenderer.getWidth(text) + 5, mc.textRenderer.fontHeight + 4) ? getThemeColor().darker().darker() : getThemeColor(); DrawHelper.drawRoundedRectangleWithShadowBadWay( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, xPos - 1, y + 1, mc.textRenderer.getWidth(text) + 5, mc.textRenderer.fontHeight + 4, 2, @@ -872,7 +872,7 @@ public void render(DrawContext drawContext, SubMenuOption option, int x, int y, 1 ); DrawHelper.drawOutlineRoundedBox( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, xPos - 1, y + 1, mc.textRenderer.getWidth(text) + 5, mc.textRenderer.fontHeight + 4, 2, @@ -933,7 +933,7 @@ public void render(DrawContext drawContext, RunnableOption option, int x, int y, Color fillColor = isMouseOver(mouseX, mouseY, xPos + 2, y + 4, mc.textRenderer.getWidth(text) + 5, mc.textRenderer.fontHeight + 4) ? getThemeColor().darker().darker() : getThemeColor(); DrawHelper.drawRoundedRectangleWithShadowBadWay( - drawContext.getMatrices().peek().getPositionMatrix(), + drawContext, xPos - 1, y + 1, mc.textRenderer.getWidth(text) + 5, mc.textRenderer.fontHeight + 4, 2, diff --git a/src/main/java/com/tanishisherewith/dynamichud/widget/DynamicValueWidget.java b/src/main/java/com/tanishisherewith/dynamichud/widget/DynamicValueWidget.java index 506de8d..1e8630f 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/widget/DynamicValueWidget.java +++ b/src/main/java/com/tanishisherewith/dynamichud/widget/DynamicValueWidget.java @@ -45,8 +45,8 @@ public void writeToTag(NbtCompound tag) { @Override public void readFromTag(NbtCompound tag) { super.readFromTag(tag); - registryID = tag.getString("RegistryID"); - registryKey = tag.getString("RegistryKey"); + registryID = tag.getString("RegistryID").orElse(DynamicValueRegistry.GLOBAL_ID); + registryKey = tag.getString("RegistryKey").orElse("null"); initializeValueSupplier(); diff --git a/src/main/java/com/tanishisherewith/dynamichud/widget/Widget.java b/src/main/java/com/tanishisherewith/dynamichud/widget/Widget.java index 7838d34..a385042 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/widget/Widget.java +++ b/src/main/java/com/tanishisherewith/dynamichud/widget/Widget.java @@ -315,7 +315,7 @@ protected void drawWidgetBackground(DrawContext context) { int backgroundColor = this.isVisible() ? GlobalConfig.get().getHudActiveColor().getRGB() : GlobalConfig.get().getHudInactiveColor().getRGB(); WidgetBox box = this.getWidgetBox(); - DrawHelper.drawRectangle(context.getMatrices().peek().getPositionMatrix(), + DrawHelper.drawRectangle(context, box.x, box.y, box.getWidth(), @@ -331,16 +331,16 @@ protected void setTooltipText(Text text) { } public void readFromTag(NbtCompound tag) { - modId = tag.getString("modId"); - uid = new UID(tag.getString("UID")); + modId = tag.getString("modId").orElse("unknown"); + uid = tag.contains("UID") ? new UID(tag.getString("UID").get()) : UID.generate(); // x = tag.getInt("x"); // y = tag.getInt("y"); - anchor = Anchor.valueOf(tag.getString("anchor")); - offsetX = tag.getInt("offsetX"); - offsetY = tag.getInt("offsetY"); - isVisible = tag.getBoolean("isVisible"); - isDraggable = tag.getBoolean("isDraggable"); - shouldScale = tag.getBoolean("shouldScale"); + anchor = Anchor.valueOf(tag.getString("anchor").orElse("CENTER")); + offsetX = tag.getInt("offsetX").orElse(0); + offsetY = tag.getInt("offsetY").orElse(0); + isVisible = tag.getBoolean("isVisible").orElse(true); + isDraggable = tag.getBoolean("isDraggable").orElse(true); + shouldScale = tag.getBoolean("shouldScale").orElse(true); } /** diff --git a/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetManager.java b/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetManager.java index f32809c..1f0f05e 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetManager.java +++ b/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetManager.java @@ -196,15 +196,16 @@ public static List loadWidgets(File file) throws IOException { printWarn("RootTag is null. File is either empty or corrupted: " + file); return Collections.emptyList(); } - NbtList widgetList = rootTag.getList("widgets", NbtElement.COMPOUND_TYPE); + NbtList widgetList = rootTag.getList("widgets").orElse(null); if (widgetList == null) { printWarn("WidgetList is null. File is empty: " + file); return Collections.emptyList(); } List widgetsToAdd = new ArrayList<>(); for (int i = 0; i < widgetList.size(); i++) { - NbtCompound widgetTag = widgetList.getCompound(i); - WidgetData widgetData = widgetDataMap.get(widgetTag.getString("name")); + NbtCompound widgetTag = widgetList.getCompound(i).orElse(null); + if(widgetTag == null) continue; + WidgetData widgetData = widgetDataMap.get(widgetTag.getString("name").orElse("unknown")); if (widgetData == null) { throw new IllegalStateException("A Widget named '" + widgetTag.getString("name") + "' was found in the save file, but no matching WidgetData for its class could be located. This may indicate that the mod responsible for saving this widget has been removed or its implementation is incorrect."); } diff --git a/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetRenderer.java b/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetRenderer.java index 167d8d9..d0bc2f1 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetRenderer.java +++ b/src/main/java/com/tanishisherewith/dynamichud/widget/WidgetRenderer.java @@ -21,7 +21,7 @@ public class WidgetRenderer implements Input { public Widget selectedWidget = null; List widgets; private boolean renderInGameHud = true; - private int Z_Index = 100; + private int Z_Index = -1; /** * Add the list of widgets the widgetRenderer should render diff --git a/src/main/java/com/tanishisherewith/dynamichud/widgets/GraphWidget.java b/src/main/java/com/tanishisherewith/dynamichud/widgets/GraphWidget.java index 83c4ce7..e2e0d44 100644 --- a/src/main/java/com/tanishisherewith/dynamichud/widgets/GraphWidget.java +++ b/src/main/java/com/tanishisherewith/dynamichud/widgets/GraphWidget.java @@ -1,10 +1,10 @@ package com.tanishisherewith.dynamichud.widgets; -import com.mojang.blaze3d.systems.RenderSystem; import com.tanishisherewith.dynamichud.config.GlobalConfig; import com.tanishisherewith.dynamichud.helpers.ColorHelper; import com.tanishisherewith.dynamichud.helpers.DrawHelper; import com.tanishisherewith.dynamichud.helpers.animationhelper.animations.MathAnimations; +import com.tanishisherewith.dynamichud.utils.CustomRenderLayers; import com.tanishisherewith.dynamichud.utils.DynamicValueRegistry; import com.tanishisherewith.dynamichud.utils.contextmenu.ContextMenu; import com.tanishisherewith.dynamichud.utils.contextmenu.ContextMenuManager; @@ -13,13 +13,13 @@ import com.tanishisherewith.dynamichud.utils.contextmenu.options.BooleanOption; import com.tanishisherewith.dynamichud.utils.contextmenu.options.ColorOption; import com.tanishisherewith.dynamichud.utils.contextmenu.options.DoubleOption; +import com.tanishisherewith.dynamichud.utils.contextmenu.options.Option; import com.tanishisherewith.dynamichud.widget.DynamicValueWidget; import com.tanishisherewith.dynamichud.widget.WidgetBox; import com.tanishisherewith.dynamichud.widget.WidgetData; import com.twelvemonkeys.lang.Validate; -import net.minecraft.client.gl.ShaderProgramKeys; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.*; +import net.minecraft.client.render.VertexConsumer; import net.minecraft.nbt.NbtCompound; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; @@ -44,6 +44,7 @@ public class GraphWidget extends DynamicValueWidget implements ContextMenuProvid private float minValue, prevMinValue; private float maxValue, prevMaxValue; private Color graphColor; + private boolean graphColorRainbow; private Color backgroundColor; private float lineThickness; private boolean showGrid; @@ -53,6 +54,10 @@ public class GraphWidget extends DynamicValueWidget implements ContextMenuProvid private String label; /// Automatically update the min and max of the graph private boolean autoUpdateRange = false; + private float stepY; + private float valueStep; + private float scale; + int offset = -2; public GraphWidget(String registryID, String registryKey, String modId, Anchor anchor, float width, float height, int maxDataPoints, float minValue, float maxValue, Color graphColor, Color backgroundColor, float lineThickness, boolean showGrid, int gridLines, String label) { super(DATA, modId, anchor, registryID, registryKey); @@ -73,11 +78,16 @@ public GraphWidget(String registryID, String registryKey, String modId, Anchor a createMenu(); ContextMenuManager.getInstance().registerProvider(this); } - private void internal_init(){ + + private void internal_init() { Validate.isTrue(maxDataPoints > 2, "MaxDataPoints should be more than 2."); this.dataPoints = new float[maxDataPoints]; this.label = label.trim(); this.widgetBox = new WidgetBox(x, y, (int) width, (int) height); + this.stepY = height / (gridLines + 1); + this.valueStep = (maxValue - minValue) / (gridLines + 1); + this.scale = (float) MathHelper.clamp((stepY / 9.5), 0.0f, 1.0f); + computeOffset(); setTooltipText(Text.of("Graph displaying: " + label)); } @@ -151,122 +161,119 @@ private List getInterpolatedPoints() { } // draw a continuous interpolated curve - private void drawInterpolatedCurve(Matrix4f matrix, List points, int color, float thickness) { + private void drawInterpolatedCurve(DrawContext drawContext, List points, int color, float thickness) { if (points.size() < 2) return; - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR); - - for (int i = 0; i < points.size(); i++) { - float[] point = points.get(i); - float x = point[0]; - float y = point[1]; + drawContext.draw(vcp -> { + Matrix4f matrix = drawContext.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(CustomRenderLayers.TRIANGLE_STRIP); - // Create a thick line by offsetting vertices perpendicular to the curve - float dx = (i < points.size() - 1) ? points.get(i + 1)[0] - x : x - points.get(i - 1)[0]; - float dy = (i < points.size() - 1) ? points.get(i + 1)[1] - y : y - points.get(i - 1)[1]; - float length = (float) Math.sqrt(dx * dx + dy * dy); - if (length == 0) continue; + for (int i = 0; i < points.size(); i++) { + float[] point = points.get(i); + float x = point[0]; + float y = point[1]; - float offsetX = (thickness * 0.5f * dy) / length; - float offsetY = (thickness * 0.5f * -dx) / length; + // Create a thick line by offsetting vertices perpendicular to the curve + float dx = (i < points.size() - 1) ? points.get(i + 1)[0] - x : x - points.get(i - 1)[0]; + float dy = (i < points.size() - 1) ? points.get(i + 1)[1] - y : y - points.get(i - 1)[1]; + float length = (float) Math.sqrt(dx * dx + dy * dy); + if (length == 0) continue; - bufferBuilder.vertex(matrix, x + offsetX, y + offsetY, 0).color(color); - bufferBuilder.vertex(matrix, x - offsetX, y - offsetY, 0).color(color); - } + float offsetX = (thickness * 0.5f * dy) / length; + float offsetY = (thickness * 0.5f * -dx) / length; - RenderSystem.enableBlend(); - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + consumer.vertex(matrix, x + offsetX, y + offsetY, 0).color(color); + consumer.vertex(matrix, x - offsetX, y - offsetY, 0).color(color); + } + }); } // draw a gradient shadow under the curve - private void drawGradientShadow(Matrix4f matrix, List points, float bottomY, int startColor, int endColor) { + private void drawGradientShadow(DrawContext context, List points, float bottomY, int startColor, int endColor) { if (points.size() < 2) return; - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferBuilder = tessellator.begin(VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR); - - for (float[] point : points) { - float x = point[0]; - float y = point[1]; + context.draw(vcp -> { + Matrix4f matrix = context.getMatrices().peek().getPositionMatrix(); + VertexConsumer consumer = vcp.getBuffer(CustomRenderLayers.TRIANGLE_STRIP); - bufferBuilder.vertex(matrix, x, y, 0).color(startColor); - bufferBuilder.vertex(matrix, x, bottomY, 0).color(endColor); - } + for (float[] point : points) { + float x = point[0]; + float y = point[1]; - RenderSystem.enableBlend(); - RenderSystem.setShader(ShaderProgramKeys.POSITION_COLOR); - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); - RenderSystem.disableBlend(); + consumer.vertex(matrix, x, y, 0).color(startColor); + consumer.vertex(matrix, x, bottomY, 0).color(endColor); + } + }); } @Override public void renderWidget(DrawContext context, int mouseX, int mouseY) { - Matrix4f matrix = context.getMatrices().peek().getPositionMatrix(); - if (valueSupplier != null) { addDataPoint(getValue()); } - // Apply pulse1 animation to background alpha - float animatedAlpha = MathHelper.clamp(MathAnimations.pulse1(backgroundColor.getAlpha() / 255.0f, 0.2f, 0.001f), 0f, 1.0f); - Color animatedBackgroundColor = ColorHelper.changeAlpha(backgroundColor, (int) (animatedAlpha * 255)); - Color gradientColor = ColorHelper.changeAlpha(backgroundColor, (int) (animatedAlpha * 255 * 0.7f)); + // Safety check. Happens on startup + if(offset < 0) computeOffset(); + + if(graphColorRainbow) graphColor = ColorHelper.getRainbowColor(100); DrawHelper.enableScissor(widgetBox); - // Draw gradient background with rounded corners + // Draw gradient background with rounded.fsh corners if (!isInEditor) { - DrawHelper.drawRoundedGradientRectangle( - matrix, - animatedBackgroundColor, - gradientColor, - gradientColor, - animatedBackgroundColor, - x, y, width, height, 5, - false, true, false, false + DrawHelper.drawRoundedRectangle( + context, + x + offset, + y, + false, + true, + false, + false, + width, + height, + 4, + backgroundColor.getRGB() ); } // Draw grid lines and value markings if (showGrid) { - float stepY = height / (gridLines + 1); - float valueStep = (maxValue - minValue) / (gridLines + 1); - - //TODO: The scale is too small for grid lines for than 21 (20 is the barely visible threshold) - float scale = (float) MathHelper.clamp((stepY / 9.5), 0.0f, 1.0f); + //TODO: The scale is too small when no. of grid lines is greater than 21 (20 is the barely visible threshold) for (int i = 1; i <= gridLines; i++) { float yPos = y + stepY * i; - DrawHelper.drawHorizontalLine(matrix, x, width, yPos, 0.5f, 0x4DFFFFFF); // Semi-transparent white + DrawHelper.drawHorizontalLine(context, x + offset, width, yPos, 0.5f, 0x4DFFFFFF); // Semi-transparent white // Draw value labels on the left axis float value = maxValue - (i * valueStep); String valueText = formatValue(value); + float texWidth = mc.textRenderer.getWidth(valueText) * scale; + //Scale the text to its proper position and size with grid lines DrawHelper.scaleAndPosition(context.getMatrices(), x - 2, yPos, scale); - context.drawText(mc.textRenderer, valueText, x - mc.textRenderer.getWidth(valueText), (int) (yPos - (mc.textRenderer.fontHeight * scale) / 2.0f), 0xFFFFFFFF, true); + context.drawText(mc.textRenderer, valueText, Math.round(x + offset - texWidth), (int) (yPos - (mc.textRenderer.fontHeight * scale) / 2.0f), 0xFFFFFFFF, true); DrawHelper.stopScaling(context.getMatrices()); } + // Update the offsets for the rest of the elements drawn. + x += offset; + // Draw vertical grid lines (time axis) float stepX = width / 5; // 5 vertical lines for (int i = 1; i < 5; i++) { float xPos = x + stepX * i; - DrawHelper.drawVerticalLine(matrix, xPos, y, height, 0.5f, 0x4DFFFFFF); + DrawHelper.drawVerticalLine(context, xPos, y, height, 0.5f, 0x4DFFFFFF); } } // Draw interpolated graph curve List points = getInterpolatedPoints(); - drawInterpolatedCurve(matrix, points, graphColor.getRGB(), lineThickness); + drawInterpolatedCurve(context, points, graphColor.getRGB(), lineThickness); // Draw shadow effect under the graph drawGradientShadow( - matrix, points, y + height, + context, points, y + height, ColorHelper.changeAlpha(graphColor, 50).getRGB(), 0x00000000 ); @@ -279,8 +286,8 @@ public void renderWidget(DrawContext context, int mouseX, int mouseY) { // Draw axes - DrawHelper.drawHorizontalLine(matrix, x, width, y + height - 1, 1.0f, 0xFFFFFFFF); // X-axis - DrawHelper.drawVerticalLine(matrix, x, y, height, 1.0f, 0xFFFFFFFF); // Y-axis + DrawHelper.drawHorizontalLine(context, x, width, y + height - 1, 1.0f, 0xFFFFFFFF); // X-axis + DrawHelper.drawVerticalLine(context, x, y, height, 1.0f, 0xFFFFFFFF); // Y-axis // Draw min and max value labels with formatted values /* @@ -296,7 +303,9 @@ public void renderWidget(DrawContext context, int mouseX, int mouseY) { context.drawText(mc.textRenderer, formattedMinVal, x - mc.textRenderer.getWidth(formattedMinVal), (int) (y + height - 4), 0xFFFFFFFF, true); DrawHelper.stopScaling(context.getMatrices()); - this.widgetBox.setDimensions(x, y, width, height,shouldScale, GlobalConfig.get().getScale()); + if(showGrid) x -= offset; + + this.widgetBox.setDimensions(x, y, width + offset, height, shouldScale, GlobalConfig.get().getScale()); DrawHelper.disableScissor(); if (menu != null) menu.set(getX(), getY(), (int) Math.ceil(getHeight())); @@ -305,11 +314,11 @@ public void renderWidget(DrawContext context, int mouseX, int mouseY) { // format large values (like: 1000 -> 1K, 1000000 -> 1M) private String formatValue(float value) { if (Math.abs(value) >= 1_000_000) { - return String.format("%.1fM", value / 1_000_000); + return String.format("%.1fM", value / 1_000_000).trim(); } else if (Math.abs(value) >= 1_000) { - return String.format("%.1fK", value / 1_000); + return String.format("%.1fK", value / 1_000).trim(); } else { - return String.format("%.0f", value); + return String.format("%.0f", value).trim(); } } @@ -330,13 +339,21 @@ public void createMenu() { ); menu.addOption(new DoubleOption(Text.of("Number of Grid Lines"), 1, 25, 1, - () -> (double) this.gridLines, value -> this.gridLines = value.intValue(), menu) + () -> (double) this.gridLines, value -> { + this.setGridLines(value.intValue()); + computeOffset(); + }, menu) .renderWhen(() -> this.showGrid) ); menu.addOption(new ColorOption(Text.of("Graph Line Color"), () -> this.graphColor, value -> this.graphColor = value, menu) .description(Text.of("Specify the color you want for the graph's lines")) ); + menu.addOption(new BooleanOption(Text.of("Rainbow Graph Line Color"), + () -> this.graphColorRainbow, value -> this.graphColorRainbow = value) + .description(Text.of("Color your graph line with funny rainbow")) + .withComplexity(Option.Complexity.Pro) + ); menu.addOption(new ColorOption(Text.of("Graph Background Color"), () -> this.backgroundColor, value -> this.backgroundColor = value, menu) .description(Text.of("Specify the color you want for the graph's background")) @@ -347,6 +364,20 @@ public void createMenu() { ); } + private void computeOffset(){ + // The first text is usually the largest but a negative value may occupy more width so we check the first and last text. + // Idk how this will break. + if(mc.textRenderer == null) return; + + String firstText = formatValue(maxValue - valueStep); + String lastText = formatValue(maxValue - (gridLines * valueStep)); + + offset = Math.max( + (int) Math.ceil(mc.textRenderer.getWidth(firstText) * this.scale), + (int) Math.ceil(mc.textRenderer.getWidth(lastText) * this.scale) + ); + } + public float getMinValue() { return minValue; } @@ -354,6 +385,7 @@ public float getMinValue() { public void setMinValue(float minValue) { this.prevMinValue = this.minValue; this.minValue = minValue; + this.valueStep = (maxValue - minValue) / (gridLines + 1); } public float getPrevMinValue() { @@ -367,6 +399,7 @@ public float getMaxValue() { public void setMaxValue(float maxValue) { this.prevMaxValue = this.maxValue; this.maxValue = maxValue; + this.valueStep = (maxValue - minValue) / (gridLines + 1); } public float getPrevMaxValue() { @@ -421,6 +454,9 @@ public int getGridLines() { public void setGridLines(int gridLines) { this.gridLines = gridLines; + this.stepY = height / (gridLines + 1); + this.valueStep = (maxValue - minValue) / (gridLines + 1); + this.scale = (float) MathHelper.clamp((stepY / 9.5), 0.0f, 1.0f); } public boolean isShowGrid() { @@ -468,23 +504,26 @@ public void writeToTag(NbtCompound tag) { tag.putInt("gridLines", gridLines); tag.putString("label", label); tag.putBoolean("autoUpdateRange", autoUpdateRange); + tag.putBoolean("graphColorRainbow", graphColorRainbow); } @Override public void readFromTag(NbtCompound tag) { super.readFromTag(tag); - this.width = tag.getFloat("width"); - this.height = tag.getFloat("height"); - this.maxDataPoints = tag.getInt("maxDataPoints"); - this.minValue = tag.getFloat("minValue"); - this.maxValue = tag.getFloat("maxValue"); - this.graphColor = new Color(tag.getInt("graphColor")); - this.backgroundColor = new Color(tag.getInt("backgroundColor")); - this.lineThickness = tag.getFloat("lineThickness"); - this.showGrid = tag.getBoolean("showGrid"); - this.gridLines = tag.getInt("gridLines"); - this.label = tag.getString("label"); - this.autoUpdateRange = tag.getBoolean("autoUpdateRange"); + this.width = tag.getFloat("width").orElse(100f); + this.height = tag.getFloat("height").orElse(50f); + this.maxDataPoints = tag.getInt("maxDataPoints").orElse(100); + this.minValue = tag.getFloat("minValue").orElse(0f); + this.maxValue = tag.getFloat("maxValue").orElse(1f); + this.graphColor = new Color(tag.getInt("graphColor").orElse(0xFF00FF00), true); // default green + this.backgroundColor = new Color(tag.getInt("backgroundColor").orElse(0xFF000000), true); // default black + this.lineThickness = tag.getFloat("lineThickness").orElse(1.0f); + this.showGrid = tag.getBoolean("showGrid").orElse(true); + this.gridLines = tag.getInt("gridLines").orElse(5); + this.label = tag.getString("label").orElse("Graph"); + this.autoUpdateRange = tag.getBoolean("autoUpdateRange").orElse(false); + this.graphColorRainbow = tag.getBoolean("graphColorRainbow").orElse(false); + this.setMinValue(minValue); this.setMaxValue(maxValue); @@ -504,8 +543,8 @@ public static class GraphWidgetBuilder extends DynamicValueWidgetBuilder DATA = new WidgetData<>("TextWidget", "Display Text on screen", TextWidget::new); @@ -33,9 +25,6 @@ public class TextWidget extends DynamicValueWidget implements ContextMenuProvide protected boolean rainbow; // Whether to apply a rainbow effect to the text protected int rainbowSpeed = 2; //Speed of the rainbow effect protected float rainbowSpread = 0.01f, rainbowSaturation = 1.0f, rainbowBrightness = 1.0f; - private String registryKey; - //private DynamicValueRegistry valueRegistry; - private String registryID; public TextWidget() { this(DynamicValueRegistry.GLOBAL_ID, "unknown", false, false, Color.WHITE, "unknown"); @@ -55,63 +44,46 @@ public TextWidget(String registryID, String registryKey, boolean shadow, boolean } public void createMenu() { - ContextMenuProperties properties = ContextMenuProperties.builder().skin(new ModernSkin(Color.YELLOW)).build(); - menu = new ContextMenu<>(getX(), getY(), properties); + menu = new ContextMenu<>(getX(), getY(),ContextMenuProperties.createGenericSimplified()); - // Boolean Option - menu.addOption(new BooleanOption(Text.of("Toggle Shadow"), + menu.addOption(new BooleanOption(Text.of("Shadow"), () -> this.shadow, value -> this.shadow = value, BooleanOption.BooleanType.ON_OFF) - .description(Text.of("Enable or disable text shadow"))); - - // Color Option + .description(Text.of("Adds shadow to your text")) + ); + menu.addOption(new BooleanOption(Text.of("Rainbow"), + () -> this.rainbow, value -> this.rainbow = value, + BooleanOption.BooleanType.ON_OFF) + .description(Text.of("Adds rainbow effect to your text")) + ); menu.addOption(new ColorOption(Text.of("Text Color"), () -> this.textColor, value -> this.textColor = value, menu) - .description(Text.of("Change the text color"))); - - // Double Option - menu.addOption(new DoubleOption(Text.of("Opacity"), - 0.0, 1.0, 0.1f, + .description(Text.of("Specify the color you want to add to your text")) + .renderWhen(() -> !this.rainbow) + ); + menu.addOption(new DoubleOption(Text.of("Rainbow Speed"), + 1, 5.0f, 1, + () -> (double) this.rainbowSpeed, value -> this.rainbowSpeed = value.intValue(), menu) + .renderWhen(() -> this.rainbow) + ); + menu.addOption(new DoubleOption(Text.of("Rainbow Spread"), + 0.001f, 0.15f, 0.001f, + () -> (double) this.rainbowSpread, value -> this.rainbowSpread = value.floatValue(), menu) + .renderWhen(() -> this.rainbow) + .withComplexity(Option.Complexity.Enhanced) + ); + menu.addOption(new DoubleOption(Text.of("Rainbow Saturation"), + 0, 1.0f, 0.1f, + () -> (double) this.rainbowSaturation, value -> this.rainbowSaturation = value.floatValue(), menu) + .renderWhen(() -> this.rainbow) + .withComplexity(Option.Complexity.Pro) + ); + menu.addOption(new DoubleOption(Text.of("Rainbow Brightness"), + 0, 1.0f, 0.01f, () -> (double) this.rainbowBrightness, value -> this.rainbowBrightness = value.floatValue(), menu) - .description(Text.of("Adjust text opacity"))); - - // Runnable Option - AtomicBoolean ran = new AtomicBoolean(false); - menu.addOption(new RunnableOption(Text.of("Reset Position"), - ran::get, ran::set, - () -> this.setPosition(0, 0)) - .description(Text.of("Reset widget to default position"))); - - // List Option - AtomicReference style = new AtomicReference<>("Style1"); - List styles = Arrays.asList("Style1", "Style2", "Style3"); - menu.addOption(new ListOption<>(Text.of("Text Style"), - style::get, style::set, styles) - .description(Text.of("Choose a text style"))); - - // Enum Option - menu.addOption(new EnumOption<>(Text.of("Alignment"), - () -> GroupLayout.Alignment.CENTER, value -> {}, GroupLayout.Alignment.values()) - .description(Text.of("Set text alignment"))); - - // Option Group - OptionGroup group = new OptionGroup(Text.of("Display Options")); - group.addOption(new BooleanOption(Text.of("Bold Text"), - () -> false, value -> {}, BooleanOption.BooleanType.YES_NO) - .description(Text.of("Enable bold text"))); - group.addOption(new DoubleOption(Text.of("Font Size"), - 8.0, 24.0, 1.0f, - () -> 12.0, value -> {}, menu) - .description(Text.of("Adjust font size"))); - menu.addOption(group); - - // SubMenu Option - SubMenuOption subMenu = (SubMenuOption) new SubMenuOption(Text.of("Advanced Settings"), menu) - .description(Text.of("Open advanced settings")); - subMenu.getSubMenu().addOption(new BooleanOption(Text.of("Some Boolean"), - () -> false, value -> {}, BooleanOption.BooleanType.TRUE_FALSE) - .description(Text.of("True/False"))); - menu.addOption(subMenu); + .renderWhen(() -> this.rainbow) + .withComplexity(Option.Complexity.Pro) + ); } @Override @@ -126,6 +98,7 @@ public void renderWidget(DrawContext drawContext, int mouseX, int mouseY) { } else { drawContext.drawText(mc.textRenderer, text, getX() + 2, getY() + 2, color, shadow); } + drawContext.draw(); widgetBox.setDimensions(getX(), getY(), mc.textRenderer.getWidth(text) + 3, mc.textRenderer.fontHeight + 2, this.shouldScale, GlobalConfig.get().getScale()); } menu.set(getX(), getY(), (int) Math.ceil(getHeight())); @@ -159,15 +132,15 @@ public void writeToTag(NbtCompound tag) { @Override public void readFromTag(NbtCompound tag) { super.readFromTag(tag); - shadow = tag.getBoolean("Shadow"); - rainbow = tag.getBoolean("Rainbow"); - rainbowSpeed = tag.getInt("RainbowSpeed"); - rainbowSpread = tag.getFloat("RainbowSpread"); - rainbowSaturation = tag.getFloat("RainbowSaturation"); - rainbowBrightness = tag.getFloat("RainbowBrightness"); - textColor = new Color(tag.getInt("TextColor")); - registryKey = tag.getString("RegistryKey"); - registryID = tag.getString("RegistryID"); + shadow = tag.getBoolean("Shadow").orElse(false); + rainbow = tag.getBoolean("Rainbow").orElse(false); + rainbowSpeed = tag.getInt("RainbowSpeed").orElse(1); + rainbowSpread = tag.getFloat("RainbowSpread").orElse(1.0f); + rainbowSaturation = tag.getFloat("RainbowSaturation").orElse(1.0f); + rainbowBrightness = tag.getFloat("RainbowBrightness").orElse(1.0f); + textColor = new Color(tag.getInt("TextColor").orElse(0xFFFFFFFF), true); // default white + registryKey = tag.getString("RegistryKey").orElse("default:key"); + registryID = tag.getString("RegistryID").orElse("default:id"); //createMenu(); } diff --git a/src/main/resources/assets/dynamichud/shaders/core/rounded.fsh b/src/main/resources/assets/dynamichud/shaders/core/rounded.fsh new file mode 100644 index 0000000..8fd458d --- /dev/null +++ b/src/main/resources/assets/dynamichud/shaders/core/rounded.fsh @@ -0,0 +1,28 @@ +#version 150 + +uniform sampler2D Sampler0; +uniform vec4 ColorModulator; +uniform vec4 Roundness; +uniform vec2 widthHeight; + +in vec2 texCoord0; +in vec4 vertexColor; + +out vec4 fragColor; + +float sdRoundBoxOutline(vec2 p, vec2 b, vec4 r) { + r.xy = (p.x > 0.0) ? r.xy : r.zw; + r.x = (p.y > 0.0) ? r.x : r.y; + vec2 q = abs(p) - b + r.x; + return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; +} + +void main() { + float distance = sdRoundBoxOutline(texCoord0 - widthHeight / 2, widthHeight / 2, Roundness); + float fw = fwidth(distance); + // This is what allows the rectangle to support the original color's alpha. + float alpha = smoothstep(-fw, fw, -distance) * ColorModulator.a * vertexColor.a; + vec4 color = ColorModulator * vertexColor * vec4(1, 1, 1, alpha); + if (color.a < 0.01) discard; + fragColor = color; +} \ No newline at end of file diff --git a/src/main/resources/assets/dynamichud/shaders/core/rounded.vsh b/src/main/resources/assets/dynamichud/shaders/core/rounded.vsh new file mode 100644 index 0000000..052a7c0 --- /dev/null +++ b/src/main/resources/assets/dynamichud/shaders/core/rounded.vsh @@ -0,0 +1,18 @@ +#version 150 + +in vec3 Position; +in vec2 UV0; +in vec4 Color; + +uniform mat4 ModelViewMat; +uniform mat4 ProjMat; + +out vec2 texCoord0; +out vec4 vertexColor; + +void main() { + gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0); + + texCoord0 = UV0; + vertexColor = Color; +} \ No newline at end of file diff --git a/src/main/resources/assets/dynamichud/shaders/core/rounded_outline.fsh b/src/main/resources/assets/dynamichud/shaders/core/rounded_outline.fsh new file mode 100644 index 0000000..bb0fd63 --- /dev/null +++ b/src/main/resources/assets/dynamichud/shaders/core/rounded_outline.fsh @@ -0,0 +1,37 @@ +#version 150 + +uniform sampler2D Sampler0; +uniform vec4 ColorModulator; +uniform vec4 Roundness; +uniform vec4 Thickness; +uniform vec2 widthHeight; + +in vec2 texCoord0; +in vec4 vertexColor; + +out vec4 fragColor; + +float sdRoundBoxOutline(vec2 p, vec2 b, vec4 r) { + r.xy = (p.x > 0.0) ? r.xy : r.zw; + r.x = (p.y > 0.0) ? r.x : r.y; + vec2 q = abs(p) - b + r.x; + float distance = min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; + return distance + Thickness.x * 0.5; // Shift outline boundary +} + +void main() { + float distance = sdRoundBoxOutline(texCoord0 - widthHeight / 2, widthHeight / 2, Roundness); + float fw = fwidth(distance); + + // Define strict outline boundaries + float innerEdge = smoothstep(-Thickness.x, -Thickness.x + fw, distance); + float outerEdge = smoothstep(0, fw, distance); + + // This is what allows the rectangle to support the original color's alpha uniformly thoughout. + float outlineAlpha = (innerEdge - outerEdge) * ColorModulator.a * vertexColor.a; + + vec4 color = ColorModulator * vertexColor * vec4(1, 1, 1, outlineAlpha); + + if (color.a < 0.01) discard; + fragColor = color; +} \ No newline at end of file diff --git a/src/main/resources/dynamichud.mixins.json b/src/main/resources/dynamichud.mixins.json index f5d7c16..f60e286 100644 --- a/src/main/resources/dynamichud.mixins.json +++ b/src/main/resources/dynamichud.mixins.json @@ -10,6 +10,7 @@ "defaultRequire": 1 }, "client": [ - "OptionsScreenMixin" + "OptionsScreenMixin", + "RenderLayerMixin" ] } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 6ff31d0..a6ef3cf 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,6 +32,7 @@ "fabricloader": ">=${loader_version}", "fabric": "*", "java": ">=21", + "fabric-api": "*", "minecraft": "~${minecraft_version}" }, "custom": { @@ -42,6 +43,6 @@ } }, "suggests": { - "yet_another_config_lib_v3": ">=3.6.6+1.21.4-fabric" + "yet_another_config_lib_v3": ">=${yacl_version}" } }