diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt index 3d4e6daadf76..ebbb7fa3074c 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/RenderBackground.kt @@ -7,7 +7,6 @@ import at.hannibal2.skyhanni.data.GuiEditManager.getAbsY import at.hannibal2.skyhanni.data.GuiEditManager.getDummySize import at.hannibal2.skyhanni.utils.ColorUtils.toChromaColor import at.hannibal2.skyhanni.utils.RenderUtils -import io.github.moulberry.notenoughupdates.util.Utils import net.minecraft.client.Minecraft import net.minecraft.client.gui.ScaledResolution import net.minecraft.client.renderer.GlStateManager @@ -49,12 +48,13 @@ class RenderBackground { val textureLocation = ResourceLocation("skyhanni", "scoreboard.png") Minecraft.getMinecraft().textureManager.bindTexture(textureLocation) - Utils.drawTexturedRect( - (x - border).toFloat(), - (y - border).toFloat(), - (elementWidth + border * 3).toFloat(), - (elementHeight + border * 2).toFloat(), - GL11.GL_NEAREST + RenderUtils.drawRoundTexturedRect( + x - border, + y - border, + elementWidth + border * 3, + elementHeight + border * 2, + GL11.GL_NEAREST, + backgroundConfig.roundedCornerSmoothness, ) } else { RenderUtils.drawRoundRect( @@ -63,7 +63,7 @@ class RenderBackground { elementWidth + border * 3, elementHeight + border * 2, backgroundConfig.color.toChromaColor().rgb, - backgroundConfig.roundedCornerSmoothness + backgroundConfig.roundedCornerSmoothness, ) } if (outlineConfig.enabled) { @@ -76,7 +76,7 @@ class RenderBackground { outlineConfig.colorBottom.toChromaColor().rgb, outlineConfig.thickness, backgroundConfig.roundedCornerSmoothness, - outlineConfig.blur + outlineConfig.blur, ) } } @@ -133,7 +133,7 @@ class RenderBackground { newX, newY, position.getScale(), - position.isCenter + position.isCenter, ) } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/RoundedRectangleShader.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/RoundedShader.kt similarity index 75% rename from src/main/java/at/hannibal2/skyhanni/features/misc/RoundedRectangleShader.kt rename to src/main/java/at/hannibal2/skyhanni/features/misc/RoundedShader.kt index 9ce2d0ce71ca..ab4b1165c2be 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/RoundedRectangleShader.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/RoundedShader.kt @@ -4,10 +4,7 @@ import at.hannibal2.skyhanni.utils.shader.Shader import at.hannibal2.skyhanni.utils.shader.Uniform import net.minecraft.client.Minecraft -object RoundedRectangleShader : Shader("rounded_rect", "rounded_rect") { - - val INSTANCE: RoundedRectangleShader - get() = this +abstract class RoundedShader(vertex: String, fragment: String) : Shader(vertex, fragment) { var scaleFactor: Float = 0f var radius: Float = 0f @@ -26,3 +23,15 @@ object RoundedRectangleShader : Shader("rounded_rect", "rounded_rect") { registerUniform(Uniform.UniformType.VEC2, "centerPos") { centerPos } } } + +object RoundedRectangleShader : RoundedShader("rounded_rect", "rounded_rect") { + + val INSTANCE: RoundedRectangleShader + get() = this +} + +object RoundedTextureShader : RoundedShader("rounded_texture", "rounded_texture") { + + val INSTANCE: RoundedTextureShader + get() = this +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index d32ff9ea947f..9ff6053e791b 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -13,6 +13,7 @@ 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.features.misc.RoundedTextureShader import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.CollectionUtils.zipWithNext3 import at.hannibal2.skyhanni.utils.ColorUtils.getFirstColorCode @@ -1719,6 +1720,48 @@ object RenderUtils { GlStateManager.enableDepth() } + + /** + * Method to draw a rounded textured rect. + * + * **NOTE:** If you are using [GlStateManager.translate] or [GlStateManager.scale] + * with this method, ensure they are invoked in the correct order if you use both. That is, [GlStateManager.translate] + * is called **BEFORE** [GlStateManager.scale], otherwise the textured rect will not be rendered correctly + * + * @param filter the texture filter to use + * @param radius the radius of the corners (default 10), NOTE: If you pass less than 1 it will just draw as a normal textured rect + * @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. + */ + fun drawRoundTexturedRect(x: Int, y: Int, width: Int, height: Int, filter: Int, radius: Int = 10, smoothness: Int = 1) { + // if radius is 0 then just draw a normal textured rect + if (radius <= 0) { + Utils.drawTexturedRect(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), filter) + return + } + + 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 + + RoundedTextureShader.scaleFactor = scaledRes.scaleFactor.toFloat() + RoundedTextureShader.radius = radius.toFloat() + RoundedTextureShader.smoothness = smoothness.toFloat() + RoundedTextureShader.halfSize = floatArrayOf(widthIn / 2f, heightIn / 2f) + RoundedTextureShader.centerPos = floatArrayOf(xIn + (widthIn / 2f), yIn + (heightIn / 2f)) + + GlStateManager.pushMatrix() + ShaderManager.enableShader(ShaderManager.Shaders.ROUNDED_TEXTURE) + + Utils.drawTexturedRect(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), filter) + + ShaderManager.disableShader() + GlStateManager.popMatrix() + } + /** * Method to draw a rounded rectangle. * 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 39a2fe302d3a..ed4dbabdfe6c 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/shader/ShaderManager.kt @@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.features.chroma.TexturedChromaShader import at.hannibal2.skyhanni.features.misc.DarkenShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleOutlineShader import at.hannibal2.skyhanni.features.misc.RoundedRectangleShader +import at.hannibal2.skyhanni.features.misc.RoundedTextureShader import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.LorenzUtils import net.minecraft.client.Minecraft @@ -28,6 +29,7 @@ object ShaderManager { TEXTURED_CHROMA(TexturedChromaShader.INSTANCE), ROUNDED_RECTANGLE(RoundedRectangleShader.INSTANCE), ROUNDED_RECT_OUTLINE(RoundedRectangleOutlineShader.INSTANCE), + ROUNDED_TEXTURE(RoundedTextureShader.INSTANCE), DARKEN(DarkenShader.INSTANCE) ; diff --git a/src/main/resources/assets/skyhanni/shaders/rounded_texture.fsh b/src/main/resources/assets/skyhanni/shaders/rounded_texture.fsh new file mode 100644 index 000000000000..a38ebc4eac00 --- /dev/null +++ b/src/main/resources/assets/skyhanni/shaders/rounded_texture.fsh @@ -0,0 +1,37 @@ +#version 120 + +uniform float scaleFactor; +uniform float radius; +uniform float smoothness; +uniform vec2 halfSize; +uniform vec2 centerPos; + +uniform sampler2D outTexture; + +varying vec2 outTextureCoords; +varying vec4 outColor; + +// From https://www.shadertoy.com/view/WtdSDs +float roundedRectSDF(vec2 center, vec2 halfSize, float radius) { + return length(max(abs(center) - halfSize + radius, 0.0)) - radius; +} + +void main() { + float xScale = gl_ModelViewMatrix[0][0]; + float yScale = gl_ModelViewMatrix[1][1]; + float xTranslation = gl_ModelViewMatrix[3][0]; + float yTranslation = gl_ModelViewMatrix[3][1]; + + vec2 newHalfSize = vec2(halfSize.x * xScale, halfSize.y * yScale); + + float newCenterPosY = centerPos.y; + if (yScale > 1.0) { + newCenterPosY = centerPos.y - (halfSize.y * (yScale - 1)); + } + + vec2 newCenterPos = vec2((centerPos.x * xScale) + (xTranslation * scaleFactor), newCenterPosY - (yTranslation * scaleFactor)); + + float distance = roundedRectSDF(gl_FragCoord.xy - newCenterPos, newHalfSize, radius); + float smoothed = 1.0 - smoothstep(0.0, smoothness, distance); + gl_FragColor = (texture2D(outTexture, outTextureCoords) * outColor) * vec4(1.0, 1.0, 1.0, smoothed); +} diff --git a/src/main/resources/assets/skyhanni/shaders/rounded_texture.vsh b/src/main/resources/assets/skyhanni/shaders/rounded_texture.vsh new file mode 100644 index 000000000000..227f964a1211 --- /dev/null +++ b/src/main/resources/assets/skyhanni/shaders/rounded_texture.vsh @@ -0,0 +1,10 @@ +#version 120 + +varying vec2 outTextureCoords; +varying vec4 outColor; + +void main(){ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + outColor = gl_Color; + outTextureCoords = gl_MultiTexCoord0.st; +}