From a15ef68de8e33df296c565d12994df2ee965626e Mon Sep 17 00:00:00 2001 From: Vixid <52578495+VixidDev@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:07:55 +0100 Subject: Improvement: Added Outline to Custom Scoreboard (#1461) Co-authored-by: J10a1n15 <45315647+j10a1n15@users.noreply.github.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../at/hannibal2/skyhanni/utils/RenderUtils.kt | 105 ++++++++++++++++++++- .../utils/renderables/RenderLineTooltips.kt | 61 ++---------- .../at/hannibal2/skyhanni/utils/shader/Shader.kt | 6 ++ .../skyhanni/utils/shader/ShaderManager.kt | 3 + 4 files changed, 122 insertions(+), 53 deletions(-) (limited to 'src/main/java/at/hannibal2/skyhanni/utils') diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 0ea8b76eb..b89850608 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getDummySize import at.hannibal2.skyhanni.events.GuiRenderItemEvent import at.hannibal2.skyhanni.events.LorenzRenderWorldEvent import at.hannibal2.skyhanni.events.RenderGuiItemOverlayEvent +import at.hannibal2.skyhanni.features.misc.RoundedRectangleOutlineShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleShader import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.renderables.Renderable @@ -34,6 +35,7 @@ import net.minecraft.util.ResourceLocation import org.lwjgl.opengl.GL11 import java.awt.Color import kotlin.math.cos +import kotlin.math.max import kotlin.math.sin import kotlin.math.sqrt import kotlin.time.Duration @@ -1472,7 +1474,7 @@ object RenderUtils { * * @param color color of rect * @param radius the radius of the corners (default 10) - * @param smoothness how smooth the corners will appear (default 2). NOTE: This does very + * @param smoothness how smooth the corners will appear (default 1). NOTE: This does very * little to the smoothness of the corners in reality due to how the final pixel color is calculated. * It is best kept at its default. */ @@ -1492,12 +1494,111 @@ object RenderUtils { GlStateManager.pushMatrix() ShaderManager.enableShader("rounded_rect") - Gui.drawRect(x, y, x + width, y + height, color) + Gui.drawRect(x - 5, y - 5, x + width + 5, y + height + 5, color) ShaderManager.disableShader() GlStateManager.popMatrix() } + /** + * Method to draw the outline of a rounded rectangle with a color gradient. For a single color just pass + * in the color to both topColor and bottomColor. + * + * This is *not* a method that draws a rounded rectangle **with** an outline, rather, this draws **only** the outline. + * + * **NOTE:** The same notices given from [drawRoundRect] should be acknowledged with this method also. + * + * @param topColor color of the top of the outline + * @param bottomColor color of the bottom of the outline + * @param borderThickness the thickness of the border + * @param radius radius of the corners of the rectangle (default 10) + * @param blur the amount to blur the outline (default 0.7f) + */ + fun drawRoundRectOutline( + x: Int, + y: Int, + width: Int, + height: Int, + topColor: Int, + bottomColor: Int, + borderThickness: Int, + radius: Int = 10, + blur: Float = 0.7f, + ) { + val scaledRes = ScaledResolution(Minecraft.getMinecraft()) + val widthIn = width * scaledRes.scaleFactor + val heightIn = height * scaledRes.scaleFactor + val xIn = x * scaledRes.scaleFactor + val yIn = y * scaledRes.scaleFactor + + val borderAdjustment = borderThickness / 2 + + RoundedRectangleOutlineShader.scaleFactor = scaledRes.scaleFactor.toFloat() + RoundedRectangleOutlineShader.radius = radius.toFloat() + RoundedRectangleOutlineShader.halfSize = floatArrayOf(widthIn / 2f, heightIn / 2f) + RoundedRectangleOutlineShader.centerPos = floatArrayOf(xIn + (widthIn / 2f), yIn + (heightIn / 2f)) + RoundedRectangleOutlineShader.borderThickness = borderThickness.toFloat() + // The blur argument is a bit misleading, the greater the value the more sharp the edges of the + // outline will be and the smaller the value the blurrier. So we take the difference from 1 + // so the shader can blur the edges accordingly. This is because a 'blurriness' option makes more sense + // to users than a 'sharpness' option in this context + RoundedRectangleOutlineShader.borderBlur = max(1 - blur, 0f) + + GlStateManager.pushMatrix() + ShaderManager.enableShader("rounded_rect_outline") + + drawGradientRect( + x - borderAdjustment, + y - borderAdjustment, + x + width + borderAdjustment, + y + height + borderAdjustment, + topColor, + bottomColor + ) + + ShaderManager.disableShader() + GlStateManager.popMatrix() + } + + fun drawGradientRect( + left: Int, + top: Int, + right: Int, + bottom: Int, + startColor: Int = -0xfeffff0, + endColor: Int = -0xfeffff0, + ) { + val startAlpha = (startColor shr 24 and 255).toFloat() / 255.0f + val startRed = (startColor shr 16 and 255).toFloat() / 255.0f + val startGreen = (startColor shr 8 and 255).toFloat() / 255.0f + val startBlue = (startColor and 255).toFloat() / 255.0f + val endAlpha = (endColor shr 24 and 255).toFloat() / 255.0f + val endRed = (endColor shr 16 and 255).toFloat() / 255.0f + val endGreen = (endColor shr 8 and 255).toFloat() / 255.0f + val endBlue = (endColor and 255).toFloat() / 255.0f + GlStateManager.disableTexture2D() + GlStateManager.enableBlend() + GlStateManager.disableAlpha() + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) + GlStateManager.shadeModel(7425) + val tessellator = Tessellator.getInstance() + val worldrenderer = tessellator.worldRenderer + worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR) + worldrenderer.pos(right.toDouble(), top.toDouble(), 0.0) + .color(startRed, startGreen, startBlue, startAlpha).endVertex() + worldrenderer.pos(left.toDouble(), top.toDouble(), 0.0) + .color(startRed, startGreen, startBlue, startAlpha).endVertex() + worldrenderer.pos(left.toDouble(), bottom.toDouble(), 0.0) + .color(endRed, endGreen, endBlue, endAlpha).endVertex() + worldrenderer.pos(right.toDouble(), bottom.toDouble(), 0.0) + .color(endRed, endGreen, endBlue, endAlpha).endVertex() + tessellator.draw() + GlStateManager.shadeModel(7424) + GlStateManager.disableBlend() + GlStateManager.enableAlpha() + GlStateManager.enableTexture2D() + } + // TODO move off of neu function fun drawTexturedRect(x: Float, y: Float) { with(ScaledResolution(Minecraft.getMinecraft())) { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt index cc5404039..09ab434d0 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt @@ -5,14 +5,12 @@ import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.RenderUtils import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned import io.github.moulberry.notenoughupdates.util.Utils +import java.awt.Color import net.minecraft.client.Minecraft import net.minecraft.client.gui.ScaledResolution import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.RenderHelper -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.vertex.DefaultVertexFormats import net.minecraft.item.ItemStack -import java.awt.Color object RenderLineTooltips { @@ -66,38 +64,38 @@ object RenderLineTooltips { val zLevel = 300f GlStateManager.translate(tooltipX.toFloat(), tooltipY.toFloat(), zLevel) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = -4, right = tooltipTextWidth + 3, bottom = -3, ) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = tooltipHeight + 3, right = tooltipTextWidth + 3, bottom = tooltipHeight + 4, ) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = -3, right = tooltipTextWidth + 3, bottom = tooltipHeight + 3, ) - drawGradientRect( + RenderUtils.drawGradientRect( left = -4, top = -3, right = -3, bottom = tooltipHeight + 3, ) - drawGradientRect( + RenderUtils.drawGradientRect( left = tooltipTextWidth + 3, top = -3, right = tooltipTextWidth + 4, bottom = tooltipHeight + 3, ) val borderColorEnd = borderColorStart and 0xFEFEFE shr 1 or (borderColorStart and -0x1000000) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = -3 + 1, right = -3 + 1, @@ -105,7 +103,7 @@ object RenderLineTooltips { startColor = borderColorStart, endColor = borderColorEnd ) - drawGradientRect( + RenderUtils.drawGradientRect( left = tooltipTextWidth + 2, top = -3 + 1, right = tooltipTextWidth + 3, @@ -113,7 +111,7 @@ object RenderLineTooltips { startColor = borderColorStart, endColor = borderColorEnd ) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = -3, right = tooltipTextWidth + 3, @@ -121,7 +119,7 @@ object RenderLineTooltips { startColor = borderColorStart, endColor = borderColorStart ) - drawGradientRect( + RenderUtils.drawGradientRect( left = -3, top = tooltipHeight + 2, right = tooltipTextWidth + 3, @@ -147,43 +145,4 @@ object RenderLineTooltips { GlStateManager.enableRescaleNormal() GlStateManager.disableLighting() } - - private fun drawGradientRect( - left: Int, - top: Int, - right: Int, - bottom: Int, - startColor: Int = -0xfeffff0, - endColor: Int = -0xfeffff0, - ) { - val startAlpha = (startColor shr 24 and 255).toFloat() / 255.0f - val startRed = (startColor shr 16 and 255).toFloat() / 255.0f - val startGreen = (startColor shr 8 and 255).toFloat() / 255.0f - val startBlue = (startColor and 255).toFloat() / 255.0f - val endAlpha = (endColor shr 24 and 255).toFloat() / 255.0f - val endRed = (endColor shr 16 and 255).toFloat() / 255.0f - val endGreen = (endColor shr 8 and 255).toFloat() / 255.0f - val endBlue = (endColor and 255).toFloat() / 255.0f - GlStateManager.disableTexture2D() - GlStateManager.enableBlend() - GlStateManager.disableAlpha() - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0) - GlStateManager.shadeModel(7425) - val tessellator = Tessellator.getInstance() - val worldrenderer = tessellator.worldRenderer - worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR) - worldrenderer.pos(right.toDouble(), top.toDouble(), 0.0) - .color(startRed, startGreen, startBlue, startAlpha).endVertex() - worldrenderer.pos(left.toDouble(), top.toDouble(), 0.0) - .color(startRed, startGreen, startBlue, startAlpha).endVertex() - worldrenderer.pos(left.toDouble(), bottom.toDouble(), 0.0) - .color(endRed, endGreen, endBlue, endAlpha).endVertex() - worldrenderer.pos(right.toDouble(), bottom.toDouble(), 0.0) - .color(endRed, endGreen, endBlue, endAlpha).endVertex() - tessellator.draw() - GlStateManager.shadeModel(7424) - GlStateManager.disableBlend() - GlStateManager.enableAlpha() - GlStateManager.enableTexture2D() - } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt index 03b2fb3ac..8bbe5bba3 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/Shader.kt @@ -100,6 +100,12 @@ abstract class Shader(val vertex: String, val fragment: String) { fun disable() = ShaderHelper.glUseProgram(0) + /** + * @param uniformType Type of uniform, there should be a 1 to 1 equivalent to that in the shader file + * @param name The name of the uniform in the shader file. This should match exactly to the name given + * to the uniform in the shader file. + * @param uniformValuesSupplier The supplier that changes / sets the uniform's value + */ fun registerUniform(uniformType: Uniform.UniformType, name: String, uniformValuesSupplier: Supplier) { uniforms.add(Uniform(this, uniformType, name, uniformValuesSupplier)) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt index 3c6bc5ce0..3efcb0b77 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt @@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.utils.shader import at.hannibal2.skyhanni.features.chroma.StandardChromaShader import at.hannibal2.skyhanni.features.chroma.TexturedChromaShader +import at.hannibal2.skyhanni.features.misc.RoundedRectangleOutlineShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleShader import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils @@ -25,6 +26,7 @@ object ShaderManager { STANDARD_CHROMA(StandardChromaShader.INSTANCE), TEXTURED_CHROMA(TexturedChromaShader.INSTANCE), ROUNDED_RECTANGLE(RoundedRectangleShader.INSTANCE), + ROUNDED_RECT_OUTLINE(RoundedRectangleOutlineShader.INSTANCE), ; companion object { @@ -33,6 +35,7 @@ object ShaderManager { "standard_chroma" -> STANDARD_CHROMA.shader "textured_chroma" -> TEXTURED_CHROMA.shader "rounded_rect" -> ROUNDED_RECTANGLE.shader + "rounded_rect_outline" -> ROUNDED_RECT_OUTLINE.shader else -> { null } -- cgit