diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/register/EntityRenderFeatures.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/register/EntityRenderFeatures.kt index d29e2fbaf..245e8b0a6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/register/EntityRenderFeatures.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/register/EntityRenderFeatures.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.entities.feature.register import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer import de.bixilon.minosoft.gui.rendering.entities.feature.hitbox.HitboxManager +import de.bixilon.minosoft.gui.rendering.entities.feature.text.BillboardTextRegister import de.bixilon.minosoft.gui.rendering.entities.renderer.living.player.PlayerRegister import de.bixilon.minosoft.util.Initializable @@ -23,6 +24,7 @@ class EntityRenderFeatures(renderer: EntitiesRenderer) : Initializable { val hitbox = HitboxManager(renderer).register() val player = PlayerRegister(renderer).register() + val text = BillboardTextRegister(renderer).register() override fun init() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextFeature.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextFeature.kt index edb47451a..add8b6db2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextFeature.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextFeature.kt @@ -13,12 +13,16 @@ package de.bixilon.minosoft.gui.rendering.entities.feature.text +import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.data.text.ChatComponent import de.bixilon.minosoft.gui.rendering.entities.feature.EntityRenderFeature import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer import de.bixilon.minosoft.gui.rendering.font.renderer.component.ChatComponentRenderer +import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderInfo import de.bixilon.minosoft.gui.rendering.font.renderer.element.TextRenderProperties +import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh open class BillboardTextFeature( @@ -26,6 +30,7 @@ open class BillboardTextFeature( text: ChatComponent?, ) : EntityRenderFeature(renderer) { private var mesh: BillboardTextMesh? = null + private var info: TextRenderInfo? = null var text: ChatComponent? = text set(value) { if (field == value) return @@ -35,20 +40,32 @@ open class BillboardTextFeature( override fun update(millis: Long, delta: Float) { if (!enabled) return unload() + if (this.mesh != null) return // matrix, ...? val text = this.text ?: return unload() if (text.length == 0) return unload() + createMesh(text) } private fun createMesh(text: ChatComponent) { val mesh = BillboardTextMesh(renderer.renderer.context) - val properties = TextRenderProperties() - ChatComponentRenderer.render3d(renderer.renderer.context, properties, Vec2(Int.MAX_VALUE), mesh, text) + val info = ChatComponentRenderer.render3d(renderer.renderer.context, PROPERTIES, MAX_SIZE, mesh, text) + + + this.mesh = mesh + this.info = info } override fun draw() { - // TODO: shader - mesh?.draw() + val mesh = this.mesh ?: return + if (mesh.state != Mesh.MeshStates.LOADED) mesh.load() + renderer.renderer.context.system.reset(depth = DepthFunctions.ALWAYS) + val shader = renderer.renderer.features.text.shader + shader.use() + val matrix = Mat4() + .translateAssign(Vec3(renderer.entity.renderInfo.position + renderer.renderer.context.camera.offset.offset) + Vec3(0, 2, 0)) + shader.matrix = matrix + mesh.draw() } override fun updateVisibility(occluded: Boolean) { @@ -57,7 +74,14 @@ open class BillboardTextFeature( override fun unload() { val mesh = this.mesh ?: return + this.mesh = null + this.info = null if (mesh.state != Mesh.MeshStates.LOADED) return renderer.renderer.queue += { mesh.unload() } } + + private companion object { + val PROPERTIES = TextRenderProperties(allowNewLine = false) + val MAX_SIZE = Vec2(150.0f, PROPERTIES.lineHeight) + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextRegister.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextRegister.kt new file mode 100644 index 000000000..cd6b5d989 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextRegister.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.entities.feature.text + +import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft +import de.bixilon.minosoft.gui.rendering.entities.EntitiesRenderer +import de.bixilon.minosoft.gui.rendering.entities.feature.register.FeatureRegister + +class BillboardTextRegister(renderer: EntitiesRenderer) : FeatureRegister { + val shader = renderer.context.system.createShader(minosoft("entities/features/text"), ::BillboardTextShader) + + override fun postInit() { + shader.load() + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextShader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextShader.kt new file mode 100644 index 000000000..87eabf0a1 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextShader.kt @@ -0,0 +1,37 @@ +/* + * 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.entities.feature.text + +import de.bixilon.kotlinglm.mat4x4.Mat4 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.minosoft.gui.rendering.camera.FogManager +import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer +import de.bixilon.minosoft.gui.rendering.shader.Shader +import de.bixilon.minosoft.gui.rendering.shader.types.FogShader +import de.bixilon.minosoft.gui.rendering.shader.types.LightShader +import de.bixilon.minosoft.gui.rendering.shader.types.TextureShader +import de.bixilon.minosoft.gui.rendering.shader.types.ViewProjectionShader +import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager + +class BillboardTextShader( + override val native: NativeShader, +) : Shader(), TextureShader, LightShader, ViewProjectionShader, FogShader { + override var textures: TextureManager by textureManager() + override val lightmap: LightmapBuffer by lightmap() + override var viewProjectionMatrix: Mat4 by viewProjectionMatrix() + override var cameraPosition: Vec3 by cameraPosition() + override var fog: FogManager by fog() + var matrix: Mat4 by uniform("uMatrix", Mat4()) +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh b/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh index c5409681a..520481fdf 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh @@ -16,7 +16,7 @@ layout (location = 0) in vec3 vinPosition; layout (location = 1) in vec2 vinUV; layout (location = 2) in float vinIndexLayerAnimation;// texture index (0xF0000000), texture layer (0x0FFFF000), animation index (0x00000FFF) -layout (location = 3) in float vinTintColorAndLight;// Light (0xFF000000); 3 bytes color (0x00FFFFFF) +layout (location = 3) in float vinLightTint;// Light (0xFF000000); 3 bytes color (0x00FFFFFF) #include "minosoft:animation/header_vertex" @@ -30,8 +30,8 @@ uniform mat4 uViewProjectionMatrix; void main() { gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f); - uint tintColorAndLight = floatBitsToUint(vinTintColorAndLight); - finTintColor = getRGBColor(tintColorAndLight & 0xFFFFFFu) * getLight(tintColorAndLight >> 24u); + uint lightTint = floatBitsToUint(vinLightTint); + finTintColor = getRGBColor(lightTint & 0xFFFFFFu) * getLight(lightTint >> 24u); finFragmentPosition = vinPosition; run_animation(); diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk/text/text.vsh b/src/main/resources/assets/minosoft/rendering/shader/chunk/text/text.vsh index ad62b81b8..edc8575cf 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/chunk/text/text.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/chunk/text/text.vsh @@ -16,7 +16,7 @@ layout (location = 0) in vec3 vinPosition; layout (location = 1) in vec2 vinUV; layout (location = 2) in float vinIndexLayerAnimation;// texture index (0xF0000000), texture layer (0x0FFFF000) -layout (location = 3) in float vinTintColorAndLight;// Light (0xFF000000); 3 bytes color (0x00FFFFFF) +layout (location = 3) in float vinLightTint;// Light (0xFF000000); 3 bytes color (0x00FFFFFF) uniform mat4 uViewProjectionMatrix; @@ -34,8 +34,8 @@ out vec4 finTintColor; void main() { gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f); - uint tintColorAndLight = floatBitsToUint(vinTintColorAndLight); - finTintColor = getRGBColor(tintColorAndLight & 0xFFFFFFu) * getLight(tintColorAndLight >> 24u); + uint lightTint = floatBitsToUint(vinLightTint); + finTintColor = getRGBColor(lightTint & 0xFFFFFFu) * getLight(lightTint >> 24u); finFragmentPosition = vinPosition; uint indexLayerAnimation = floatBitsToUint(vinIndexLayerAnimation); diff --git a/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.fsh b/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.fsh new file mode 100644 index 000000000..b620c244a --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.fsh @@ -0,0 +1,37 @@ +/* + * Minosoft + * Copyright (C) 2020 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. + */ + +#version 330 core + +out vec4 foutColor; + + +flat in uint finTextureIndex; +in vec3 finTextureCoordinates; + +in vec4 finTintColor; + + +#include "minosoft:texture" +#include "minosoft:alpha" +#include "minosoft:fog" + +void main() { + vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates, 0.0f); + discard_if_0(texelColor.a); + + foutColor = texelColor * finTintColor; + set_alpha_transparent(); + + set_fog(); +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.vsh b/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.vsh new file mode 100644 index 000000000..87e34dd37 --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/entities/features/text/text.vsh @@ -0,0 +1,45 @@ +/* + * Minosoft + * Copyright (C) 2020 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. + */ + +#version 330 core + +layout (location = 0) in vec3 vinPosition; +layout (location = 1) in vec2 vinUV; +layout (location = 2) in float vinIndexLayerAnimation;// texture index (0xF0000000), texture layer (0x0FFFF000) +layout (location = 3) in float vinLightTint;// Light (0xFF000000); 3 bytes color (0x00FFFFFF) + +uniform mat4 uViewProjectionMatrix; +uniform mat4 uMatrix; + + +flat out uint finTextureIndex; +out vec3 finTextureCoordinates; +out vec3 finFragmentPosition; + +out vec4 finTintColor; + + + +#include "minosoft:color" +#include "minosoft:light" + +void main() { + gl_Position = uViewProjectionMatrix * uMatrix * vec4(vinPosition, 1.0f); + uint lightTint = floatBitsToUint(vinLightTint); + finTintColor = getRGBColor(lightTint & 0xFFFFFFu);// * getLight(lightTint >> 24u); // TODO + finFragmentPosition = vinPosition; + + uint indexLayerAnimation = floatBitsToUint(vinIndexLayerAnimation); + finTextureIndex = indexLayerAnimation >> 28u; + finTextureCoordinates = vec3(vinUV, ((indexLayerAnimation >> 12) & 0xFFFFu)); +}