-
Notifications
You must be signed in to change notification settings - Fork 30
/
UICircle.kt
109 lines (89 loc) · 3.33 KB
/
UICircle.kt
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
package gg.essential.elementa.components
import gg.essential.elementa.UIComponent
import gg.essential.elementa.dsl.toConstraint
import gg.essential.elementa.dsl.pixels
import gg.essential.elementa.utils.readFromLegacyShader
import gg.essential.universal.UMatrixStack
import gg.essential.universal.shader.BlendState
import gg.essential.universal.shader.Float2Uniform
import gg.essential.universal.shader.FloatUniform
import gg.essential.universal.shader.UShader
import java.awt.Color
/**
* Simple component that uses shaders to draw a circle. This component
* takes a radius instead of a height/width!
*
* @param radius circle radius
* @param color circle color
* @param steps unused, kept for backwards compatibility
*/
class UICircle @JvmOverloads constructor(radius: Float = 0f, color: Color = Color.WHITE, var steps: Int = 0) :
UIComponent() {
init {
setColor(color.toConstraint())
setRadius(radius.pixels())
}
override fun getLeft(): Float {
return constraints.getX() - getRadius()
}
override fun getTop(): Float {
return constraints.getY() - getRadius()
}
override fun getWidth(): Float {
return getRadius() * 2
}
override fun getHeight(): Float {
return getRadius() * 2
}
override fun isPositionCenter(): Boolean {
return true
}
override fun draw(matrixStack: UMatrixStack) {
beforeDraw(matrixStack)
val x = constraints.getX()
val y = constraints.getY()
val r = getRadius()
val color = getColor()
if (color.alpha == 0) return super.draw(matrixStack)
drawCircle(matrixStack, x, y, r, color)
super.draw(matrixStack)
}
companion object {
private lateinit var shader: UShader
private lateinit var shaderRadiusUniform: FloatUniform
private lateinit var shaderCenterPositionUniform: Float2Uniform
fun initShaders() {
if (::shader.isInitialized)
return
shader = UShader.readFromLegacyShader("rect", "circle", BlendState.NORMAL)
if (!shader.usable) {
println("Failed to load Elementa UICircle shader")
return
}
shaderRadiusUniform = shader.getFloatUniform("u_Radius")
shaderCenterPositionUniform = shader.getFloat2Uniform("u_CenterPos")
}
@Deprecated(
UMatrixStack.Compat.DEPRECATED,
ReplaceWith("drawCircle(matrixStack, centerX, centerY, radius, color)"),
)
fun drawCircle(centerX: Float, centerY: Float, radius: Float, color: Color) =
drawCircle(UMatrixStack(), centerX, centerY, radius, color)
fun drawCircle(matrixStack: UMatrixStack, centerX: Float, centerY: Float, radius: Float, color: Color) {
if (!::shader.isInitialized || !shader.usable)
return
shader.bind()
shaderRadiusUniform.setValue(radius)
shaderCenterPositionUniform.setValue(centerX, centerY)
UIBlock.drawBlockWithActiveShader(
matrixStack,
color,
(centerX - radius).toDouble(),
(centerY - radius).toDouble(),
(centerX + radius).toDouble(),
(centerY + radius).toDouble()
)
shader.unbind()
}
}
}