Refactor source layout

Introduce compat source sets and move all kotlin sources to the main directory

[no changelog]
This commit is contained in:
Linnea Gräf
2024-08-28 19:04:24 +02:00
parent a690630816
commit d2f240ff0c
251 changed files with 295 additions and 38 deletions

View File

@@ -0,0 +1,101 @@
package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
import io.github.notenoughupdates.moulconfig.platform.next
import org.joml.Matrix4f
import net.minecraft.client.font.TextRenderer
import net.minecraft.client.render.BufferRenderer
import net.minecraft.client.render.GameRenderer
import net.minecraft.client.render.LightmapTextureManager
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexConsumer
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.assertTrueOr
@RenderContextDSL
class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
val matrixStack by worldContext::matrixStack
fun waypoint(position: BlockPos, label: Text) {
text(
label,
Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}")
)
}
fun text(
vararg texts: Text,
verticalAlign: RenderInWorldContext.VerticalAlign = RenderInWorldContext.VerticalAlign.CENTER,
background: Int = 0x70808080,
) {
assertTrueOr(texts.isNotEmpty()) { return@text }
for ((index, text) in texts.withIndex()) {
worldContext.matrixStack.push()
val width = MC.font.getWidth(text)
worldContext.matrixStack.translate(-width / 2F, verticalAlign.align(index, texts.size), 0F)
val vertexConsumer: VertexConsumer =
worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough())
val matrix4f = worldContext.matrixStack.peek().positionMatrix
vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(background)
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(background)
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f)
.color(background)
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(background)
.light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next()
worldContext.matrixStack.translate(0F, 0F, 0.01F)
MC.font.draw(
text,
0F,
0F,
-1,
false,
worldContext.matrixStack.peek().positionMatrix,
worldContext.vertexConsumers,
TextRenderer.TextLayerType.SEE_THROUGH,
0,
LightmapTextureManager.MAX_LIGHT_COORDINATE
)
worldContext.matrixStack.pop()
}
}
fun texture(
texture: Identifier, width: Int, height: Int,
u1: Float, v1: Float,
u2: Float, v2: Float,
) {
RenderSystem.setShaderTexture(0, texture)
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram)
val hw = width / 2F
val hh = height / 2F
val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix
val buf = Tessellator.getInstance()
.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR)
buf.vertex(matrix4f, -hw, -hh, 0F)
.color(-1)
.texture(u1, v1).next()
buf.vertex(matrix4f, -hw, +hh, 0F)
.color(-1)
.texture(u1, v2).next()
buf.vertex(matrix4f, +hw, +hh, 0F)
.color(-1)
.texture(u2, v2).next()
buf.vertex(matrix4f, +hw, -hh, 0F)
.color(-1)
.texture(u2, v1).next()
BufferRenderer.drawWithGlobalProgram(buf.end())
}
}

View File

@@ -0,0 +1,33 @@
package moe.nea.firmament.util.render
import me.shedaniel.math.Color
val pi = Math.PI
val tau = Math.PI * 2
fun lerpAngle(a: Float, b: Float, progress: Float): Float {
// TODO: there is at least 10 mods to many in here lol
val shortestAngle = ((((b.mod(tau) - a.mod(tau)).mod(tau)) + tau + pi).mod(tau)) - pi
return ((a + (shortestAngle) * progress).mod(tau)).toFloat()
}
fun lerp(a: Float, b: Float, progress: Float): Float {
return a + (b - a) * progress
}
fun lerp(a: Int, b: Int, progress: Float): Int {
return (a + (b - a) * progress).toInt()
}
fun ilerp(a: Float, b: Float, value: Float): Float {
return (value - a) / (b - a)
}
fun lerp(a: Color, b: Color, progress: Float): Color {
return Color.ofRGBA(
lerp(a.red, b.red, progress),
lerp(a.green, b.green, progress),
lerp(a.blue, b.blue, progress),
lerp(a.alpha, b.alpha, progress),
)
}

View File

@@ -0,0 +1,95 @@
package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
import io.github.notenoughupdates.moulconfig.platform.next
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::getPositionTexColorProgram)
RenderSystem.enableBlend()
val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
val bufferBuilder = Tessellator.getInstance().begin(DrawMode.TRIANGLES, VertexFormats.POSITION_TEXTURE_COLOR)
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)))
.color(-1)
.next()
bufferBuilder
.vertex(matrix, first.x, first.y, 0F)
.texture(lerp(u1, u2, ilerp(first.x)), lerp(v1, v2, ilerp(first.y)))
.color(-1)
.next()
bufferBuilder
.vertex(matrix, 0F, 0F, 0F)
.texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F)))
.color(-1)
.next()
}
BufferRenderer.drawWithGlobalProgram(bufferBuilder.end())
RenderSystem.disableBlend()
}
}

View File

@@ -0,0 +1,6 @@
package moe.nea.firmament.util.render
@DslMarker
annotation class RenderContextDSL {
}

View File

@@ -0,0 +1,294 @@
package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
import io.github.notenoughupdates.moulconfig.platform.next
import java.lang.Math.pow
import org.joml.Matrix4f
import org.joml.Vector3f
import net.minecraft.client.gl.VertexBuffer
import net.minecraft.client.render.BufferBuilder
import net.minecraft.client.render.BufferRenderer
import net.minecraft.client.render.Camera
import net.minecraft.client.render.GameRenderer
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.RenderPhase
import net.minecraft.client.render.RenderTickCounter
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import moe.nea.firmament.events.WorldRenderLastEvent
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.MC
@RenderContextDSL
class RenderInWorldContext private constructor(
private val tesselator: Tessellator,
val matrixStack: MatrixStack,
private val camera: Camera,
private val tickCounter: RenderTickCounter,
val vertexConsumers: VertexConsumerProvider.Immediate,
) {
object RenderLayers {
val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris",
VertexFormats.POSITION_COLOR,
VertexFormat.DrawMode.TRIANGLES,
RenderLayer.DEFAULT_BUFFER_SIZE,
false, true,
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
.program(RenderPhase.COLOR_PROGRAM)
.build(false))
}
fun color(color: me.shedaniel.math.Color) {
color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f)
}
fun color(red: Float, green: Float, blue: Float, alpha: Float) {
RenderSystem.setShaderColor(red, green, blue, alpha)
}
fun block(blockPos: BlockPos) {
matrixStack.push()
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
buildCube(matrixStack.peek().positionMatrix, tesselator)
matrixStack.pop()
}
enum class VerticalAlign {
TOP, BOTTOM, CENTER;
fun align(index: Int, count: Int): Float {
return when (this) {
CENTER -> (index - count / 2F) * (1 + MC.font.fontHeight.toFloat())
BOTTOM -> (index - count) * (1 + MC.font.fontHeight.toFloat())
TOP -> (index) * (1 + MC.font.fontHeight.toFloat())
}
}
}
fun waypoint(position: BlockPos, vararg label: Text) {
text(
position.toCenterPos(),
*label,
Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}"),
background = 0xAA202020.toInt()
)
}
fun withFacingThePlayer(position: Vec3d, block: FacingThePlayerContext.() -> Unit) {
matrixStack.push()
matrixStack.translate(position.x, position.y, position.z)
val actualCameraDistance = position.distanceTo(camera.pos)
val distanceToMoveTowardsCamera = if (actualCameraDistance < 10) 0.0 else -(actualCameraDistance - 10.0)
val vec = position.subtract(camera.pos).multiply(distanceToMoveTowardsCamera / actualCameraDistance)
matrixStack.translate(vec.x, vec.y, vec.z)
matrixStack.multiply(camera.rotation)
matrixStack.scale(0.025F, -0.025F, 1F)
FacingThePlayerContext(this).run(block)
matrixStack.pop()
vertexConsumers.drawCurrentLayer()
}
fun sprite(position: Vec3d, sprite: Sprite, width: Int, height: Int) {
texture(
position, sprite.atlasId, width, height, sprite.minU, sprite.minV, sprite.maxU, sprite.maxV
)
}
fun texture(
position: Vec3d, texture: Identifier, width: Int, height: Int,
u1: Float, v1: Float,
u2: Float, v2: Float,
) {
withFacingThePlayer(position) {
texture(texture, width, height, u1, v1, u2, v2)
}
}
fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER, background: Int = 0x70808080) {
withFacingThePlayer(position) {
text(*texts, verticalAlign = verticalAlign, background = background)
}
}
fun tinyBlock(vec3d: Vec3d, size: Float) {
RenderSystem.setShader(GameRenderer::getPositionColorProgram)
matrixStack.push()
matrixStack.translate(vec3d.x, vec3d.y, vec3d.z)
matrixStack.scale(size, size, size)
matrixStack.translate(-.5, -.5, -.5)
buildCube(matrixStack.peek().positionMatrix, tesselator)
matrixStack.pop()
}
fun wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) {
RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram)
matrixStack.push()
RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(blockPos.toCenterPos()), 0.25).toFloat())
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
buildWireFrameCube(matrixStack.peek(), tesselator)
matrixStack.pop()
}
fun line(vararg points: Vec3d, lineWidth: Float = 10F) {
line(points.toList(), lineWidth)
}
fun tracer(toWhere: Vec3d, lineWidth: Float = 3f) {
val cameraForward = Vector3f(0f, 0f, 1f).rotate(camera.rotation)
line(camera.pos.add(Vec3d(cameraForward)), toWhere, lineWidth = lineWidth)
}
fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram)
RenderSystem.lineWidth(lineWidth)
val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
val matrix = matrixStack.peek()
var lastNormal: Vector3f? = null
points.zipWithNext().forEach { (a, b) ->
val normal = Vector3f(b.x.toFloat(), b.y.toFloat(), b.z.toFloat())
.sub(a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
.normalize()
val lastNormal0 = lastNormal ?: normal
lastNormal = normal
buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat())
.color(-1)
.normal(matrix, lastNormal0.x, lastNormal0.y, lastNormal0.z)
.next()
buffer.vertex(matrix.positionMatrix, b.x.toFloat(), b.y.toFloat(), b.z.toFloat())
.color(-1)
.normal(matrix, normal.x, normal.y, normal.z)
.next()
}
BufferRenderer.drawWithGlobalProgram(buffer.end())
}
companion object {
private fun doLine(
matrix: MatrixStack.Entry,
buf: BufferBuilder,
i: Float,
j: Float,
k: Float,
x: Float,
y: Float,
z: Float
) {
val normal = Vector3f(x, y, z)
.sub(i, j, k)
.normalize()
buf.vertex(matrix.positionMatrix, i, j, k)
.normal(matrix, normal.x, normal.y, normal.z)
.color(-1)
.next()
buf.vertex(matrix.positionMatrix, x, y, z)
.normal(matrix, normal.x, normal.y, normal.z)
.color(-1)
.next()
}
private fun buildWireFrameCube(matrix: MatrixStack.Entry, tessellator: Tessellator) {
val buf = tessellator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
for (i in 0..1) {
for (j in 0..1) {
val i = i.toFloat()
val j = j.toFloat()
doLine(matrix, buf, 0F, i, j, 1F, i, j)
doLine(matrix, buf, i, 0F, j, i, 1F, j)
doLine(matrix, buf, i, j, 0F, i, j, 1F)
}
}
BufferRenderer.drawWithGlobalProgram(buf.end())
}
private fun buildCube(matrix: Matrix4f, tessellator: Tessellator) {
val buf = tessellator.begin(VertexFormat.DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR)
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next()
buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next()
RenderLayers.TRANSLUCENT_TRIS.draw(buf.end())
}
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
RenderSystem.disableDepthTest()
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
RenderSystem.disableCull()
event.matrices.push()
event.matrices.translate(-event.camera.pos.x, -event.camera.pos.y, -event.camera.pos.z)
val ctx = RenderInWorldContext(
RenderSystem.renderThreadTesselator(),
event.matrices,
event.camera,
event.tickCounter,
event.vertexConsumers
)
block(ctx)
event.matrices.pop()
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
VertexBuffer.unbind()
RenderSystem.enableDepthTest()
RenderSystem.enableCull()
RenderSystem.disableBlend()
}
}
}

View File

@@ -0,0 +1,22 @@
package moe.nea.firmament.util.render
import org.joml.Vector4f
import net.minecraft.client.gui.DrawContext
fun DrawContext.enableScissorWithTranslation(x1: Float, y1: Float, x2: Float, y2: Float) {
val pMat = matrices.peek().positionMatrix
val target = Vector4f()
target.set(x1, y1, 0f, 1f)
target.mul(pMat)
val scissorX1 = target.x
val scissorY1 = target.y
target.set(x2, y2, 0f, 1f)
target.mul(pMat)
val scissorX2 = target.x
val scissorY2 = target.y
enableScissor(scissorX1.toInt(), scissorY1.toInt(), scissorX2.toInt(), scissorY2.toInt())
}