mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
hud: font rendering fixes, more debug info
This commit is contained in:
parent
034e6e8f01
commit
39758cf057
@ -38,6 +38,7 @@ class Font(
|
||||
const val CHAR_MARGIN = 1 // used for background
|
||||
const val TOTAL_CHAR_HEIGHT = CHAR_HEIGHT + 2 * CHAR_MARGIN // top and bottom
|
||||
const val HORIZONTAL_SPACING = 1
|
||||
const val HORIZONTAL_SPACING_SHADOW = 0
|
||||
const val VERTICAL_SPACING = 3
|
||||
}
|
||||
}
|
||||
|
@ -22,21 +22,35 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.util.KUtil.decide
|
||||
import de.bixilon.minosoft.util.MMath.ceil
|
||||
import glm_.vec2.Vec2i
|
||||
|
||||
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, z: Int, element: Element, fontAlignment: ElementAlignments, renderWindow: RenderWindow, consumer: GUIVertexConsumer?, renderInfo: TextRenderInfo, text: TextComponent): Boolean {
|
||||
if (text.message.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
val elementMaxSize = element.maxSize
|
||||
val shadow = text.formatting.contains(PreChatFormattingCodes.SHADOWED)
|
||||
// ToDo: Only 1 quad for the underline and the strikethrough
|
||||
|
||||
var alignmentXOffset = 0
|
||||
if (size.x >= elementMaxSize.x || size.y >= elementMaxSize.y) {
|
||||
if (size.x > elementMaxSize.x || size.y > elementMaxSize.y) {
|
||||
// The size is already bigger/equals the maximum size
|
||||
return true
|
||||
}
|
||||
|
||||
fun applyOffset() {
|
||||
if (consumer == null) {
|
||||
// preparing phase
|
||||
renderInfo.lines += TextLineInfo()
|
||||
} else {
|
||||
alignmentXOffset = fontAlignment.getOffset(element.size.x, renderInfo.currentLine.width)
|
||||
}
|
||||
}
|
||||
|
||||
fun addY(height: Int): Boolean {
|
||||
val nextY = offset.y + height
|
||||
val nextSizeY = nextY - initialOffset.y + Font.TOTAL_CHAR_HEIGHT // add initial height for chars + end margin
|
||||
@ -54,14 +68,9 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
if (addY(Font.TOTAL_CHAR_HEIGHT)) {
|
||||
return true
|
||||
}
|
||||
renderInfo.currentLine++
|
||||
renderInfo.currentLineNumber++
|
||||
offset.x = initialOffset.x + Font.CHAR_MARGIN
|
||||
if (consumer == null) {
|
||||
// preparing phase
|
||||
renderInfo.lines += TextLineInfo()
|
||||
} else {
|
||||
alignmentXOffset = fontAlignment.getOffset(element.size.x, renderInfo.lines[renderInfo.currentLine].width)
|
||||
}
|
||||
applyOffset()
|
||||
return false
|
||||
}
|
||||
|
||||
@ -78,7 +87,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
return addX(width, false)
|
||||
}
|
||||
if (consumer == null) {
|
||||
renderInfo.lines[renderInfo.currentLine].width += width
|
||||
renderInfo.currentLine.width += width
|
||||
}
|
||||
offset.x = nextX
|
||||
if (nextSizeX > size.x) {
|
||||
@ -94,15 +103,11 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
if (nextSizeY > elementMaxSize.y) {
|
||||
return true
|
||||
}
|
||||
if (consumer != null) {
|
||||
alignmentXOffset = fontAlignment.getOffset(element.size.x, renderInfo.lines[renderInfo.currentLine].width)
|
||||
} else {
|
||||
renderInfo.lines += TextLineInfo() // add line 0
|
||||
}
|
||||
size.y = nextSizeY
|
||||
size.x += Font.CHAR_MARGIN * 2
|
||||
offset += Font.CHAR_MARGIN
|
||||
}
|
||||
applyOffset()
|
||||
|
||||
|
||||
for (charCode in text.message.codePoints().toArray()) {
|
||||
@ -126,7 +131,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
if (offset.x != initialOffset.x + Font.CHAR_MARGIN) {
|
||||
// add spacing between letters
|
||||
width += Font.HORIZONTAL_SPACING
|
||||
width += shadow.decide(Font.HORIZONTAL_SPACING_SHADOW, Font.HORIZONTAL_SPACING)
|
||||
}
|
||||
val previousY = offset.y
|
||||
|
||||
@ -147,7 +152,7 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
consumer?.let { charData.render(letterOffset, z, text, it) }
|
||||
|
||||
if (consumer == null) {
|
||||
renderInfo.lines[renderInfo.currentLine].chars += char
|
||||
renderInfo.currentLine.chars += char
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,5 +15,8 @@ package de.bixilon.minosoft.gui.rendering.font.renderer
|
||||
|
||||
class TextRenderInfo(
|
||||
val lines: MutableList<TextLineInfo> = mutableListOf(),
|
||||
var currentLine: Int = 0,
|
||||
)
|
||||
var currentLineNumber: Int = 0,
|
||||
) {
|
||||
val currentLine: TextLineInfo
|
||||
get() = lines[currentLineNumber]
|
||||
}
|
||||
|
@ -13,13 +13,15 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.gui.elements.text
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
|
||||
|
||||
class AutoTextElement(
|
||||
hudRenderer: HUDRenderer,
|
||||
var interval: Int,
|
||||
alignment: ElementAlignments = ElementAlignments.LEFT,
|
||||
private val updater: () -> Any,
|
||||
) : TextElement(hudRenderer, "") {
|
||||
) : TextElement(hudRenderer, "", alignment) {
|
||||
private var remainingTicks = 0
|
||||
|
||||
init {
|
||||
|
@ -46,11 +46,16 @@ open class TextElement(
|
||||
prepared = false
|
||||
}
|
||||
|
||||
private var emptyMessage: Boolean = true
|
||||
|
||||
final override var textComponent: ChatComponent = ChatComponent.of("")
|
||||
protected set(value) {
|
||||
field = value
|
||||
emptyMessage = value.message.isEmpty()
|
||||
val prefSize = Vec2i.EMPTY
|
||||
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, prefSize, 0, InfiniteSizeElement(hudRenderer), fontAlignment, renderWindow, null, TextRenderInfo(), value)
|
||||
if (!emptyMessage) {
|
||||
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, prefSize, 0, InfiniteSizeElement(hudRenderer), fontAlignment, renderWindow, null, TextRenderInfo(), value)
|
||||
}
|
||||
this.prefSize = prefSize
|
||||
apply()
|
||||
}
|
||||
@ -62,17 +67,16 @@ open class TextElement(
|
||||
}
|
||||
|
||||
override fun silentApply() {
|
||||
size = Vec2i.EMPTY
|
||||
if (textComponent.message.isNotEmpty()) {
|
||||
val size = Vec2i.EMPTY
|
||||
val size = Vec2i.EMPTY
|
||||
if (!emptyMessage) {
|
||||
val renderInfo = TextRenderInfo()
|
||||
ChatComponentRenderer.render(Vec2i.EMPTY, Vec2i.EMPTY, size, 0, this, fontAlignment, renderWindow, null, renderInfo, textComponent)
|
||||
|
||||
renderInfo.currentLine = 0
|
||||
renderInfo.currentLineNumber = 0
|
||||
this.renderInfo = renderInfo
|
||||
this.size = size
|
||||
preparedSize = size
|
||||
}
|
||||
|
||||
this.size = size
|
||||
preparedSize = size
|
||||
}
|
||||
|
||||
override fun apply() {
|
||||
@ -96,10 +100,13 @@ open class TextElement(
|
||||
|
||||
|
||||
override fun render(offset: Vec2i, z: Int, consumer: GUIVertexConsumer): Int {
|
||||
if (emptyMessage) {
|
||||
return 0
|
||||
}
|
||||
val initialOffset = offset + margin.offset
|
||||
|
||||
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, consumer, renderInfo, textComponent)
|
||||
renderInfo.currentLine = 0
|
||||
renderInfo.currentLineNumber = 0
|
||||
prepared = true
|
||||
|
||||
if (background) {
|
||||
|
@ -63,7 +63,7 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
|
||||
|
||||
private fun initLeft(): Element {
|
||||
val layout = RowLayout(hudRenderer)
|
||||
layout.margin = Vec4i(5)
|
||||
layout.margin = Vec4i(2)
|
||||
layout += TextElement(hudRenderer, TextComponent(RunConfiguration.VERSION_STRING, ChatColors.RED))
|
||||
layout += AutoTextElement(hudRenderer, 1) { "FPS ${renderWindow.renderStats.smoothAvgFPS.round10}" }
|
||||
renderWindow[WorldRenderer]?.apply {
|
||||
@ -93,7 +93,7 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
|
||||
|
||||
layout += LineSpacerElement(hudRenderer)
|
||||
|
||||
layout += TextElement(hudRenderer, "Difficulty ${connection.world.difficulty.format()}, ${connection.world.difficultyLocked.decide("locked", "unlocked")}", ElementAlignments.RIGHT).apply {
|
||||
layout += TextElement(hudRenderer, "Difficulty ${connection.world.difficulty.format()}, ${connection.world.difficultyLocked.decide("locked", "unlocked")}").apply {
|
||||
connection.registerEvent(CallbackEventInvoker.of<DifficultyChangeEvent> {
|
||||
text = "Difficulty ${it.difficulty.format()}, ${it.locked.decide("locked", "unlocked")}"
|
||||
})
|
||||
@ -104,7 +104,7 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
|
||||
|
||||
private fun initRight(): Element {
|
||||
val layout = RowLayout(hudRenderer, ElementAlignments.RIGHT)
|
||||
layout.margin = Vec4i(5)
|
||||
layout.margin = Vec4i(2)
|
||||
layout += TextElement(hudRenderer, "Java ${Runtime.version()} ${System.getProperty("sun.arch.data.model")}bit", ElementAlignments.RIGHT)
|
||||
|
||||
layout += LineSpacerElement(hudRenderer)
|
||||
@ -137,6 +137,14 @@ class DebugHUD(val hudRenderer: HUDRenderer) : HUD<GridLayout> {
|
||||
|
||||
layout += TextElement(hudRenderer, "Mods ${ModLoader.MOD_MAP.size}x loaded, ${connection.size}x listeners", ElementAlignments.RIGHT)
|
||||
|
||||
layout += LineSpacerElement(hudRenderer)
|
||||
|
||||
renderWindow.inputHandler.camera.apply {
|
||||
layout += AutoTextElement(hudRenderer, 1, ElementAlignments.RIGHT) {
|
||||
// ToDo: Tags
|
||||
target ?: return@AutoTextElement ""
|
||||
}
|
||||
}
|
||||
return layout
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ class Camera(
|
||||
var cameraRight = Vec3d(0.0, 0.0, -1.0)
|
||||
private var cameraUp = Vec3d(0.0, 1.0, 0.0)
|
||||
|
||||
// ToDo: They should also be available in headless mode
|
||||
var target: RaycastHit? = null
|
||||
private set
|
||||
var blockTarget: BlockRaycastHit? = null // Block target or if blocked by entity null
|
||||
|
@ -15,7 +15,9 @@ package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.util.KUtil.format
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.data.text.TextFormattable
|
||||
import glm_.vec3.Vec3d
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
@ -25,23 +27,29 @@ open class BlockRaycastHit(
|
||||
hitDirection: Directions,
|
||||
val blockState: BlockState,
|
||||
val blockPosition: Vec3i,
|
||||
) : RaycastHit(position, distance, hitDirection) {
|
||||
) : RaycastHit(position, distance, hitDirection), TextFormattable {
|
||||
val hitPosition = position - blockPosition
|
||||
|
||||
override fun toString(): String {
|
||||
val ret = StringBuilder()
|
||||
ret.append(blockPosition)
|
||||
ret.append(": ")
|
||||
ret.append(blockState.block.resourceLocation)
|
||||
return toText().legacyText
|
||||
}
|
||||
|
||||
for ((key, value) in blockState.properties) {
|
||||
ret.append('\n')
|
||||
ret.append(' ')
|
||||
ret.append(key.group)
|
||||
ret.append(": ")
|
||||
ret.append(value.format())
|
||||
override fun toText(): ChatComponent {
|
||||
val text = BaseComponent()
|
||||
|
||||
text += "Block target "
|
||||
text += blockPosition
|
||||
text += ": "
|
||||
text += blockState.block.resourceLocation
|
||||
|
||||
for ((property, value) in blockState.properties) {
|
||||
text += "\n"
|
||||
text += property
|
||||
text += ": "
|
||||
text += value
|
||||
}
|
||||
|
||||
return ret.toString()
|
||||
return text
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,20 +34,25 @@ class EntityRaycastHit(
|
||||
override fun toText(): ChatComponent {
|
||||
val text = BaseComponent()
|
||||
|
||||
text += "Entity target "
|
||||
text += position
|
||||
text += (": ")
|
||||
text += ": "
|
||||
text += entity.entityType.resourceLocation
|
||||
|
||||
text += "\n Id: "
|
||||
text += entity.id
|
||||
|
||||
text += "\n UUID: "
|
||||
text += entity.uuid
|
||||
text += "\n"
|
||||
text += "Id: ${entity.id}"
|
||||
text += "\n"
|
||||
text += "UUID: ${entity.uuid}"
|
||||
|
||||
for ((key, value) in entity.entityMetaDataFormatted) {
|
||||
text += "\n "
|
||||
text += key
|
||||
|
||||
val metaData = entity.entityMetaDataFormatted
|
||||
if (metaData.isNotEmpty()) {
|
||||
text += "\n"
|
||||
}
|
||||
|
||||
for ((property, value) in metaData) {
|
||||
text += "\n"
|
||||
text += property
|
||||
text += ": "
|
||||
text += value
|
||||
}
|
||||
|
@ -15,8 +15,10 @@ package de.bixilon.minosoft.gui.rendering.input.camera.hit
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.fluid.Fluid
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.data.text.TextFormattable
|
||||
import glm_.vec3.Vec3d
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
@ -27,9 +29,27 @@ class FluidRaycastHit(
|
||||
val blockState: BlockState,
|
||||
val blockPosition: Vec3i,
|
||||
val fluid: Fluid,
|
||||
) : RaycastHit(position, distance, hitDirection) {
|
||||
) : RaycastHit(position, distance, hitDirection), TextFormattable {
|
||||
|
||||
override fun toString(): String {
|
||||
return "$blockPosition: ${fluid.resourceLocation}\n Height: ${fluid.getHeight(blockState)}\n Level: ${blockState.properties[BlockProperties.FLUID_LEVEL]}"
|
||||
return toText().legacyText
|
||||
}
|
||||
|
||||
override fun toText(): ChatComponent {
|
||||
val text = BaseComponent()
|
||||
|
||||
text += "Fluid target "
|
||||
text += blockPosition
|
||||
text += ": "
|
||||
text += fluid.resourceLocation
|
||||
|
||||
for ((property, value) in blockState.properties) {
|
||||
text += "\n"
|
||||
text += property
|
||||
text += ": "
|
||||
text += value
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import de.bixilon.minosoft.util.enum.AliasableEnum
|
||||
import de.bixilon.minosoft.util.json.JSONSerializer
|
||||
import glm_.vec2.Vec2t
|
||||
import glm_.vec3.Vec3t
|
||||
import glm_.vec4.Vec4t
|
||||
import okio.Buffer
|
||||
import sun.misc.Unsafe
|
||||
import java.io.PrintWriter
|
||||
@ -255,6 +256,8 @@ object KUtil {
|
||||
is Float -> "§d%.3f".format(this)
|
||||
is Double -> "§d%.4f".format(this)
|
||||
is Number -> TextComponent(this).color(ChatColors.LIGHT_PURPLE)
|
||||
is ResourceLocation -> TextComponent(this.toString()).color(ChatColors.GOLD)
|
||||
is Vec4t<*> -> "(${this.x.format()} ${this.y.format()} ${this.z.format()} ${this.w.format()})"
|
||||
is Vec3t<*> -> "(${this.x.format()} ${this.y.format()} ${this.z.format()})"
|
||||
is Vec2t<*> -> "(${this.x.format()} ${this.y.format()})"
|
||||
else -> this.toString()
|
||||
|
Loading…
x
Reference in New Issue
Block a user