1.21.3 WIP
This commit is contained in:
@@ -1,25 +1,46 @@
|
||||
@file:OptIn(ExperimentalContracts::class)
|
||||
|
||||
package moe.nea.firmament.util
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
||||
object ErrorUtil {
|
||||
var aggressiveErrors = run {
|
||||
Thread.currentThread().stackTrace.any { it.className.startsWith("org.junit.") } || Firmament.DEBUG
|
||||
|| ErrorUtil::class.java.desiredAssertionStatus()
|
||||
}
|
||||
|
||||
inline fun softCheck(message: String, func: () -> Boolean) {
|
||||
inline fun softCheck(message: String, check: Boolean) {
|
||||
if (!check) softError(message)
|
||||
}
|
||||
|
||||
inline fun lazyCheck(message: String, func: () -> Boolean) {
|
||||
contract {
|
||||
callsInPlace(func, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (!aggressiveErrors) return
|
||||
if (func()) return
|
||||
error(message)
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE") // Suppressed since i want the logger to not pick up the ErrorUtil stack-frame
|
||||
inline fun softError(message: String, exception: Throwable) {
|
||||
if (aggressiveErrors) throw IllegalStateException(message, exception)
|
||||
else Firmament.logger.error(message, exception)
|
||||
}
|
||||
|
||||
inline fun softError(message: String) {
|
||||
if (aggressiveErrors) error(message)
|
||||
else Firmament.logger.error(message)
|
||||
}
|
||||
|
||||
inline fun <T : Any> notNullOr(nullable: T?, message: String, orElse: () -> T): T {
|
||||
contract {
|
||||
callsInPlace(orElse, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (nullable == null) {
|
||||
softError(message)
|
||||
return orElse()
|
||||
|
||||
@@ -3,9 +3,13 @@ package moe.nea.firmament.util
|
||||
import io.github.moulberry.repo.data.Coordinate
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
||||
import net.minecraft.client.option.GameOptions
|
||||
import net.minecraft.client.network.ClientPlayerEntity
|
||||
import net.minecraft.client.render.WorldRenderer
|
||||
import net.minecraft.client.render.item.ItemRenderer
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket
|
||||
import net.minecraft.registry.BuiltinRegistries
|
||||
@@ -14,7 +18,9 @@ import net.minecraft.registry.RegistryWrapper
|
||||
import net.minecraft.resource.ReloadableResourceManagerImpl
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import moe.nea.firmament.events.TickEvent
|
||||
import moe.nea.firmament.events.WorldReadyEvent
|
||||
|
||||
object MC {
|
||||
|
||||
@@ -29,6 +35,9 @@ object MC {
|
||||
(nextTickTodos.poll() ?: break).invoke()
|
||||
}
|
||||
}
|
||||
WorldReadyEvent.subscribe("MC:ready") {
|
||||
this.lastWorld
|
||||
}
|
||||
}
|
||||
|
||||
fun sendChat(text: Text) {
|
||||
@@ -69,6 +78,7 @@ object MC {
|
||||
|
||||
|
||||
inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManagerImpl)
|
||||
inline val itemRenderer: ItemRenderer get() = instance.itemRenderer
|
||||
inline val worldRenderer: WorldRenderer get() = instance.worldRenderer
|
||||
inline val networkHandler get() = player?.networkHandler
|
||||
inline val instance get() = MinecraftClient.getInstance()
|
||||
@@ -79,11 +89,11 @@ object MC {
|
||||
inline val inGameHud get() = instance.inGameHud
|
||||
inline val font get() = instance.textRenderer
|
||||
inline val soundManager get() = instance.soundManager
|
||||
inline val player get() = instance.player
|
||||
inline val camera get() = instance.cameraEntity
|
||||
inline val player: ClientPlayerEntity? get() = instance.player
|
||||
inline val camera: Entity? get() = instance.cameraEntity
|
||||
inline val guiAtlasManager get() = instance.guiAtlasManager
|
||||
inline val world get() = instance.world
|
||||
inline var screen
|
||||
inline val world: ClientWorld? get() = instance.world
|
||||
inline var screen: Screen?
|
||||
get() = instance.currentScreen
|
||||
set(value) = instance.setScreen(value)
|
||||
val screenName get() = screen?.title?.unformattedString?.trim()
|
||||
@@ -92,7 +102,13 @@ object MC {
|
||||
inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager
|
||||
val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup()
|
||||
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
|
||||
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getWrapperOrThrow(RegistryKeys.ITEM)
|
||||
val defaultItems: RegistryWrapper.Impl<Item> = defaultRegistries.getOrThrow(RegistryKeys.ITEM)
|
||||
var lastWorld: World? = null
|
||||
get() {
|
||||
field = world ?: field
|
||||
return field
|
||||
}
|
||||
private set
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ object SBData {
|
||||
it.serverType.getOrNull()?.name?.uppercase(),
|
||||
it.mode.getOrNull(),
|
||||
it.map.getOrNull())
|
||||
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
|
||||
SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw))
|
||||
profileIdCommandDebounce = TimeMark.now()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
package moe.nea.firmament.util
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import io.github.moulberry.repo.data.NEUIngredient
|
||||
import io.github.moulberry.repo.data.NEUItem
|
||||
import io.github.moulberry.repo.data.Rarity
|
||||
@@ -16,6 +17,9 @@ import net.minecraft.component.type.NbtComponent
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.network.RegistryByteBuf
|
||||
import net.minecraft.network.codec.PacketCodec
|
||||
import net.minecraft.network.codec.PacketCodecs
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.repo.ItemCache.asItemStack
|
||||
import moe.nea.firmament.repo.set
|
||||
@@ -68,6 +72,9 @@ value class SkyblockId(val neuItem: String) {
|
||||
val NULL: SkyblockId = SkyblockId("null")
|
||||
val PET_NULL: SkyblockId = SkyblockId("null_pet")
|
||||
private val illlegalPathRegex = "[^a-z0-9_.-/]".toRegex()
|
||||
val CODEC = Codec.STRING.xmap({ SkyblockId(it) }, { it.neuItem })
|
||||
val PACKET_CODEC: PacketCodec<in RegistryByteBuf, SkyblockId> =
|
||||
PacketCodecs.STRING.xmap({ SkyblockId(it) }, { it.neuItem })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,77 +1,71 @@
|
||||
|
||||
|
||||
package moe.nea.firmament.util.data
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
|
||||
import kotlin.reflect.KClass
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.server.command.CommandOutput
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.events.ScreenChangeEvent
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
interface IDataHolder<T> {
|
||||
companion object {
|
||||
internal var badLoads: MutableList<String> = CopyOnWriteArrayList()
|
||||
private val allConfigs: MutableMap<KClass<out IDataHolder<*>>, IDataHolder<*>> = mutableMapOf()
|
||||
private val dirty: MutableSet<KClass<out IDataHolder<*>>> = mutableSetOf()
|
||||
companion object {
|
||||
internal var badLoads: MutableList<String> = CopyOnWriteArrayList()
|
||||
private val allConfigs: MutableMap<KClass<out IDataHolder<*>>, IDataHolder<*>> = mutableMapOf()
|
||||
private val dirty: MutableSet<KClass<out IDataHolder<*>>> = mutableSetOf()
|
||||
|
||||
internal fun <T : IDataHolder<K>, K> putDataHolder(kClass: KClass<T>, inst: IDataHolder<K>) {
|
||||
allConfigs[kClass] = inst
|
||||
}
|
||||
internal fun <T : IDataHolder<K>, K> putDataHolder(kClass: KClass<T>, inst: IDataHolder<K>) {
|
||||
allConfigs[kClass] = inst
|
||||
}
|
||||
|
||||
fun <T : IDataHolder<K>, K> markDirty(kClass: KClass<T>) {
|
||||
if (kClass !in allConfigs) {
|
||||
Firmament.logger.error("Tried to markDirty '${kClass.qualifiedName}', which isn't registered as 'IConfigHolder'")
|
||||
return
|
||||
}
|
||||
dirty.add(kClass)
|
||||
}
|
||||
fun <T : IDataHolder<K>, K> markDirty(kClass: KClass<T>) {
|
||||
if (kClass !in allConfigs) {
|
||||
Firmament.logger.error("Tried to markDirty '${kClass.qualifiedName}', which isn't registered as 'IConfigHolder'")
|
||||
return
|
||||
}
|
||||
dirty.add(kClass)
|
||||
}
|
||||
|
||||
private fun performSaves() {
|
||||
val toSave = dirty.toList().also {
|
||||
dirty.clear()
|
||||
}
|
||||
for (it in toSave) {
|
||||
val obj = allConfigs[it]
|
||||
if (obj == null) {
|
||||
Firmament.logger.error("Tried to save '${it}', which isn't registered as 'ConfigHolder'")
|
||||
continue
|
||||
}
|
||||
obj.save()
|
||||
}
|
||||
}
|
||||
private fun performSaves() {
|
||||
val toSave = dirty.toList().also {
|
||||
dirty.clear()
|
||||
}
|
||||
for (it in toSave) {
|
||||
val obj = allConfigs[it]
|
||||
if (obj == null) {
|
||||
Firmament.logger.error("Tried to save '${it}', which isn't registered as 'ConfigHolder'")
|
||||
continue
|
||||
}
|
||||
obj.save()
|
||||
}
|
||||
}
|
||||
|
||||
private fun warnForResetConfigs(player: CommandOutput) {
|
||||
if (badLoads.isNotEmpty()) {
|
||||
player.sendMessage(
|
||||
Text.literal(
|
||||
"The following configs have been reset: ${badLoads.joinToString(", ")}. " +
|
||||
"This can be intentional, but probably isn't."
|
||||
)
|
||||
)
|
||||
badLoads.clear()
|
||||
}
|
||||
}
|
||||
private fun warnForResetConfigs() {
|
||||
if (badLoads.isNotEmpty()) {
|
||||
MC.sendChat(
|
||||
Text.literal(
|
||||
"The following configs have been reset: ${badLoads.joinToString(", ")}. " +
|
||||
"This can be intentional, but probably isn't."
|
||||
)
|
||||
)
|
||||
badLoads.clear()
|
||||
}
|
||||
}
|
||||
|
||||
fun registerEvents() {
|
||||
ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
|
||||
performSaves()
|
||||
val p = MinecraftClient.getInstance().player
|
||||
if (p != null) {
|
||||
warnForResetConfigs(p)
|
||||
}
|
||||
}
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
|
||||
performSaves()
|
||||
})
|
||||
}
|
||||
fun registerEvents() {
|
||||
ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
|
||||
performSaves()
|
||||
warnForResetConfigs()
|
||||
}
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
|
||||
performSaves()
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val data: T
|
||||
fun save()
|
||||
fun markDirty()
|
||||
fun load()
|
||||
val data: T
|
||||
fun save()
|
||||
fun markDirty()
|
||||
fun load()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user