aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/util/render/RenderCircleProgress.kt
blob: a8245cae6fb326f260575822c32df3dc5b5e97d2 (plain)
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
/*
 * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

package moe.nea.firmament.util.render

import com.mojang.blaze3d.systems.RenderSystem
import org.joml.Matrix4f
import org.joml.Vector2f
import kotlin.math.atan2
import kotlin.math.tan
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.BufferRenderer
import net.minecraft.client.render.GameRenderer
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexFormat.DrawMode
import net.minecraft.client.render.VertexFormats
import net.minecraft.util.Identifier

object RenderCircleProgress {

    fun renderCircle(
        drawContext: DrawContext,
        texture: Identifier,
        progress: Float,
        u1: Float,
        u2: Float,
        v1: Float,
        v2: Float,
    ) {
        RenderSystem.setShaderTexture(0, texture)
        RenderSystem.setShader { GameRenderer.getPositionColorTexProgram() }
        RenderSystem.enableBlend()
        val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
        val bufferBuilder = Tessellator.getInstance().buffer
        bufferBuilder.begin(DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR_TEXTURE)
        bufferBuilder.fixedColor(255, 255, 255, 255)

        val corners = listOf(
            Vector2f(0F, -1F),
            Vector2f(1F, -1F),
            Vector2f(1F, 0F),
            Vector2f(1F, 1F),
            Vector2f(0F, 1F),
            Vector2f(-1F, 1F),
            Vector2f(-1F, 0F),
            Vector2f(-1F, -1F),
        )

        for (i in (0 until 8)) {
            if (progress < i / 8F) {
                break
            }
            val second = corners[(i + 1) % 8]
            val first = corners[i]
            if (progress <= (i + 1) / 8F) {
                val internalProgress = 1 - (progress - i / 8F) * 8F
                val angle = lerpAngle(
                    atan2(second.y, second.x),
                    atan2(first.y, first.x),
                    internalProgress
                )
                if (angle < tau / 8 || angle >= tau * 7 / 8) {
                    second.set(1F, tan(angle))
                } else if (angle < tau * 3 / 8) {
                    second.set(1 / tan(angle), 1F)
                } else if (angle < tau * 5 / 8) {
                    second.set(-1F, -tan(angle))
                } else {
                    second.set(-1 / tan(angle), -1F)
                }
            }

            fun ilerp(f: Float): Float =
                ilerp(-1f, 1f, f)

            bufferBuilder
                .vertex(matrix, second.x, second.y, 0F)
                .texture(lerp(u1, u2, ilerp(second.x)), lerp(v1, v2, ilerp(second.y)))
                .next()
            bufferBuilder
                .vertex(matrix, first.x, first.y, 0F)
                .texture(lerp(u1, u2, ilerp(first.x)), lerp(v1, v2, ilerp(first.y)))
                .next()
            bufferBuilder
                .vertex(matrix, 0F, 0F, 0F)
                .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F)))
                .next()
        }
        bufferBuilder.unfixColor()
        BufferRenderer.drawWithGlobalProgram(bufferBuilder.end())
        RenderSystem.disableBlend()
    }



}