forked from SparkUniverse/Elementa
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUIRoundedRectangle.kt
More file actions
122 lines (104 loc) · 4.96 KB
/
UIRoundedRectangle.kt
File metadata and controls
122 lines (104 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package gg.essential.elementa.components
import gg.essential.elementa.ElementaVersion
import gg.essential.elementa.UIComponent
import gg.essential.elementa.dsl.pixels
import gg.essential.elementa.utils.readElementaShaderSource
import gg.essential.elementa.utils.readFromLegacyShader
import gg.essential.universal.UGraphics
import gg.essential.universal.UMatrixStack
import gg.essential.universal.render.URenderPipeline
import gg.essential.universal.shader.BlendState
import gg.essential.universal.shader.Float4Uniform
import gg.essential.universal.shader.FloatUniform
import gg.essential.universal.shader.UShader
import gg.essential.universal.vertex.UBufferBuilder
import java.awt.Color
/**
* Alternative to [UIBlock] with rounded corners.
*
* @param radius corner radius.
*/
open class UIRoundedRectangle(radius: Float) : UIComponent() {
init {
setRadius(radius.pixels())
}
override fun draw(matrixStack: UMatrixStack) {
beforeDrawCompat(matrixStack)
val radius = getRadius()
val color = getColor()
if (color.alpha != 0)
drawRoundedRectangle(matrixStack, getLeft(), getTop(), getRight(), getBottom(), radius, color)
super.draw(matrixStack)
}
companion object {
private lateinit var shader: UShader
private lateinit var shaderRadiusUniform: FloatUniform
private lateinit var shaderInnerRectUniform: Float4Uniform
private val PIPELINE = URenderPipeline.builderWithLegacyShader(
"elementa:rounded_rectangle",
UGraphics.DrawMode.QUADS,
UGraphics.CommonVertexFormats.POSITION_COLOR,
readElementaShaderSource("rect", "vsh"),
readElementaShaderSource("rounded_rect", "fsh"),
).apply {
@Suppress("DEPRECATION")
blendState = BlendState.NORMAL
depthTest = URenderPipeline.DepthTest.Always // see UIBlock.PIPELINE
}.build()
private val PIPELINE2 = URenderPipeline.builderWithLegacyShader(
"elementa:rounded_rectangle",
UGraphics.DrawMode.QUADS,
UGraphics.CommonVertexFormats.POSITION_COLOR,
readElementaShaderSource("rect", "vsh"),
readElementaShaderSource("rounded_rect", "fsh"),
).apply {
blendState = BlendState.ALPHA
depthTest = URenderPipeline.DepthTest.Always // see UIBlock.PIPELINE
}.build()
fun initShaders() {
if (URenderPipeline.isRequired) return
if (::shader.isInitialized)
return
@Suppress("DEPRECATION")
shader = UShader.readFromLegacyShader("rect", "rounded_rect", BlendState.NORMAL)
if (!shader.usable) {
println("Failed to load Elementa UIRoundedRectangle shader")
return
}
shaderRadiusUniform = shader.getFloatUniform("u_Radius")
shaderInnerRectUniform = shader.getFloat4Uniform("u_InnerRect")
}
@Deprecated(
UMatrixStack.Compat.DEPRECATED,
ReplaceWith("drawRoundedRectangle(matrixStack, left, top, right, bottom, radius, color)"),
)
fun drawRoundedRectangle(left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) =
drawRoundedRectangle(UMatrixStack(), left, top, right, bottom, radius, color)
/**
* Draws a rounded rectangle
*/
fun drawRoundedRectangle(matrixStack: UMatrixStack, left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) {
if (!URenderPipeline.isRequired && !ElementaVersion.atLeastV9Active) {
@Suppress("DEPRECATION")
return drawRoundedRectangleLegacy(matrixStack, left, top, right, bottom, radius, color)
}
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
UIBlock.drawBlock(bufferBuilder, matrixStack, color, left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble())
bufferBuilder.build()?.drawAndClose(if (ElementaVersion.atLeastV10Active) PIPELINE2 else PIPELINE) {
uniform("u_Radius", radius)
uniform("u_InnerRect", left + radius, top + radius, right - radius, bottom - radius)
}
}
@Deprecated("Stops working in 1.21.5")
@Suppress("DEPRECATION")
private fun drawRoundedRectangleLegacy(matrixStack: UMatrixStack, left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) {
if (!::shader.isInitialized || !shader.usable)
return
shader.bind()
shaderRadiusUniform.setValue(radius)
shaderInnerRectUniform.setValue(left + radius, top + radius, right - radius, bottom - radius)
UIBlock.drawBlockWithActiveShader(matrixStack, color, left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble())
shader.unbind()
}
}
}