Skip to content

Commit f9c95e8

Browse files
authored
Build: Add support for Minecraft 1.21.5
GitHub: #162
1 parent ef58dbc commit f9c95e8

File tree

20 files changed

+350
-59
lines changed

20 files changed

+350
-59
lines changed

api/Elementa.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ public class gg/essential/elementa/components/UIBlock : gg/essential/elementa/UI
554554

555555
public final class gg/essential/elementa/components/UIBlock$Companion {
556556
public final fun drawBlock (Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
557+
public final fun drawBlock (Lgg/essential/universal/vertex/UVertexConsumer;Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
557558
public final fun drawBlock (Ljava/awt/Color;DDDD)V
558559
public final fun drawBlockSized (Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
559560
public final fun drawBlockSized (Ljava/awt/Color;DDDD)V

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
kotlin = "1.5.10"
33
kotlinx-coroutines = "1.5.2"
44
jetbrains-annotations = "23.0.0"
5-
universalcraft = "363"
5+
universalcraft = "389"
66
commonmark = "0.17.1"
77
dom4j = "2.1.1"
88

src/main/kotlin/gg/essential/elementa/components/GradientComponent.kt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import gg.essential.elementa.state.MappedState
55
import gg.essential.elementa.state.State
66
import gg.essential.universal.UGraphics
77
import gg.essential.universal.UMatrixStack
8+
import gg.essential.universal.render.URenderPipeline
9+
import gg.essential.universal.shader.BlendState
10+
import gg.essential.universal.vertex.UBufferBuilder
811
import org.lwjgl.opengl.GL11
912
import java.awt.Color
1013

@@ -86,6 +89,7 @@ open class GradientComponent constructor(
8689
"This method does not allow for gradients to be rendered at sub-pixel positions. Use the Double variant instead and do not cast to Int.",
8790
ReplaceWith("drawGradientBlock(x1.toDouble(), y1.toDouble(), x2.toDouble(), y2.toDouble(), startColor, endColor, direction)")
8891
)
92+
@Suppress("DEPRECATION")
8993
fun drawGradientBlock(
9094
x1: Int,
9195
y1: Int,
@@ -123,7 +127,27 @@ open class GradientComponent constructor(
123127
endColor: Color,
124128
direction: GradientDirection
125129
) {
126-
UGraphics.enableBlend()
130+
if (!URenderPipeline.isRequired) {
131+
@Suppress("DEPRECATION")
132+
return drawGradientBlockLegacy(matrixStack, x1, y1, x2, y2, startColor, endColor, direction)
133+
}
134+
135+
val colors = direction.getGradientColors(startColor, endColor)
136+
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
137+
bufferBuilder.pos(matrixStack, x2, y1, 0.0).color(colors.topRight).endVertex()
138+
bufferBuilder.pos(matrixStack, x1, y1, 0.0).color(colors.topLeft).endVertex()
139+
bufferBuilder.pos(matrixStack, x1, y2, 0.0).color(colors.bottomLeft).endVertex()
140+
bufferBuilder.pos(matrixStack, x2, y2, 0.0).color(colors.bottomRight).endVertex()
141+
bufferBuilder.build()?.drawAndClose(PIPELINE)
142+
}
143+
144+
@Deprecated("Stops working in 1.21.5")
145+
@Suppress("DEPRECATION")
146+
private fun drawGradientBlockLegacy(
147+
matrixStack: UMatrixStack,
148+
x1: Double, y1: Double, x2: Double, y2: Double,
149+
startColor: Color, endColor: Color, direction: GradientDirection
150+
) {
127151
UGraphics.disableAlpha()
128152
UGraphics.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO)
129153
UGraphics.shadeModel(GL11.GL_SMOOTH)
@@ -141,5 +165,9 @@ open class GradientComponent constructor(
141165
UGraphics.disableBlend()
142166
UGraphics.enableAlpha()
143167
}
168+
169+
private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:gradient_block", UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
170+
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
171+
}.build()
144172
}
145173
}

src/main/kotlin/gg/essential/elementa/components/SVGComponent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class SVGComponent(private var svg: SVG) : UIComponent(), ImageProvider {
4848

4949
matrixStack.push()
5050

51+
@Suppress("DEPRECATION")
5152
UGraphics.enableBlend()
5253
@Suppress("DEPRECATION")
5354
UGraphics.disableTexture2D()

src/main/kotlin/gg/essential/elementa/components/TreeGraphComponent.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ data class TreeGraphStyle(
1717
val lineWidth: Float = 2f,
1818
val isHorizontal: Boolean = false,
1919
val lineDrawer: (UIPoint, UIPoint) -> Unit = { p0, p1 ->
20+
@Suppress("DEPRECATION") // impossible to fix because TreeGraphStyle is public API
2021
LineUtils.drawLine(p0, p1, lineColor, lineWidth)
2122
}
2223
)

src/main/kotlin/gg/essential/elementa/components/UIBlock.kt

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import gg.essential.elementa.state.State
88
import gg.essential.elementa.state.toConstraint
99
import gg.essential.universal.UGraphics
1010
import gg.essential.universal.UMatrixStack
11+
import gg.essential.universal.render.URenderPipeline
12+
import gg.essential.universal.shader.BlendState
13+
import gg.essential.universal.vertex.UBufferBuilder
14+
import gg.essential.universal.vertex.UVertexConsumer
1115
import org.lwjgl.opengl.GL11
1216
import java.awt.Color
1317

@@ -53,6 +57,19 @@ open class UIBlock(colorConstraint: ColorConstraint = Color.WHITE.toConstraint()
5357
drawBlock(UMatrixStack(), color, x1, y1, x2, y2)
5458

5559
fun drawBlock(matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
60+
if (!URenderPipeline.isRequired) {
61+
@Suppress("DEPRECATION")
62+
return drawBlockLegacy(matrixStack, color, x1, y1, x2, y2)
63+
}
64+
65+
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
66+
drawBlock(bufferBuilder, matrixStack, color, x1, y1, x2, y2)
67+
bufferBuilder.build()?.drawAndClose(PIPELINE)
68+
}
69+
70+
@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
71+
@Suppress("DEPRECATION")
72+
private fun drawBlockLegacy(matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
5673
UGraphics.enableBlend()
5774
UGraphics.tryBlendFuncSeparate(770, 771, 1, 0)
5875

@@ -63,22 +80,18 @@ open class UIBlock(colorConstraint: ColorConstraint = Color.WHITE.toConstraint()
6380
UGraphics.disableBlend()
6481
}
6582

83+
@Deprecated("Stops working in 1.21.5, use URenderPipeline via UBufferBuilder with drawBlock(UVertexConsumer, ...) instead.")
84+
@Suppress("DEPRECATION")
6685
fun drawBlockWithActiveShader(matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
6786
val buffer = UGraphics.getFromTessellator()
6887
buffer.beginWithActiveShader(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
6988
drawBlock(buffer, matrixStack, color, x1, y1, x2, y2)
7089
}
7190

91+
@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
92+
@Suppress("DEPRECATION")
7293
private fun drawBlock(worldRenderer: UGraphics, matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
73-
val red = color.red.toFloat() / 255f
74-
val green = color.green.toFloat() / 255f
75-
val blue = color.blue.toFloat() / 255f
76-
val alpha = color.alpha.toFloat() / 255f
77-
78-
worldRenderer.pos(matrixStack, x1, y2, 0.0).color(red, green, blue, alpha).endVertex()
79-
worldRenderer.pos(matrixStack, x2, y2, 0.0).color(red, green, blue, alpha).endVertex()
80-
worldRenderer.pos(matrixStack, x2, y1, 0.0).color(red, green, blue, alpha).endVertex()
81-
worldRenderer.pos(matrixStack, x1, y1, 0.0).color(red, green, blue, alpha).endVertex()
94+
drawBlock(worldRenderer.asUVertexConsumer(), matrixStack, color, x1, y1, x2, y2)
8295

8396
if (ElementaVersion.active >= ElementaVersion.v1) {
8497
// At some point MC started enabling its depth test during font rendering but all GUI code is
@@ -96,6 +109,18 @@ open class UIBlock(colorConstraint: ColorConstraint = Color.WHITE.toConstraint()
96109
}
97110
}
98111

112+
fun drawBlock(vertexConsumer: UVertexConsumer, matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
113+
val red = color.red.toFloat() / 255f
114+
val green = color.green.toFloat() / 255f
115+
val blue = color.blue.toFloat() / 255f
116+
val alpha = color.alpha.toFloat() / 255f
117+
118+
vertexConsumer.pos(matrixStack, x1, y2, 0.0).color(red, green, blue, alpha).endVertex()
119+
vertexConsumer.pos(matrixStack, x2, y2, 0.0).color(red, green, blue, alpha).endVertex()
120+
vertexConsumer.pos(matrixStack, x2, y1, 0.0).color(red, green, blue, alpha).endVertex()
121+
vertexConsumer.pos(matrixStack, x1, y1, 0.0).color(red, green, blue, alpha).endVertex()
122+
}
123+
99124
@Deprecated(
100125
"Pass UMatrixStack as first argument, required for 1.17",
101126
ReplaceWith("drawBlock(matrixStack, color, x1, y1, x2, y2)")
@@ -106,5 +131,15 @@ open class UIBlock(colorConstraint: ColorConstraint = Color.WHITE.toConstraint()
106131
fun drawBlockSized(matrixStack: UMatrixStack, color: Color, x: Double, y: Double, width: Double, height: Double) {
107132
drawBlock(matrixStack, color, x, y, x + width, y + height)
108133
}
134+
135+
private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:block", UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
136+
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
137+
// At some point MC started enabling its depth test during font rendering but all GUI code is
138+
// essentially flat and has depth tests disabled. This can cause stuff rendered in the background of the
139+
// GUI to interfere with text rendered in the foreground because none of the blocks rendered in between
140+
// will actually write to the depth buffer.
141+
// To work around this, we'll write depth buffer unconditionally in the area where we draw the block.
142+
depthTest = URenderPipeline.DepthTest.Always
143+
}.build()
109144
}
110145
}

src/main/kotlin/gg/essential/elementa/components/UICircle.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ package gg.essential.elementa.components
33
import gg.essential.elementa.UIComponent
44
import gg.essential.elementa.dsl.toConstraint
55
import gg.essential.elementa.dsl.pixels
6+
import gg.essential.elementa.utils.readElementaShaderSource
67
import gg.essential.elementa.utils.readFromLegacyShader
8+
import gg.essential.universal.UGraphics
79
import gg.essential.universal.UMatrixStack
10+
import gg.essential.universal.render.URenderPipeline
811
import gg.essential.universal.shader.BlendState
912
import gg.essential.universal.shader.Float2Uniform
1013
import gg.essential.universal.shader.FloatUniform
1114
import gg.essential.universal.shader.UShader
15+
import gg.essential.universal.vertex.UBufferBuilder
1216
import java.awt.Color
1317

1418
/**
@@ -66,10 +70,23 @@ class UICircle @JvmOverloads constructor(radius: Float = 0f, color: Color = Colo
6670
private lateinit var shaderRadiusUniform: FloatUniform
6771
private lateinit var shaderCenterPositionUniform: Float2Uniform
6872

73+
private val PIPELINE = URenderPipeline.builderWithLegacyShader(
74+
"elementa:circle",
75+
UGraphics.DrawMode.QUADS,
76+
UGraphics.CommonVertexFormats.POSITION_COLOR,
77+
readElementaShaderSource("rect", "vsh"),
78+
readElementaShaderSource("circle", "fsh"),
79+
).apply {
80+
blendState = BlendState.NORMAL
81+
depthTest = URenderPipeline.DepthTest.Always // see UIBlock.PIPELINE
82+
}.build()
83+
6984
fun initShaders() {
85+
if (URenderPipeline.isRequired) return
7086
if (::shader.isInitialized)
7187
return
7288

89+
@Suppress("DEPRECATION")
7390
shader = UShader.readFromLegacyShader("rect", "circle", BlendState.NORMAL)
7491
if (!shader.usable) {
7592
println("Failed to load Elementa UICircle shader")
@@ -87,6 +104,30 @@ class UICircle @JvmOverloads constructor(radius: Float = 0f, color: Color = Colo
87104
drawCircle(UMatrixStack(), centerX, centerY, radius, color)
88105

89106
fun drawCircle(matrixStack: UMatrixStack, centerX: Float, centerY: Float, radius: Float, color: Color) {
107+
if (!URenderPipeline.isRequired) {
108+
@Suppress("DEPRECATION")
109+
return drawCircleLegacy(matrixStack, centerX, centerY, radius, color)
110+
}
111+
112+
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
113+
UIBlock.drawBlock(
114+
bufferBuilder,
115+
matrixStack,
116+
color,
117+
(centerX - radius).toDouble(),
118+
(centerY - radius).toDouble(),
119+
(centerX + radius).toDouble(),
120+
(centerY + radius).toDouble()
121+
)
122+
bufferBuilder.build()?.drawAndClose(PIPELINE) {
123+
uniform("u_Radius", radius)
124+
uniform("u_CenterPos", centerX, centerY)
125+
}
126+
}
127+
128+
@Deprecated("Stops working in 1.21.5")
129+
@Suppress("DEPRECATION")
130+
private fun drawCircleLegacy(matrixStack: UMatrixStack, centerX: Float, centerY: Float, radius: Float, color: Color) {
90131
if (!::shader.isInitialized || !shader.usable)
91132
return
92133

src/main/kotlin/gg/essential/elementa/components/UIRoundedRectangle.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ package gg.essential.elementa.components
22

33
import gg.essential.elementa.UIComponent
44
import gg.essential.elementa.dsl.pixels
5+
import gg.essential.elementa.utils.readElementaShaderSource
56
import gg.essential.elementa.utils.readFromLegacyShader
7+
import gg.essential.universal.UGraphics
68
import gg.essential.universal.UMatrixStack
9+
import gg.essential.universal.render.URenderPipeline
710
import gg.essential.universal.shader.BlendState
811
import gg.essential.universal.shader.Float4Uniform
912
import gg.essential.universal.shader.FloatUniform
1013
import gg.essential.universal.shader.UShader
14+
import gg.essential.universal.vertex.UBufferBuilder
1115
import java.awt.Color
1216

1317
/**
@@ -37,10 +41,23 @@ open class UIRoundedRectangle(radius: Float) : UIComponent() {
3741
private lateinit var shaderRadiusUniform: FloatUniform
3842
private lateinit var shaderInnerRectUniform: Float4Uniform
3943

44+
private val PIPELINE = URenderPipeline.builderWithLegacyShader(
45+
"elementa:rounded_rectangle",
46+
UGraphics.DrawMode.QUADS,
47+
UGraphics.CommonVertexFormats.POSITION_COLOR,
48+
readElementaShaderSource("rect", "vsh"),
49+
readElementaShaderSource("rounded_rect", "fsh"),
50+
).apply {
51+
blendState = BlendState.NORMAL
52+
depthTest = URenderPipeline.DepthTest.Always // see UIBlock.PIPELINE
53+
}.build()
54+
4055
fun initShaders() {
56+
if (URenderPipeline.isRequired) return
4157
if (::shader.isInitialized)
4258
return
4359

60+
@Suppress("DEPRECATION")
4461
shader = UShader.readFromLegacyShader("rect", "rounded_rect", BlendState.NORMAL)
4562
if (!shader.usable) {
4663
println("Failed to load Elementa UIRoundedRectangle shader")
@@ -61,6 +78,22 @@ open class UIRoundedRectangle(radius: Float) : UIComponent() {
6178
* Draws a rounded rectangle
6279
*/
6380
fun drawRoundedRectangle(matrixStack: UMatrixStack, left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) {
81+
if (!URenderPipeline.isRequired) {
82+
@Suppress("DEPRECATION")
83+
return drawRoundedRectangleLegacy(matrixStack, left, top, right, bottom, radius, color)
84+
}
85+
86+
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
87+
UIBlock.drawBlock(bufferBuilder, matrixStack, color, left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble())
88+
bufferBuilder.build()?.drawAndClose(PIPELINE) {
89+
uniform("u_Radius", radius)
90+
uniform("u_InnerRect", left + radius, top + radius, right - radius, bottom - radius)
91+
}
92+
}
93+
94+
@Deprecated("Stops working in 1.21.5")
95+
@Suppress("DEPRECATION")
96+
private fun drawRoundedRectangleLegacy(matrixStack: UMatrixStack, left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) {
6497
if (!::shader.isInitialized || !shader.usable)
6598
return
6699

src/main/kotlin/gg/essential/elementa/components/UIShape.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import gg.essential.elementa.UIComponent
44
import gg.essential.elementa.dsl.toConstraint
55
import gg.essential.universal.UGraphics
66
import gg.essential.universal.UMatrixStack
7+
import gg.essential.universal.render.URenderPipeline
8+
import gg.essential.universal.shader.BlendState
9+
import gg.essential.universal.vertex.UBufferBuilder
710
import org.lwjgl.opengl.GL11
811
import java.awt.Color
912

@@ -41,6 +44,30 @@ open class UIShape @JvmOverloads constructor(color: Color = Color.WHITE) : UICom
4144
val color = this.getColor()
4245
if (color.alpha == 0) return super.draw(matrixStack)
4346

47+
if (URenderPipeline.isRequired) {
48+
draw(matrixStack, color)
49+
} else {
50+
@Suppress("DEPRECATION")
51+
drawLegacy(matrixStack, color)
52+
}
53+
54+
super.draw(matrixStack)
55+
}
56+
57+
private fun draw(matrixStack: UMatrixStack, color: Color) {
58+
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.TRIANGLE_FAN, UGraphics.CommonVertexFormats.POSITION_COLOR)
59+
vertices.forEach {
60+
bufferBuilder
61+
.pos(matrixStack, it.absoluteX.toDouble(), it.absoluteY.toDouble(), 0.0)
62+
.color(color.red, color.green, color.blue, color.alpha)
63+
.endVertex()
64+
}
65+
bufferBuilder.build()?.drawAndClose(PIPELINE)
66+
}
67+
68+
@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
69+
@Suppress("DEPRECATION")
70+
private fun drawLegacy(matrixStack: UMatrixStack, color: Color) {
4471
UGraphics.enableBlend()
4572
UGraphics.disableTexture2D()
4673
val red = color.red.toFloat() / 255f
@@ -66,7 +93,11 @@ open class UIShape @JvmOverloads constructor(color: Color = Color.WHITE) : UICom
6693

6794
UGraphics.enableTexture2D()
6895
UGraphics.disableBlend()
96+
}
6997

70-
super.draw(matrixStack)
98+
private companion object {
99+
private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:shape", UGraphics.DrawMode.TRIANGLE_FAN, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
100+
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
101+
}.build()
71102
}
72103
}

src/main/kotlin/gg/essential/elementa/components/UIText.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import gg.essential.elementa.state.State
1010
import gg.essential.elementa.state.pixels
1111
import gg.essential.universal.UGraphics
1212
import gg.essential.universal.UMatrixStack
13+
import gg.essential.universal.render.URenderPipeline
1314
import java.awt.Color
1415

1516
/**
@@ -117,7 +118,10 @@ constructor(
117118
return super.draw(matrixStack)
118119
}
119120

120-
UGraphics.enableBlend()
121+
if (!URenderPipeline.isRequired) {
122+
@Suppress("DEPRECATION")
123+
UGraphics.enableBlend()
124+
}
121125

122126
val shadow = shadowState.get()
123127
val shadowColor = shadowColorState.get()

0 commit comments

Comments
 (0)