1.21.3 WIP

This commit is contained in:
Linnea Gräf
2024-11-03 01:24:24 +01:00
parent 646843ba3b
commit 22f0cc59a2
105 changed files with 2854 additions and 2646 deletions

View File

@@ -4,12 +4,70 @@ import com.mojang.blaze3d.systems.RenderSystem
import me.shedaniel.math.Color
import org.joml.Matrix4f
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderLayer
import net.minecraft.client.render.RenderLayer.MultiPhaseParameters
import net.minecraft.client.render.RenderPhase
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
import net.minecraft.util.Identifier
import net.minecraft.util.TriState
import net.minecraft.util.Util
import moe.nea.firmament.util.MC
fun DrawContext.isUntranslatedGuiDrawContext(): Boolean {
return (matrices.peek().positionMatrix.properties() and Matrix4f.PROPERTY_IDENTITY.toInt()) != 0
}
object GuiRenderLayers {
val GUI_TEXTURED_NO_DEPTH = Util.memoize<Identifier, RenderLayer> { texture: Identifier ->
RenderLayer.of("firmament_gui_textured_no_depth",
VertexFormats.POSITION_TEXTURE_COLOR,
VertexFormat.DrawMode.QUADS,
RenderLayer.CUTOUT_BUFFER_SIZE,
MultiPhaseParameters.builder()
.texture(RenderPhase.Texture(texture, TriState.FALSE, false))
.program(RenderPhase.POSITION_TEXTURE_COLOR_PROGRAM)
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.build(false))
}
}
@Deprecated("Use the other drawGuiTexture")
fun DrawContext.drawGuiTexture(
x: Int, y: Int, z: Int, width: Int, height: Int, sprite: Identifier
) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height)
fun DrawContext.drawGuiTexture(
sprite: Identifier,
x: Int, y: Int, width: Int, height: Int
) = this.drawGuiTexture(RenderLayer::getGuiTextured, sprite, x, y, width, height)
fun DrawContext.drawTexture(
sprite: Identifier,
x: Int,
y: Int,
u: Float,
v: Float,
width: Int,
height: Int,
textureWidth: Int,
textureHeight: Int
) {
this.drawTexture(RenderLayer::getGuiTextured,
sprite,
x,
y,
u,
v,
width,
height,
width,
height,
textureWidth,
textureHeight)
}
fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Color) {
// TODO: push scissors
// TODO: use matrix translations and a different render layer
@@ -18,11 +76,12 @@ fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Colo
return
}
RenderSystem.lineWidth(MC.window.scaleFactor.toFloat())
val buf = this.vertexConsumers.getBuffer(RenderInWorldContext.RenderLayers.LINES)
buf.vertex(fromX.toFloat(), fromY.toFloat(), 0F).color(color.color)
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
buf.vertex(toX.toFloat(), toY.toFloat(), 0F).color(color.color)
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
this.draw()
draw { vertexConsumers ->
val buf = vertexConsumers.getBuffer(RenderInWorldContext.RenderLayers.LINES)
buf.vertex(fromX.toFloat(), fromY.toFloat(), 0F).color(color.color)
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
buf.vertex(toX.toFloat(), toY.toFloat(), 0F).color(color.color)
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
}
}

View File

@@ -76,13 +76,10 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
u1: Float, v1: Float,
u2: Float, v2: Float,
) {
RenderSystem.setShaderTexture(0, texture)
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram)
val buf = worldContext.vertexConsumers.getBuffer(RenderLayer.getGuiTexturedOverlay(texture))
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()
@@ -95,7 +92,7 @@ class FacingThePlayerContext(val worldContext: RenderInWorldContext) {
buf.vertex(matrix4f, +hw, -hh, 0F)
.color(-1)
.texture(u2, v1).next()
BufferRenderer.drawWithGlobalProgram(buf.end())
worldContext.vertexConsumers.draw()
}
}

View File

@@ -1,23 +1,30 @@
package moe.nea.firmament.util.render
import net.minecraft.client.gl.ShaderProgram
import net.minecraft.client.gl.Defines
import net.minecraft.client.gl.ShaderProgramKey
import net.minecraft.client.render.RenderPhase
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.RegisterCustomShadersEvent
import moe.nea.firmament.events.DebugInstantiateEvent
import moe.nea.firmament.util.MC
object FirmamentShaders {
val shaders = mutableListOf<ShaderProgramKey>()
private fun shader(name: String, format: VertexFormat, defines: Defines): ShaderProgramKey {
val key = ShaderProgramKey(Firmament.identifier(name), format, defines)
shaders.add(key)
return key
}
private lateinit var _LINES: ShaderProgram
val LINES = RenderPhase.ShaderProgram({ _LINES })
val LINES = RenderPhase.ShaderProgram(shader("core/rendertype_lines", VertexFormats.LINES, Defines.EMPTY))
@Subscribe
fun registerCustomShaders(event: RegisterCustomShadersEvent) {
event.register(
"firmament_rendertype_lines",
VertexFormats.LINES,
{ _LINES = it },
)
}
@Subscribe
fun debugLoad(event: DebugInstantiateEvent) {
shaders.forEach {
MC.instance.shaderLoader.getOrCreateProgram(it)
}
}
}

View File

@@ -1,4 +1,3 @@
package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
@@ -9,7 +8,8 @@ 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.RenderLayer
import net.minecraft.client.render.RenderPhase
import net.minecraft.client.render.Tessellator
import net.minecraft.client.render.VertexFormat.DrawMode
import net.minecraft.client.render.VertexFormats
@@ -17,79 +17,77 @@ 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)
fun renderCircle(
drawContext: DrawContext,
texture: Identifier,
progress: Float,
u1: Float,
u2: Float,
v1: Float,
v2: Float,
) {
RenderSystem.enableBlend()
drawContext.draw {
val bufferBuilder = it.getBuffer(RenderLayer.getGuiTexturedOverlay(texture))
val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
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),
)
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)
}
}
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()
}
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()
}
}
RenderSystem.disableBlend()
}
}

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.util.render
import com.mojang.blaze3d.systems.RenderSystem
@@ -8,14 +6,12 @@ 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.VertexConsumer
import net.minecraft.client.render.VertexConsumerProvider
import net.minecraft.client.render.VertexFormat
import net.minecraft.client.render.VertexFormats
@@ -31,273 +27,287 @@ 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,
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))
val LINES = RenderLayer.of("firmament_rendertype_lines",
VertexFormats.LINES,
VertexFormat.DrawMode.LINES,
RenderLayer.DEFAULT_BUFFER_SIZE,
false, false, // do we need translucent? i dont think so
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.program(FirmamentShaders.LINES)
.build(false)
)
}
object RenderLayers {
val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris",
VertexFormats.POSITION_COLOR,
VertexFormat.DrawMode.TRIANGLES,
RenderLayer.CUTOUT_BUFFER_SIZE,
false, true,
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
.program(RenderPhase.POSITION_COLOR_PROGRAM)
.build(false))
val LINES = RenderLayer.of("firmament_rendertype_lines",
VertexFormats.LINES,
VertexFormat.DrawMode.LINES,
RenderLayer.CUTOUT_BUFFER_SIZE,
false, false, // do we need translucent? i dont think so
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.program(FirmamentShaders.LINES)
.build(false)
)
val COLORED_QUADS = RenderLayer.of(
"firmament_quads",
VertexFormats.POSITION_COLOR,
VertexFormat.DrawMode.QUADS,
RenderLayer.CUTOUT_BUFFER_SIZE,
false, true,
RenderLayer.MultiPhaseParameters.builder()
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
.program(RenderPhase.POSITION_COLOR_PROGRAM)
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
.build(false)
)
}
fun color(color: me.shedaniel.math.Color) {
color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f)
}
@Deprecated("stateful color management is no longer a thing")
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)
}
@Deprecated("stateful color management is no longer a thing")
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()
}
fun block(blockPos: BlockPos, color: Int) {
matrixStack.push()
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
matrixStack.pop()
}
enum class VerticalAlign {
TOP, BOTTOM, CENTER;
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 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 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)
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)
FacingThePlayerContext(this).run(block)
matrixStack.pop()
vertexConsumers.drawCurrentLayer()
}
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 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 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 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 tinyBlock(vec3d: Vec3d, size: Float, color: Int) {
matrixStack.push()
matrixStack.translate(vec3d.x, vec3d.y, vec3d.z)
matrixStack.scale(size, size, size)
matrixStack.translate(-.5, -.5, -.5)
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
matrixStack.pop()
vertexConsumers.draw()
}
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 wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) {
val buf = vertexConsumers.getBuffer(RenderLayer.LINES)
matrixStack.push()
// TODO: this does not render through blocks (or water layers) anymore
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(), buf)
matrixStack.pop()
vertexConsumers.draw()
}
fun line(vararg points: Vec3d, lineWidth: Float = 10F) {
line(points.toList(), lineWidth)
}
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 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.lineWidth(lineWidth)
val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
RenderSystem.lineWidth(lineWidth)
// TODO: replace with renderlayers
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()
}
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()
}
RenderLayers.LINES.draw(buffer.end())
}
RenderLayers.LINES.draw(buffer.end())
}
// TODO: put the favourite icons in front of items again
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()
}
companion object {
private fun doLine(
matrix: MatrixStack.Entry,
buf: VertexConsumer,
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)
private fun buildWireFrameCube(matrix: MatrixStack.Entry, buf: VertexConsumer) {
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)
}
}
}
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())
}
private fun buildCube(matrix: Matrix4f, buf: VertexConsumer, color: Int) {
// Y-
buf.vertex(matrix, 0F, 0F, 0F).color(color)
buf.vertex(matrix, 0F, 0F, 1F).color(color)
buf.vertex(matrix, 1F, 0F, 1F).color(color)
buf.vertex(matrix, 1F, 0F, 0F).color(color)
// Y+
buf.vertex(matrix, 0F, 1F, 0F).color(color)
buf.vertex(matrix, 1F, 1F, 0F).color(color)
buf.vertex(matrix, 1F, 1F, 1F).color(color)
buf.vertex(matrix, 0F, 1F, 1F).color(color)
// X-
buf.vertex(matrix, 0F, 0F, 0F).color(color)
buf.vertex(matrix, 0F, 0F, 1F).color(color)
buf.vertex(matrix, 0F, 1F, 1F).color(color)
buf.vertex(matrix, 0F, 1F, 0F).color(color)
// X+
buf.vertex(matrix, 1F, 0F, 0F).color(color)
buf.vertex(matrix, 1F, 1F, 0F).color(color)
buf.vertex(matrix, 1F, 1F, 1F).color(color)
buf.vertex(matrix, 1F, 0F, 1F).color(color)
// Z-
buf.vertex(matrix, 0F, 0F, 0F).color(color)
buf.vertex(matrix, 1F, 0F, 0F).color(color)
buf.vertex(matrix, 1F, 1F, 0F).color(color)
buf.vertex(matrix, 0F, 1F, 0F).color(color)
// Z+
buf.vertex(matrix, 0F, 0F, 1F).color(color)
buf.vertex(matrix, 0F, 1F, 1F).color(color)
buf.vertex(matrix, 1F, 1F, 1F).color(color)
buf.vertex(matrix, 1F, 0F, 1F).color(color)
}
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
RenderSystem.disableDepthTest()
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
RenderSystem.disableCull()
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
// TODO: there should be *no more global state*. the only thing we should be doing is render layers. that includes settings like culling, blending, shader color, and depth testing
// For now i will let these functions remain, but this needs to go before i do a full (non-beta) release
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)
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
)
val ctx = RenderInWorldContext(
RenderSystem.renderThreadTesselator(),
event.matrices,
event.camera,
event.tickCounter,
event.vertexConsumers
)
block(ctx)
block(ctx)
event.matrices.pop()
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
VertexBuffer.unbind()
RenderSystem.enableDepthTest()
RenderSystem.enableCull()
RenderSystem.disableBlend()
}
}
event.matrices.pop()
event.vertexConsumers.draw()
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
VertexBuffer.unbind()
RenderSystem.enableDepthTest()
RenderSystem.enableCull()
RenderSystem.disableBlend()
}
}
}