mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 03:44:54 -04:00
wip 3d text rendering
This commit is contained in:
parent
4db50e521e
commit
940ca35471
@ -42,7 +42,7 @@ class SignBlockEntity(connection: PlayConnection) : MeshedBlockEntity(connection
|
||||
}
|
||||
|
||||
override fun createMeshedRenderer(renderWindow: RenderWindow, blockState: BlockState, blockPosition: Vec3i): SignBlockEntityRenderer {
|
||||
return SignBlockEntityRenderer(this, blockState)
|
||||
return SignBlockEntityRenderer(this, renderWindow, blockState)
|
||||
}
|
||||
|
||||
companion object : BlockEntityFactory<SignBlockEntity> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
* Copyright (C) 2020-2022 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.
|
||||
*
|
||||
@ -33,7 +33,7 @@ object RenderConstants {
|
||||
val TEXT_BACKGROUND_COLOR = RGBColor(0, 0, 0, 80)
|
||||
|
||||
|
||||
const val FRUSTUM_CULLING_ENABLED = true
|
||||
const val FRUSTUM_CULLING_ENABLED = false
|
||||
const val SHOW_FPS_IN_WINDOW_TITLE = true
|
||||
|
||||
const val MAXIMUM_QUEUE_TIME_PER_FRAME = 20L
|
||||
|
@ -13,15 +13,19 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font
|
||||
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kotlinglm.vec2.Vec2t
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.kotlinglm.vec4.Vec4
|
||||
import de.bixilon.kutil.math.simple.FloatMath.ceil
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
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
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
|
||||
class CharData(
|
||||
private val renderWindow: RenderWindow,
|
||||
@ -122,6 +126,30 @@ class CharData(
|
||||
return (width * scale).ceil
|
||||
}
|
||||
|
||||
fun render3d(matrix: Mat4, mesh: WorldMesh, color: RGBColor): Float {
|
||||
val endMatrix = matrix * Mat4().translateAssign(Vec3(width, Font.CHAR_HEIGHT.toFloat(), 0))
|
||||
val startPosition = matrix * Vec4(1, 1, 1, 1)
|
||||
val endPosition = endMatrix * Vec4(1, 1, 1, 1)
|
||||
val positions = arrayOf(
|
||||
Vec3(startPosition.x, startPosition.y, startPosition.z),
|
||||
Vec3(endPosition.x, startPosition.y, endPosition.z),
|
||||
Vec3(endPosition.x, endPosition.y, endPosition.z),
|
||||
Vec3(startPosition.x, endPosition.y, startPosition.z),
|
||||
)
|
||||
val texturePositions = arrayOf(
|
||||
Vec2(uvEnd.x, uvStart.y),
|
||||
uvStart,
|
||||
Vec2(uvStart.x, uvEnd.y),
|
||||
uvEnd,
|
||||
)
|
||||
|
||||
val opaqueMesh = mesh.opaqueMesh ?: return 0.0f
|
||||
for ((vertexIndex, textureIndex) in opaqueMesh.order) {
|
||||
opaqueMesh.addVertex(positions[vertexIndex].array, texturePositions[textureIndex], texture ?: return 0.0f, color.rgb, 0xFF)
|
||||
}
|
||||
return width.toFloat()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
const val ITALIC_OFFSET = 2.5f
|
||||
|
@ -13,12 +13,14 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer
|
||||
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
|
||||
object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
|
||||
|
||||
@ -30,4 +32,10 @@ object BaseComponentRenderer : ChatComponentRenderer<BaseComponent> {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun render3DFlat(matrix: Mat4, mesh: WorldMesh, text: BaseComponent) {
|
||||
for (part in text.parts) {
|
||||
ChatComponentRenderer.render3DFlat(matrix, mesh, text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,20 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer
|
||||
|
||||
import de.bixilon.kotlinglm.GLM
|
||||
import de.bixilon.kotlinglm.func.rad
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.text.BaseComponent
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.data.text.TextComponent
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
|
||||
interface ChatComponentRenderer<T : ChatComponent> {
|
||||
|
||||
@ -29,8 +35,11 @@ interface ChatComponentRenderer<T : ChatComponent> {
|
||||
*/
|
||||
fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, renderWindow: RenderWindow, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: T): Boolean
|
||||
|
||||
fun render3DFlat(matrix: Mat4, mesh: WorldMesh, text: T)
|
||||
|
||||
companion object : ChatComponentRenderer<ChatComponent> {
|
||||
const val TEXT_BLOCK_RESOLUTION = 64
|
||||
var a = 0.0f
|
||||
|
||||
override fun render(initialOffset: Vec2i, offset: Vec2i, size: Vec2i, element: Element, renderWindow: RenderWindow, consumer: GUIVertexConsumer?, options: GUIVertexOptions?, renderInfo: TextRenderInfo, text: ChatComponent): Boolean {
|
||||
return when (text) {
|
||||
@ -39,5 +48,36 @@ interface ChatComponentRenderer<T : ChatComponent> {
|
||||
else -> TODO("Don't know how to render ${text::class.java}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun render3DFlat(matrix: Mat4, mesh: WorldMesh, text: ChatComponent) {
|
||||
when (text) {
|
||||
is BaseComponent -> BaseComponentRenderer.render3DFlat(matrix, mesh, text)
|
||||
is TextComponent -> TextComponentRenderer.render3DFlat(matrix, mesh, text)
|
||||
else -> TODO("Don't know how to render ${text::class.java}")
|
||||
}
|
||||
}
|
||||
|
||||
fun render3dFlat(renderWindow: RenderWindow, position: Vec3, scale: Float, rotation: Vec3, mesh: WorldMesh, text: ChatComponent) {
|
||||
val positionMatrix = Mat4()
|
||||
.translateAssign(position)
|
||||
.rotateAssign(a.rad, Vec3(0, 1, 0)) * Mat4()
|
||||
.translateAssign(-position)
|
||||
|
||||
var orthoMatrix = positionMatrix * GLM.ortho(0.0f, TEXT_BLOCK_RESOLUTION.toFloat(), TEXT_BLOCK_RESOLUTION.toFloat(), 0.0f)
|
||||
a += 3.0f
|
||||
if (a > 360) {
|
||||
a = 0.0f
|
||||
}
|
||||
|
||||
val text = "abcdefghijkl"
|
||||
|
||||
|
||||
for ((index, char) in text.codePoints().toArray().withIndex()) {
|
||||
val data = renderWindow.font[char] ?: continue
|
||||
val width = data.render3d(orthoMatrix, mesh, ChatColors[index % ChatColors.VALUES.size])
|
||||
val translated = Mat4().translateAssign(Vec3(width, 0, 0))
|
||||
orthoMatrix = orthoMatrix * translated
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.font.renderer
|
||||
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.PreChatFormattingCodes
|
||||
@ -23,6 +24,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.Element
|
||||
import de.bixilon.minosoft.gui.rendering.gui.elements.HorizontalAlignments.Companion.getOffset
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
|
||||
object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
|
||||
@ -186,4 +188,8 @@ object TextComponentRenderer : ChatComponentRenderer<TextComponent> {
|
||||
pushLine()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun render3DFlat(matrix: Mat4, mesh: WorldMesh, text: TextComponent) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ interface OpaqueDrawable : Renderer {
|
||||
get() = false
|
||||
|
||||
fun setupOpaque() {
|
||||
renderSystem.reset()
|
||||
renderSystem.reset(faceCulling = false)
|
||||
}
|
||||
|
||||
fun drawOpaque()
|
||||
|
@ -13,28 +13,37 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.world.entities.renderer.sign
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.entities.block.SignBlockEntity
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.entity.sign.StandingSignBlock
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.entity.sign.WallSignBlock
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.ChatComponentRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.MeshedBlockEntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import java.util.*
|
||||
|
||||
class SignBlockEntityRenderer(
|
||||
val sign: SignBlockEntity,
|
||||
val renderWindow: RenderWindow,
|
||||
override val blockState: BlockState,
|
||||
) : MeshedBlockEntityRenderer<SignBlockEntity> {
|
||||
|
||||
override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: ByteArray, ambientLight: FloatArray, tints: IntArray?): Boolean {
|
||||
val block = this.blockState.block
|
||||
if (position.x != 0 || position.y != 1 || position.z != 0) {
|
||||
return false
|
||||
}
|
||||
if (block is StandingSignBlock) {
|
||||
println("Rendering standing sign at $position (${block.resourceLocation})")
|
||||
// println("Rendering standing sign at $position (${block.resourceLocation})")
|
||||
} else if (block is WallSignBlock) {
|
||||
println("Rendering wall sign at $position (${block.resourceLocation})")
|
||||
}
|
||||
|
||||
ChatComponentRenderer.render3dFlat(renderWindow, position.toVec3 + Vec3(0, 1.0f, 0.0f), 1.0f, Vec3(), mesh, sign.lines[0])
|
||||
// ToDo
|
||||
|
||||
return true
|
||||
|
@ -166,7 +166,7 @@ class SolidCullSectionPreparer(
|
||||
random.setSeed(0L)
|
||||
}
|
||||
tints = tintColorCalculator.getAverageTint(chunk, neighbourChunks, blockState, x, y, z)
|
||||
rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, ambientLight, tints)
|
||||
rendered = false // rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, ambientLight, tints)
|
||||
|
||||
if (blockEntityModel is MeshedBlockEntityRenderer<*>) {
|
||||
rendered = blockEntityModel.singleRender(position, mesh, random, blockState, neighbourBlocks, light, ambientLight, tints) || rendered
|
||||
|
Loading…
x
Reference in New Issue
Block a user