diff --git a/build.gradle.kts b/build.gradle.kts
index 824b0a635..a76a52d43 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -222,7 +222,7 @@ testing {
options {
val options = this as TestNGOptions
options.preserveOrder = true
- // options.excludeGroups("pixlyzer", "light", "packet", "version", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "world_renderer", "rendering")
+ options.excludeGroups("command", "registry", "biome", "input", "version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "world_renderer", "rendering")
}
}
}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/DummyCodePointRenderer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/DummyCodePointRenderer.kt
new file mode 100644
index 000000000..09f2e8358
--- /dev/null
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/DummyCodePointRenderer.kt
@@ -0,0 +1,26 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.font.renderer.code
+
+import de.bixilon.kotlinglm.vec2.Vec2
+import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
+import de.bixilon.minosoft.gui.rendering.system.dummy.texture.DummyTexture
+
+class DummyCodePointRenderer(
+ override val uvStart: Vec2 = Vec2(0.1f, 0.2f),
+ override val uvEnd: Vec2 = Vec2(0.6f, 0.7f),
+ override val width: Float = 5.0f,
+) : RasterizedCodePointRenderer {
+ override val texture = DummyTexture(minosoft("test"))
+}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRendererTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRendererTest.kt
new file mode 100644
index 000000000..854cf3f35
--- /dev/null
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRendererTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.font.renderer.code
+
+import de.bixilon.kotlinglm.vec2.Vec2
+import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
+import de.bixilon.minosoft.data.text.formatting.color.ChatColors
+import de.bixilon.minosoft.data.text.formatting.color.RGBColor
+import de.bixilon.minosoft.gui.rendering.gui.mesh.DummyGUIVertexConsumer
+import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
+import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
+import org.testng.Assert.assertEquals
+import org.testng.Assert.assertNull
+import org.testng.annotations.Test
+
+@Test(groups = ["font"], priority = -1)
+class RasterizedCodePointRendererTest {
+
+ fun verifySimpleSetup() {
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
+ this.char++
+ assertEquals(tint, ChatColors.BLUE)
+ assertEquals(uvStart, Vec2(0.1, 0.2))
+ assertEquals(uvEnd, Vec2(0.6, 0.7))
+ assertEquals(texture.resourceLocation, minosoft("test"))
+ assertNull(options)
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, false, false, false, 1.0f, consumer, null)
+
+ assertEquals(1, consumer.char)
+ }
+
+ fun verifyComplexSetup() {
+ var chars = 0
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
+ chars++
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, true, true, false, 1.0f, consumer, null)
+
+ assertEquals(4, chars)
+ }
+
+ fun unformatted() {
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, index: Int) {
+ assertEquals(start, Vec2(10.0f, 13.0f)) // top spacing
+ assertEquals(end, Vec2(15.0f, 21.0f)) // start + width | start + height
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, false, false, false, 1.0f, consumer, null)
+ }
+
+ fun scaled() {
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
+ assertEquals(start, Vec2(10.0f, 13.5f)) // top spacing
+ assertEquals(end, Vec2(17.5f, 25.5f)) // start + width | start + height
+
+ // uv stays the same
+ assertEquals(uvStart, Vec2(0.1, 0.2))
+ assertEquals(uvEnd, Vec2(0.6, 0.7))
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, false, false, false, 1.5f, consumer, null)
+ }
+
+ fun shadow() {
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, index: Int) {
+ if (index == 1) return
+ assertEquals(start, Vec2(11.0f, 14.0f))
+ assertEquals(end, Vec2(16.0f, 22.0f))
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, true, false, false, 1.0f, consumer, null)
+
+ assertEquals(consumer.char, 2)
+ }
+
+ fun bold() {
+ val consumer = object : DummyGUIVertexConsumer() {
+ override fun addChar(start: Vec2, end: Vec2, index: Int) {
+ if (index == 0) return
+ assertEquals(start, Vec2(10.5f, 13.0f))
+ assertEquals(end, Vec2(15.5f, 21.0f))
+ }
+ }
+ val char = DummyCodePointRenderer()
+
+ char.render(Vec2(10.0f, 12.0f), ChatColors.BLUE, false, true, false, 1.0f, consumer, null)
+
+ assertEquals(consumer.char, 2)
+ }
+
+ // TODO: ascent
+}
diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt
new file mode 100644
index 000000000..7d293f24b
--- /dev/null
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt
@@ -0,0 +1,50 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.gui.mesh
+
+import de.bixilon.kotlinglm.vec2.Vec2
+import de.bixilon.kotlinglm.vec2.Vec2i
+import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
+import de.bixilon.minosoft.data.text.formatting.color.RGBColor
+import de.bixilon.minosoft.gui.rendering.gui.atlas.CodeTexturePart
+import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
+import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
+import de.bixilon.minosoft.gui.rendering.system.dummy.texture.DummyTexture
+import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
+
+open class DummyGUIVertexConsumer : GUIVertexConsumer {
+ override val whiteTexture = CodeTexturePart(texture = DummyTexture(minosoft("white")), uvStart = Vec2(0.0f, 0.0f), uvEnd = Vec2(0.001f, 0.001f), size = Vec2i(16, 16))
+ override val order: Array> get() = Mesh.QUAD_TO_QUAD_ORDER
+ var char = 0
+
+ override fun addCache(cache: GUIMeshCache) {
+ TODO("Not yet implemented")
+ }
+
+ override fun ensureSize(size: Int) {
+ TODO("Not yet implemented")
+ }
+
+ override fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
+ TODO("Not yet implemented")
+ }
+
+ override fun addChar(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
+ addChar(start, end, this.char++)
+ }
+
+ open fun addChar(start: Vec2, end: Vec2, index: Int) {
+ TODO("Abstract")
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt
index f79b4e720..17104be2b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt
@@ -16,7 +16,6 @@ package de.bixilon.minosoft.gui.rendering.font
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
-import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.font.renderer.component.ChatComponentRenderer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
@@ -27,7 +26,7 @@ import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh
class WorldGUIConsumer(val mesh: SingleWorldMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer {
- override val context: RenderContext get() = mesh.context
+ override val whiteTexture = mesh.context.textureManager.whiteTexture
override val order: Array> get() = mesh.order
override fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/CodePointRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/CodePointRenderer.kt
index 631b53c48..992f93165 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/CodePointRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/CodePointRenderer.kt
@@ -14,7 +14,6 @@
package de.bixilon.minosoft.gui.rendering.font.renderer.code
import de.bixilon.kotlinglm.vec2.Vec2
-import de.bixilon.minosoft.data.text.formatting.TextFormatting
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.WorldGUIConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
@@ -25,10 +24,10 @@ interface CodePointRenderer {
fun calculateWidth(scale: Float, shadow: Boolean): Float
- fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float)
+ fun render(position: Vec2, color: RGBColor, shadow: Boolean, bold: Boolean, italic: Boolean, scale: Float, consumer: GUIVertexConsumer, options: GUIVertexOptions?)
- fun render3d(consumer: WorldGUIConsumer, color: RGBColor, shadow: Boolean, formatting: TextFormatting, scale: Float): Float {
- render(Vec2.EMPTY, color, shadow, formatting, consumer, null, scale)
+ fun render3d(color: RGBColor, shadow: Boolean, bold: Boolean, italic: Boolean, scale: Float, consumer: WorldGUIConsumer): Float {
+ render(Vec2.EMPTY, color, shadow, bold, italic, scale, consumer, null)
return calculateWidth(scale, shadow)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRenderer.kt
index 059fe4888..5966a07d0 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/code/RasterizedCodePointRenderer.kt
@@ -14,15 +14,11 @@
package de.bixilon.minosoft.gui.rendering.font.renderer.code
import de.bixilon.kotlinglm.vec2.Vec2
-import de.bixilon.minosoft.data.text.formatting.FormattingCodes
-import de.bixilon.minosoft.data.text.formatting.TextFormatting
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.BOLD_OFFSET
-import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.ITALIC_OFFSET
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.SHADOW_COLOR
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties.SHADOW_OFFSET
-import de.bixilon.minosoft.gui.rendering.font.types.font.Font
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
@@ -45,11 +41,11 @@ interface RasterizedCodePointRenderer : CodePointRenderer {
return width * scale
}
- override fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
+ override fun render(position: Vec2, color: RGBColor, shadow: Boolean, bold: Boolean, italic: Boolean, scale: Float, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
if (shadow) {
- render(position + (SHADOW_OFFSET * scale), color * SHADOW_COLOR, formatting, consumer, options, scale)
+ render(position + (SHADOW_OFFSET * scale), color * SHADOW_COLOR, bold, italic, scale, consumer, options)
}
- render(position, color, formatting, consumer, options, scale)
+ render(position, color, bold, italic, scale, consumer, options)
}
fun calculateStart(base: Vec2, scale: Float): Vec2 {
@@ -67,61 +63,19 @@ interface RasterizedCodePointRenderer : CodePointRenderer {
return position
}
- private fun render(position: Vec2, color: RGBColor, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) {
- var boldOffset = 0.0f
-
- val bold = FormattingCodes.BOLD in formatting
- val italic = FormattingCodes.ITALIC in formatting
-
- if (bold) {
- boldOffset = BOLD_OFFSET * scale
- }
- val charHeight = FontProperties.CHAR_BASE_HEIGHT * scale
- val horizontalSpacing = Font.HORIZONTAL_SPACING * scale
- val verticalSpacing = Font.VERTICAL_SPACING * scale
-
-
+ private fun render(position: Vec2, color: RGBColor, bold: Boolean, italic: Boolean, scale: Float, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
val startPosition = calculateStart(position, scale)
val endPosition = calculateEnd(startPosition, scale)
+ consumer.addChar(startPosition, endPosition, texture, uvStart, uvEnd, italic, color, options)
-
- consumer.addQuad(startPosition, endPosition, texture, uvStart, uvEnd, italic, color, options)
-
- if (FormattingCodes.BOLD in formatting) {
- consumer.addQuad(startPosition + Vec2(boldOffset, 0.0f), endPosition + Vec2(boldOffset, 0.0f), texture, uvStart, uvEnd, italic, color, options)
- }
- val whiteTexture = consumer.context.textureManager.whiteTexture
-
- if (FormattingCodes.STRIKETHROUGH in formatting) {
- consumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight / 2.0f - scale / 2), Vec2(endPosition.x + horizontalSpacing, startPosition.y + charHeight / 2.0f + scale / 2), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
- }
-
- if (FormattingCodes.UNDERLINED in formatting) {
- consumer.addQuad(startPosition + Vec2(-horizontalSpacing, charHeight), Vec2(endPosition.x + boldOffset + horizontalSpacing, startPosition.y + charHeight + verticalSpacing / 2.0f), whiteTexture.texture, whiteTexture.uvStart, whiteTexture.uvEnd, italic, color, options)
+ if (bold) {
+ // render char another time but offset in x direction
+ val boldOffset = BOLD_OFFSET * scale
+ consumer.addChar(
+ start = startPosition + Vec2(boldOffset, 0.0f),
+ end = endPosition + Vec2(boldOffset, 0.0f),
+ texture, uvStart, uvEnd, italic, color, options)
}
}
-
-
- private fun GUIVertexConsumer.addQuad(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
- val topOffset = if (italic) (end.y - start.y) / FontProperties.CHAR_BASE_HEIGHT * ITALIC_OFFSET else 0.0f
-
- val positions = arrayOf(
- Vec2(start.x + topOffset, start.y),
- Vec2(end.x + topOffset, start.y),
- end,
- Vec2(start.x, end.y),
- )
- val texturePositions = arrayOf(
- Vec2(uvEnd.x, uvStart.y),
- uvStart,
- Vec2(uvStart.x, uvEnd.y),
- uvEnd,
- )
-
- for ((vertexIndex, textureIndex) in this.order) {
- addVertex(positions[vertexIndex], texture, texturePositions[textureIndex], tint, options)
- }
- }
-
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/component/TextComponentRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/component/TextComponentRenderer.kt
index 54ebbbf36..8ea9b9c66 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/component/TextComponentRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/component/TextComponentRenderer.kt
@@ -40,8 +40,10 @@ object TextComponentRenderer : ChatComponentRenderer {
val color = text.color ?: ChatColors.WHITE
val shadow = renderInfo.shadow
val bold: Boolean = text.formatting.contains(FormattingCodes.BOLD)
+ val italic: Boolean = text.formatting.contains(FormattingCodes.ITALIC)
// ToDo: Only 1 quad for the underline and the strikethrough
+ // TODO: strike, underlined
var alignmentXOffset = 0.0f
var currentLineText = ""
@@ -177,7 +179,7 @@ object TextComponentRenderer : ChatComponentRenderer {
// ToDo: Remove Font.HORIZONTAL_SPACING
}
- consumer?.let { charData.render(letterOffset, color, shadow, text.formatting, it, options, renderInfo.scale) }
+ consumer?.let { charData.render(letterOffset, color, shadow, bold, italic, renderInfo.scale, it, options) }
if (consumer == null) {
currentLineText += char.toChar()
@@ -209,13 +211,16 @@ object TextComponentRenderer : ChatComponentRenderer {
val font = context.font[text.font]
+
+ // TODO: strike, underlined
+
for (char in text.message.codePoints()) {
val data = font?.get(char) ?: context.font.default[char] ?: continue
val expectedWidth = ((data.calculateWidth(scale, false) + Font.HORIZONTAL_SPACING) * scale).toInt()
if (maxSize.x - offset.x < expectedWidth) { // ToDo
return
}
- val width = ((data.render3d(consumer, color, shadow = false, text.formatting, scale = scale) + Font.HORIZONTAL_SPACING) * scale).toInt()
+ val width = ((data.render3d(color, shadow = false, FormattingCodes.BOLD in text.formatting, FormattingCodes.ITALIC in text.formatting, scale = scale, consumer) + Font.HORIZONTAL_SPACING) * scale).toInt()
offset.x += width
consumer.offset((width / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION.toFloat()))
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/empty/EmptyCodeRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/empty/EmptyCodeRenderer.kt
index e34ae1bc4..2962af7bc 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/empty/EmptyCodeRenderer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/types/empty/EmptyCodeRenderer.kt
@@ -14,7 +14,6 @@
package de.bixilon.minosoft.gui.rendering.font.types.empty
import de.bixilon.kotlinglm.vec2.Vec2
-import de.bixilon.minosoft.data.text.formatting.TextFormatting
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.font.renderer.code.CodePointRenderer
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties.MAX_CHAR_WIDTH
@@ -31,5 +30,5 @@ data class EmptyCodeRenderer(
}
override fun calculateWidth(scale: Float, shadow: Boolean): Float = width * scale
- override fun render(position: Vec2, color: RGBColor, shadow: Boolean, formatting: TextFormatting, consumer: GUIVertexConsumer, options: GUIVertexOptions?, scale: Float) = Unit
+ override fun render(position: Vec2, color: RGBColor, shadow: Boolean, bold: Boolean, italic: Boolean, scale: Float, consumer: GUIVertexConsumer, options: GUIVertexOptions?) = Unit
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/AtlasElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/AtlasElement.kt
index 08e9337ef..3ce510d0d 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/AtlasElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/AtlasElement.kt
@@ -25,7 +25,7 @@ class AtlasElement(
val end: Vec2i,
val slots: Int2ObjectOpenHashMap,
val areas: Map,
-) : TextureLike {
+) : TexturePart {
override val size: Vec2i = end - start
override lateinit var uvStart: Vec2
override lateinit var uvEnd: Vec2
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLikeTexture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/CodeTexturePart.kt
similarity index 96%
rename from src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLikeTexture.kt
rename to src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/CodeTexturePart.kt
index a29650a28..838e2836a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLikeTexture.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/CodeTexturePart.kt
@@ -17,9 +17,9 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
-class TextureLikeTexture(
+class CodeTexturePart(
override val texture: AbstractTexture,
override val uvStart: Vec2,
override val uvEnd: Vec2,
override val size: Vec2i,
-) : TextureLike
+) : TexturePart
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLike.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TexturePart.kt
similarity index 97%
rename from src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLike.kt
rename to src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TexturePart.kt
index 47c1a0061..b34d23628 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TextureLike.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/atlas/TexturePart.kt
@@ -17,7 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
-interface TextureLike {
+interface TexturePart {
val texture: AbstractTexture
val uvStart: Vec2
val uvEnd: Vec2
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/AtlasImageElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/AtlasImageElement.kt
index c30c965e1..8b9a13c7a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/AtlasImageElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/primitive/AtlasImageElement.kt
@@ -18,7 +18,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
-import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLike
+import de.bixilon.minosoft.gui.rendering.gui.atlas.TexturePart
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMesh
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
@@ -28,11 +28,11 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
open class AtlasImageElement(
guiRenderer: GUIRenderer,
- textureLike: TextureLike?,
- size: Vec2i = textureLike?.size ?: Vec2i.EMPTY,
+ texturePart: TexturePart?,
+ size: Vec2i = texturePart?.size ?: Vec2i.EMPTY,
tint: RGBColor = ChatColors.WHITE,
) : Element(guiRenderer, GUIMesh.GUIMeshStruct.FLOATS_PER_VERTEX * 6) {
- var texture: AbstractTexture? = textureLike?.texture
+ var texture: AbstractTexture? = texturePart?.texture
set(value) {
field = value
cacheUpToDate = false
@@ -67,7 +67,7 @@ open class AtlasImageElement(
cacheUpToDate = false
}
- var textureLike: TextureLike? = textureLike
+ var texturePart: TexturePart? = texturePart
set(value) {
if (field === value) {
return
@@ -87,7 +87,7 @@ open class AtlasImageElement(
override fun forceRender(offset: Vec2i, consumer: GUIVertexConsumer, options: GUIVertexOptions?) {
val texture = texture ?: return
- val textureLike = textureLike ?: return
+ val textureLike = texturePart ?: return
consumer.addQuad(offset, offset + size, texture, uvStart ?: textureLike.uvStart, uvEnd ?: textureLike.uvEnd, tint, options)
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt
index 158b7af2b..c283fc18a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMesh.kt
@@ -27,6 +27,7 @@ class GUIMesh(
val halfSize: Vec2,
data: AbstractFloatList,
) : Mesh(context, GUIMeshStruct, initialCacheSize = 40000, clearOnLoad = false, data = data), GUIVertexConsumer {
+ override val whiteTexture = context.textureManager.whiteTexture
override fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
addVertex(data, halfSize, position, texture, uv, tint, options)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt
index 3f89f5a1c..d06468ca2 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt
@@ -25,10 +25,12 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
class GUIMeshCache(
var halfSize: Vec2,
override val order: Array>,
- override val context: RenderContext,
+ val context: RenderContext,
initialCacheSize: Int = 1000,
var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize),
) : GUIVertexConsumer {
+ override val whiteTexture = context.textureManager.whiteTexture
+
var revision: Long = 0
var offset: Vec2i = Vec2i.EMPTY
var options: GUIVertexOptions? = null
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt
index 159893589..886bd86bc 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt
@@ -16,12 +16,15 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
-import de.bixilon.minosoft.gui.rendering.RenderContext
-import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLike
+import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
+import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties
+import de.bixilon.minosoft.gui.rendering.gui.atlas.CodeTexturePart
+import de.bixilon.minosoft.gui.rendering.gui.atlas.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderIdentifiable
+import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
interface GUIVertexConsumer {
- val context: RenderContext
+ val whiteTexture: CodeTexturePart
val order: Array>
fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
@@ -67,14 +70,36 @@ interface GUIVertexConsumer {
}
}
- fun addQuad(start: Vec2, end: Vec2, texture: TextureLike, tint: RGBColor, options: GUIVertexOptions?) {
+ fun addQuad(start: Vec2, end: Vec2, texture: TexturePart, tint: RGBColor, options: GUIVertexOptions?) {
addQuad(start, end, texture.texture, texture.uvStart, texture.uvEnd, tint, options)
}
- fun addQuad(start: Vec2i, end: Vec2i, texture: TextureLike, tint: RGBColor, options: GUIVertexOptions?) {
+ fun addQuad(start: Vec2i, end: Vec2i, texture: TexturePart, tint: RGBColor, options: GUIVertexOptions?) {
addQuad(start, end, texture.texture, texture.uvStart, texture.uvEnd, tint, options)
}
+
+ fun addChar(start: Vec2, end: Vec2, texture: AbstractTexture, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) {
+ val topOffset = if (italic) (end.y - start.y) / FontProperties.CHAR_BASE_HEIGHT * FormattingProperties.ITALIC_OFFSET else 0.0f
+
+ val positions = arrayOf(
+ Vec2(start.x + topOffset, start.y),
+ Vec2(end.x + topOffset, start.y),
+ end,
+ Vec2(start.x, end.y),
+ )
+ val texturePositions = arrayOf(
+ Vec2(uvEnd.x, uvStart.y),
+ uvStart,
+ Vec2(uvStart.x, uvEnd.y),
+ uvEnd,
+ )
+
+ for ((vertexIndex, textureIndex) in this.order) {
+ addVertex(positions[vertexIndex], texture, texturePositions[textureIndex], tint, options)
+ }
+ }
+
fun addCache(cache: GUIMeshCache)
fun ensureSize(size: Int)
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
index 0499083ea..182a0a226 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/texture/TextureManager.kt
@@ -17,7 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.RenderConstants
-import de.bixilon.minosoft.gui.rendering.gui.atlas.TextureLikeTexture
+import de.bixilon.minosoft.gui.rendering.gui.atlas.CodeTexturePart
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureArray
@@ -32,7 +32,7 @@ abstract class TextureManager {
lateinit var debugTexture: AbstractTexture
private set
- lateinit var whiteTexture: TextureLikeTexture
+ lateinit var whiteTexture: CodeTexturePart
private set
lateinit var skins: SkinManager
private set
@@ -42,7 +42,7 @@ abstract class TextureManager {
throw IllegalStateException("Already initialized!")
}
debugTexture = staticTextures.createTexture(RenderConstants.DEBUG_TEXTURE_RESOURCE_LOCATION)
- whiteTexture = TextureLikeTexture(texture = staticTextures.createTexture(minosoft("white").texture()), uvStart = Vec2(0.0f, 0.0f), uvEnd = Vec2(0.001f, 0.001f), size = Vec2i(16, 16))
+ whiteTexture = CodeTexturePart(texture = staticTextures.createTexture(minosoft("white").texture()), uvStart = Vec2(0.0f, 0.0f), uvEnd = Vec2(0.001f, 0.001f), size = Vec2i(16, 16))
}
fun initializeSkins(connection: PlayConnection) {