wip 3d text rendering

This commit is contained in:
Bixilon 2022-04-20 18:25:50 +02:00
parent 4db50e521e
commit 940ca35471
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 97 additions and 6 deletions

View File

@ -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> {

View File

@ -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

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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")
}
}

View File

@ -20,7 +20,7 @@ interface OpaqueDrawable : Renderer {
get() = false
fun setupOpaque() {
renderSystem.reset()
renderSystem.reset(faceCulling = false)
}
fun drawOpaque()

View File

@ -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

View File

@ -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