Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/Elementa.api
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ public class gg/essential/elementa/components/UIBlock : gg/essential/elementa/UI

public final class gg/essential/elementa/components/UIBlock$Companion {
public final fun drawBlock (Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
public final fun drawBlock (Lgg/essential/universal/vertex/UVertexConsumer;Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just make sure, is this intentionally public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it helps with replacing the deprecated drawBlockWithActiveShader.

public final fun drawBlock (Ljava/awt/Color;DDDD)V
public final fun drawBlockSized (Lgg/essential/universal/UMatrixStack;Ljava/awt/Color;DDDD)V
public final fun drawBlockSized (Ljava/awt/Color;DDDD)V
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
kotlin = "1.5.10"
kotlinx-coroutines = "1.5.2"
jetbrains-annotations = "23.0.0"
universalcraft = "363"
universalcraft = "389"
commonmark = "0.17.1"
dom4j = "2.1.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import gg.essential.elementa.state.MappedState
import gg.essential.elementa.state.State
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.vertex.UBufferBuilder
import org.lwjgl.opengl.GL11
import java.awt.Color

Expand Down Expand Up @@ -86,6 +89,7 @@ open class GradientComponent constructor(
"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.",
ReplaceWith("drawGradientBlock(x1.toDouble(), y1.toDouble(), x2.toDouble(), y2.toDouble(), startColor, endColor, direction)")
)
@Suppress("DEPRECATION")
fun drawGradientBlock(
x1: Int,
y1: Int,
Expand Down Expand Up @@ -123,7 +127,27 @@ open class GradientComponent constructor(
endColor: Color,
direction: GradientDirection
) {
UGraphics.enableBlend()
if (!URenderPipeline.isRequired) {
@Suppress("DEPRECATION")
return drawGradientBlockLegacy(matrixStack, x1, y1, x2, y2, startColor, endColor, direction)
}

val colors = direction.getGradientColors(startColor, endColor)
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
bufferBuilder.pos(matrixStack, x2, y1, 0.0).color(colors.topRight).endVertex()
bufferBuilder.pos(matrixStack, x1, y1, 0.0).color(colors.topLeft).endVertex()
bufferBuilder.pos(matrixStack, x1, y2, 0.0).color(colors.bottomLeft).endVertex()
bufferBuilder.pos(matrixStack, x2, y2, 0.0).color(colors.bottomRight).endVertex()
bufferBuilder.build()?.drawAndClose(PIPELINE)
}

@Deprecated("Stops working in 1.21.5")
@Suppress("DEPRECATION")
private fun drawGradientBlockLegacy(
matrixStack: UMatrixStack,
x1: Double, y1: Double, x2: Double, y2: Double,
startColor: Color, endColor: Color, direction: GradientDirection
) {
UGraphics.disableAlpha()
UGraphics.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO)
UGraphics.shadeModel(GL11.GL_SMOOTH)
Expand All @@ -141,5 +165,9 @@ open class GradientComponent constructor(
UGraphics.disableBlend()
UGraphics.enableAlpha()
}

private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:gradient_block", UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
}.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class SVGComponent(private var svg: SVG) : UIComponent(), ImageProvider {

matrixStack.push()

@Suppress("DEPRECATION")
UGraphics.enableBlend()
@Suppress("DEPRECATION")
UGraphics.disableTexture2D()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class TreeGraphStyle(
val lineWidth: Float = 2f,
val isHorizontal: Boolean = false,
val lineDrawer: (UIPoint, UIPoint) -> Unit = { p0, p1 ->
@Suppress("DEPRECATION") // impossible to fix because TreeGraphStyle is public API
LineUtils.drawLine(p0, p1, lineColor, lineWidth)
}
)
Expand Down
53 changes: 44 additions & 9 deletions src/main/kotlin/gg/essential/elementa/components/UIBlock.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import gg.essential.elementa.state.State
import gg.essential.elementa.state.toConstraint
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.vertex.UBufferBuilder
import gg.essential.universal.vertex.UVertexConsumer
import org.lwjgl.opengl.GL11
import java.awt.Color

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

fun drawBlock(matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
if (!URenderPipeline.isRequired) {
@Suppress("DEPRECATION")
return drawBlockLegacy(matrixStack, color, x1, y1, x2, y2)
}

val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
drawBlock(bufferBuilder, matrixStack, color, x1, y1, x2, y2)
bufferBuilder.build()?.drawAndClose(PIPELINE)
}

@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
@Suppress("DEPRECATION")
private fun drawBlockLegacy(matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
UGraphics.enableBlend()
UGraphics.tryBlendFuncSeparate(770, 771, 1, 0)

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

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

@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
@Suppress("DEPRECATION")
private fun drawBlock(worldRenderer: UGraphics, matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
val red = color.red.toFloat() / 255f
val green = color.green.toFloat() / 255f
val blue = color.blue.toFloat() / 255f
val alpha = color.alpha.toFloat() / 255f

worldRenderer.pos(matrixStack, x1, y2, 0.0).color(red, green, blue, alpha).endVertex()
worldRenderer.pos(matrixStack, x2, y2, 0.0).color(red, green, blue, alpha).endVertex()
worldRenderer.pos(matrixStack, x2, y1, 0.0).color(red, green, blue, alpha).endVertex()
worldRenderer.pos(matrixStack, x1, y1, 0.0).color(red, green, blue, alpha).endVertex()
drawBlock(worldRenderer.asUVertexConsumer(), matrixStack, color, x1, y1, x2, y2)

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

fun drawBlock(vertexConsumer: UVertexConsumer, matrixStack: UMatrixStack, color: Color, x1: Double, y1: Double, x2: Double, y2: Double) {
val red = color.red.toFloat() / 255f
val green = color.green.toFloat() / 255f
val blue = color.blue.toFloat() / 255f
val alpha = color.alpha.toFloat() / 255f

vertexConsumer.pos(matrixStack, x1, y2, 0.0).color(red, green, blue, alpha).endVertex()
vertexConsumer.pos(matrixStack, x2, y2, 0.0).color(red, green, blue, alpha).endVertex()
vertexConsumer.pos(matrixStack, x2, y1, 0.0).color(red, green, blue, alpha).endVertex()
vertexConsumer.pos(matrixStack, x1, y1, 0.0).color(red, green, blue, alpha).endVertex()
}

@Deprecated(
"Pass UMatrixStack as first argument, required for 1.17",
ReplaceWith("drawBlock(matrixStack, color, x1, y1, x2, y2)")
Expand All @@ -106,5 +131,15 @@ open class UIBlock(colorConstraint: ColorConstraint = Color.WHITE.toConstraint()
fun drawBlockSized(matrixStack: UMatrixStack, color: Color, x: Double, y: Double, width: Double, height: Double) {
drawBlock(matrixStack, color, x, y, x + width, y + height)
}

private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:block", UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
// At some point MC started enabling its depth test during font rendering but all GUI code is
// essentially flat and has depth tests disabled. This can cause stuff rendered in the background of the
// GUI to interfere with text rendered in the foreground because none of the blocks rendered in between
// will actually write to the depth buffer.
// To work around this, we'll write depth buffer unconditionally in the area where we draw the block.
depthTest = URenderPipeline.DepthTest.Always
}.build()
}
}
41 changes: 41 additions & 0 deletions src/main/kotlin/gg/essential/elementa/components/UICircle.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ 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.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.Float2Uniform
import gg.essential.universal.shader.FloatUniform
import gg.essential.universal.shader.UShader
import gg.essential.universal.vertex.UBufferBuilder
import java.awt.Color

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

private val PIPELINE = URenderPipeline.builderWithLegacyShader(
"elementa:circle",
UGraphics.DrawMode.QUADS,
UGraphics.CommonVertexFormats.POSITION_COLOR,
readElementaShaderSource("rect", "vsh"),
readElementaShaderSource("circle", "fsh"),
).apply {
blendState = BlendState.NORMAL
depthTest = URenderPipeline.DepthTest.Always // see UIBlock.PIPELINE
}.build()

fun initShaders() {
if (URenderPipeline.isRequired) return
if (::shader.isInitialized)
return

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

fun drawCircle(matrixStack: UMatrixStack, centerX: Float, centerY: Float, radius: Float, color: Color) {
if (!URenderPipeline.isRequired) {
@Suppress("DEPRECATION")
return drawCircleLegacy(matrixStack, centerX, centerY, radius, color)
}

val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.QUADS, UGraphics.CommonVertexFormats.POSITION_COLOR)
UIBlock.drawBlock(
bufferBuilder,
matrixStack,
color,
(centerX - radius).toDouble(),
(centerY - radius).toDouble(),
(centerX + radius).toDouble(),
(centerY + radius).toDouble()
)
bufferBuilder.build()?.drawAndClose(PIPELINE) {
uniform("u_Radius", radius)
uniform("u_CenterPos", centerX, centerY)
}
}

@Deprecated("Stops working in 1.21.5")
@Suppress("DEPRECATION")
private fun drawCircleLegacy(matrixStack: UMatrixStack, centerX: Float, centerY: Float, radius: Float, color: Color) {
if (!::shader.isInitialized || !shader.usable)
return

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ package gg.essential.elementa.components

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

/**
Expand Down Expand Up @@ -37,10 +41,23 @@ open class UIRoundedRectangle(radius: Float) : UIComponent() {
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 {
blendState = BlendState.NORMAL
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")
Expand All @@ -61,6 +78,22 @@ open class UIRoundedRectangle(radius: Float) : UIComponent() {
* Draws a rounded rectangle
*/
fun drawRoundedRectangle(matrixStack: UMatrixStack, left: Float, top: Float, right: Float, bottom: Float, radius: Float, color: Color) {
if (!URenderPipeline.isRequired) {
@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(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

Expand Down
33 changes: 32 additions & 1 deletion src/main/kotlin/gg/essential/elementa/components/UIShape.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import gg.essential.elementa.UIComponent
import gg.essential.elementa.dsl.toConstraint
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.vertex.UBufferBuilder
import org.lwjgl.opengl.GL11
import java.awt.Color

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

if (URenderPipeline.isRequired) {
draw(matrixStack, color)
} else {
@Suppress("DEPRECATION")
drawLegacy(matrixStack, color)
}

super.draw(matrixStack)
}

private fun draw(matrixStack: UMatrixStack, color: Color) {
val bufferBuilder = UBufferBuilder.create(UGraphics.DrawMode.TRIANGLE_FAN, UGraphics.CommonVertexFormats.POSITION_COLOR)
vertices.forEach {
bufferBuilder
.pos(matrixStack, it.absoluteX.toDouble(), it.absoluteY.toDouble(), 0.0)
.color(color.red, color.green, color.blue, color.alpha)
.endVertex()
}
bufferBuilder.build()?.drawAndClose(PIPELINE)
}

@Deprecated("Stops working in 1.21.5, see UGraphics.Globals")
@Suppress("DEPRECATION")
private fun drawLegacy(matrixStack: UMatrixStack, color: Color) {
UGraphics.enableBlend()
UGraphics.disableTexture2D()
val red = color.red.toFloat() / 255f
Expand All @@ -66,7 +93,11 @@ open class UIShape @JvmOverloads constructor(color: Color = Color.WHITE) : UICom

UGraphics.enableTexture2D()
UGraphics.disableBlend()
}

super.draw(matrixStack)
private companion object {
private val PIPELINE = URenderPipeline.builderWithDefaultShader("elementa:shape", UGraphics.DrawMode.TRIANGLE_FAN, UGraphics.CommonVertexFormats.POSITION_COLOR).apply {
blendState = BlendState.NORMAL.copy(srcAlpha = BlendState.Param.ONE, dstAlpha = BlendState.Param.ZERO)
}.build()
}
}
6 changes: 5 additions & 1 deletion src/main/kotlin/gg/essential/elementa/components/UIText.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import gg.essential.elementa.state.State
import gg.essential.elementa.state.pixels
import gg.essential.universal.UGraphics
import gg.essential.universal.UMatrixStack
import gg.essential.universal.render.URenderPipeline
import java.awt.Color

/**
Expand Down Expand Up @@ -117,7 +118,10 @@ constructor(
return super.draw(matrixStack)
}

UGraphics.enableBlend()
if (!URenderPipeline.isRequired) {
@Suppress("DEPRECATION")
UGraphics.enableBlend()
}

val shadow = shadowState.get()
val shadowColor = shadowColorState.get()
Expand Down
Loading