diff options
Diffstat (limited to 'src/main/kotlin/util/render/RenderCircleProgress.kt')
| -rw-r--r-- | src/main/kotlin/util/render/RenderCircleProgress.kt | 170 |
1 files changed, 118 insertions, 52 deletions
diff --git a/src/main/kotlin/util/render/RenderCircleProgress.kt b/src/main/kotlin/util/render/RenderCircleProgress.kt index efd99fe..bbc4ace 100644 --- a/src/main/kotlin/util/render/RenderCircleProgress.kt +++ b/src/main/kotlin/util/render/RenderCircleProgress.kt @@ -4,9 +4,12 @@ import com.mojang.blaze3d.vertex.VertexFormat import org.joml.Matrix3x2f import util.render.CustomRenderLayers import net.minecraft.client.gui.DrawContext +import net.minecraft.client.gui.ScreenRect import net.minecraft.client.render.BufferBuilder import net.minecraft.client.render.RenderLayer +import net.minecraft.client.render.VertexConsumerProvider import net.minecraft.client.util.BufferAllocator +import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.Identifier import moe.nea.firmament.util.MC import moe.nea.firmament.util.collections.nonNegligibleSubSectionsAlignedWith @@ -15,6 +18,105 @@ import moe.nea.firmament.util.mc.CustomRenderPassHelper object RenderCircleProgress { + + data class State( + override val x1: Int, + override val x2: Int, + override val y1: Int, + override val y2: Int, + val layer: RenderLayer.MultiPhase, + val u1: Float, + val u2: Float, + val v1: Float, + val v2: Float, + val angleRadians: ClosedFloatingPointRange<Float>, + val color: Int, + val innerCutoutRadius: Float, + override val scale: Float, + override val bounds: ScreenRect?, + override val scissorArea: ScreenRect?, + ) : MultiSpecialGuiRenderState() { + override fun createRenderer(vertexConsumers: VertexConsumerProvider.Immediate): MultiSpecialGuiRenderer<out MultiSpecialGuiRenderState> { + return Renderer(vertexConsumers) + } + } + + class Renderer(vertexConsumers: VertexConsumerProvider.Immediate) : + MultiSpecialGuiRenderer<State>(vertexConsumers) { + override fun render( + state: State, + matrices: MatrixStack + ) { + matrices.push() + matrices.translate(0F, -1F, 0F) + val sections = state.angleRadians.nonNegligibleSubSectionsAlignedWith((τ / 8f).toFloat()) + .zipWithNext().toList() + val u1 = state.u1 + val u2 = state.u2 + val v1 = state.v1 + val v2 = state.v2 + val color = state.color + val matrix = matrices.peek().positionMatrix + BufferAllocator(state.layer.vertexFormat.vertexSize * sections.size * 3).use { allocator -> + + val bufferBuilder = BufferBuilder(allocator, VertexFormat.DrawMode.TRIANGLES, state.layer.vertexFormat) + + for ((sectionStart, sectionEnd) in sections) { + val firstPoint = Projections.Two.projectAngleOntoUnitBox(sectionStart.toDouble()) + val secondPoint = Projections.Two.projectAngleOntoUnitBox(sectionEnd.toDouble()) + fun ilerp(f: Float): Float = + ilerp(-1f, 1f, f) + + bufferBuilder + .vertex(matrix, secondPoint.x, secondPoint.y, 0F) + .texture(lerp(u1, u2, ilerp(secondPoint.x)), lerp(v1, v2, ilerp(secondPoint.y))) + .color(color) + + bufferBuilder + .vertex(matrix, firstPoint.x, firstPoint.y, 0F) + .texture(lerp(u1, u2, ilerp(firstPoint.x)), lerp(v1, v2, ilerp(firstPoint.y))) + .color(color) + + bufferBuilder + .vertex(matrix, 0F, 0F, 0F) + .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F))) + .color(color) + + } + + bufferBuilder.end().use { buffer -> + if (state.innerCutoutRadius <= 0) { + state.layer.draw(buffer) + return + } + CustomRenderPassHelper( + { "RenderCircleProgress" }, + VertexFormat.DrawMode.TRIANGLES, + state.layer.vertexFormat, + MC.instance.framebuffer, + false, + ).use { renderPass -> + renderPass.uploadVertices(buffer) + renderPass.setPipeline(state.layer.pipeline) + renderPass.setUniform("InnerCutoutRadius", 4) { + it.putFloat(state.innerCutoutRadius) + } + renderPass.draw() + } + } + } + matrices.pop() + } + + override fun getElementClass(): Class<State> { + return State::class.java + } + + override fun getName(): String { + return "Firmament Circle" + } + } + fun renderCircularSlice( drawContext: DrawContext, layer: RenderLayer.MultiPhase, @@ -25,58 +127,22 @@ object RenderCircleProgress { angleRadians: ClosedFloatingPointRange<Float>, color: Int = -1, innerCutoutRadius: Float = 0F - ) { // TODO: this is fixed by adding a special gui element renderer - val sections = angleRadians.nonNegligibleSubSectionsAlignedWith((τ / 8f).toFloat()) - .zipWithNext().toList() - BufferAllocator(layer.vertexFormat.vertexSize * sections.size * 3).use { allocator -> - - val bufferBuilder = BufferBuilder(allocator, VertexFormat.DrawMode.TRIANGLES, layer.vertexFormat) - val matrix: Matrix3x2f = drawContext.matrices - - for ((sectionStart, sectionEnd) in sections) { - val firstPoint = Projections.Two.projectAngleOntoUnitBox(sectionStart.toDouble()) - val secondPoint = Projections.Two.projectAngleOntoUnitBox(sectionEnd.toDouble()) - fun ilerp(f: Float): Float = - ilerp(-1f, 1f, f) - - bufferBuilder - .vertex(matrix, secondPoint.x, secondPoint.y, 0F) - .texture(lerp(u1, u2, ilerp(secondPoint.x)), lerp(v1, v2, ilerp(secondPoint.y))) - .color(color) - - bufferBuilder - .vertex(matrix, firstPoint.x, firstPoint.y, 0F) - .texture(lerp(u1, u2, ilerp(firstPoint.x)), lerp(v1, v2, ilerp(firstPoint.y))) - .color(color) - - bufferBuilder - .vertex(matrix, 0F, 0F, 0F) - .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F))) - .color(color) - - } - - bufferBuilder.end().use { buffer -> - if (innerCutoutRadius <= 0) { - layer.draw(buffer) - return - } - CustomRenderPassHelper( - { "RenderCircleProgress" }, - VertexFormat.DrawMode.TRIANGLES, - layer.vertexFormat, - MC.instance.framebuffer, - false, - ).use { renderPass -> - renderPass.uploadVertices(buffer) - renderPass.setPipeline(layer.pipeline) - renderPass.setUniform("InnerCutoutRadius", 4) { - it.putFloat(innerCutoutRadius) - } - renderPass.draw() - } - } - } + ) { + val screenRect = ScreenRect(-1, -1, 2, 2).transform(drawContext.matrices) + drawContext.state.addSpecialElement( + State( + screenRect.left, screenRect.right, + screenRect.top, screenRect.bottom, + layer, + u1, u2, v1, v2, + angleRadians, + color, + innerCutoutRadius, + screenRect.width / 2F, + screenRect, + null + ) + ) } fun renderCircle( |
