mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 02:15:34 -04:00
font rendering improvements, rasterized font renderer test
This commit is contained in:
parent
63b8c73150
commit
a870d64d6f
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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"))
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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<Pair<Int, Int>> 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")
|
||||
}
|
||||
}
|
@ -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<Pair<Int, Int>> get() = mesh.order
|
||||
|
||||
override fun addVertex(position: Vec2, texture: ShaderIdentifiable, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -40,8 +40,10 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
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<TextComponent> {
|
||||
// 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<TextComponent> {
|
||||
|
||||
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()))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class AtlasElement(
|
||||
val end: Vec2i,
|
||||
val slots: Int2ObjectOpenHashMap<AtlasSlot>,
|
||||
val areas: Map<String, AtlasArea>,
|
||||
) : TextureLike {
|
||||
) : TexturePart {
|
||||
override val size: Vec2i = end - start
|
||||
override lateinit var uvStart: Vec2
|
||||
override lateinit var uvEnd: Vec2
|
||||
|
@ -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
|
@ -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
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -25,10 +25,12 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
|
||||
class GUIMeshCache(
|
||||
var halfSize: Vec2,
|
||||
override val order: Array<Pair<Int, Int>>,
|
||||
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
|
||||
|
@ -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<Pair<Int, Int>>
|
||||
|
||||
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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user