diff --git a/src/benchmark/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt b/src/benchmark/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt index 049b09036..cd1627872 100644 --- a/src/benchmark/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt +++ b/src/benchmark/kotlin/de/bixilon/minosoft/data/world/chunk/LightTestingUtil.kt @@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2i import de.bixilon.kutil.concurrent.lock.thread.ThreadLock import de.bixilon.kutil.observer.DataObserver import de.bixilon.kutil.reflection.ReflectionUtil.forceSet +import de.bixilon.kutil.reflection.ReflectionUtil.jvmField import de.bixilon.minosoft.data.registries.blocks.light.LightProperties import de.bixilon.minosoft.data.registries.blocks.light.OpaqueProperty import de.bixilon.minosoft.data.registries.blocks.settings.BlockSettings diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesherTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesherTest.kt index 089eede5b..fa983fb1a 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesherTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesherTest.kt @@ -444,8 +444,9 @@ class SolidSectionMesherTest { return true } - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = Broken() + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = Broken() override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) = Broken() + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = Broken() } } @@ -457,8 +458,9 @@ class SolidSectionMesherTest { private open class TestModel(val queue: TestQueue, val properties: SideProperties?) : BlockRender { - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = Broken() + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = Broken() override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) = Broken() + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = Broken() override fun getProperties(direction: Directions): SideProperties? { return this.properties } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt index d57091800..d464876ea 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt @@ -32,6 +32,7 @@ class DummyComponentConsumer : GUIVertexConsumer { override val order: RenderOrder get() = RenderOrder(IntArray(0)) override fun addVertex(x: Float, y: Float, texture: ShaderTexture?, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) = Broken() + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) = Broken() override fun addCache(cache: GUIMeshCache) = Broken() override fun ensureSize(size: Int) = Unit 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 index 693452d89..6da7875a5 100644 --- 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 @@ -14,6 +14,7 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kutil.exception.Broken import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture @@ -36,6 +37,8 @@ open class DummyGUIVertexConsumer : GUIVertexConsumer { TODO("Not yet implemented") } + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) = Broken() + override fun addChar(start: Vec2, end: Vec2, texture: Texture?, uvStart: Vec2, uvEnd: Vec2, italic: Boolean, tint: RGBColor, options: GUIVertexOptions?) { addChar(start, end, this.char++) } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumerTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumerTest.kt new file mode 100644 index 000000000..19b3d5602 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumerTest.kt @@ -0,0 +1,74 @@ +/* + * 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.models.block.state.render + +import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.kutil.cast.CastUtil.unsafeCast +import de.bixilon.kutil.exception.Broken +import de.bixilon.minosoft.data.direction.Directions +import de.bixilon.minosoft.data.text.formatting.color.RGBColor +import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.models.util.CuboidUtil +import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture +import de.bixilon.minosoft.gui.rendering.util.mesh.MeshOrder +import de.bixilon.minosoft.test.ITUtil.allocate +import org.testng.annotations.Test + +@Test(groups = ["models"]) +class BlockGUIConsumerTest { + + private fun create(): BlockGUIConsumer { + val gui = GUIRenderer::class.java.allocate() + val consumer = GUIConsumer() + + return BlockGUIConsumer(gui, Vec2(11, 12), consumer, null, Vec2(45)) + } + + private fun BlockGUIConsumer.assertVertices(vararg expected: Vec2) { + val consumer = this.consumer.unsafeCast() + + if (consumer.vertices.size != expected.size) throw AssertionError("Size mismatch") + + for (index in expected.indices) { + val delta = expected[index] - consumer.vertices[index] + if (delta.length2() < 0.01f) continue + throw AssertionError("Vertex at index $index mismatched: Expected ${expected[index]}, but got ${consumer.vertices[index]}") + } + } + + + fun `south quad with offset and specific size`() { + val consumer = create() + val position = CuboidUtil.positions(Directions.SOUTH, Vec3(0, 0, 0), Vec3(1, 1, 1)) + val uv = floatArrayOf(0f, 0f, 0f, 1f, 1f, 1f, 1f, 0f) + consumer.addQuad(position, uv, 0f, 0f) + + consumer.assertVertices(Vec2()) // TODO + } + + private class GUIConsumer : GUIVertexConsumer { + override val order = MeshOrder.QUAD + val vertices: MutableList = mutableListOf() + + override fun addVertex(x: Float, y: Float, texture: ShaderTexture?, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) = Broken() + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) = Broken() + + override fun addCache(cache: GUIMeshCache) = Broken() + override fun ensureSize(size: Int) = Unit + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/sign/SignBlockEntityRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/sign/SignBlockEntityRenderer.kt index 610507ef4..b186a00f1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/sign/SignBlockEntityRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/sign/SignBlockEntityRenderer.kt @@ -72,6 +72,10 @@ class SignBlockEntityRenderer( state.model?.render(mesh, state, tints) // render wood part } + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) { + // TODO + } + private fun renderText(state: BlockState, sign: SignBlockEntity, offset: FloatArray, mesh: ChunkMesh, light: Int) { when (state.block) { is StandingSignBlock -> renderStandingText(state.getRotation(), sign, offset, mesh, light) @@ -123,7 +127,7 @@ class SignBlockEntityRenderer( this += 0.5f } - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = Unit + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = Unit companion object { private val TEXT_PROPERTIES = TextRenderProperties(scale = 1.35f, allowNewLine = false, shadow = false, fallbackColor = ChatColors.BLACK) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextMesh.kt index 0afb58cbc..117789806 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entities/feature/text/BillboardTextMesh.kt @@ -39,6 +39,7 @@ class BillboardTextMesh(context: RenderContext) : Mesh(context, BillboardTextMes data.add(tint.rgba.buffer()) } + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) = Broken() override fun addCache(cache: GUIMeshCache) = Broken("This is not a text only consumer!") data class BillboardTextMeshStruct( 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 b91b41d69..e85bbf6d3 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 @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.font import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kutil.exception.Broken import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh import de.bixilon.minosoft.gui.rendering.font.renderer.component.ChatComponentRenderer @@ -36,6 +37,7 @@ class WorldGUIConsumer(val mesh: ChunkMesh, val transform: Mat4, val light: Int) mesh.addVertex(transformed, this.uv, texture ?: whiteTexture.texture, tint.rgb, light) } + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) = Broken() override fun addCache(cache: GUIMeshCache) { throw IllegalStateException("This is not hud!") } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt index 53f944404..268abeb75 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/elements/items/RawItemElement.kt @@ -79,7 +79,8 @@ class RawItemElement( val item = stack.item.item val model = item.model if (model != null) { - model.render(guiRenderer, offset, consumer, options, textureSize, stack) + val tints = context.tints.getItemTint(stack) + model.render(guiRenderer, offset, consumer, options, textureSize, stack, tints) } else { ColorElement(guiRenderer, textureSize, ChatColors.WHITE).render(offset, consumer, 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 ad5edd7d3..7c0c79433 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 @@ -36,6 +36,10 @@ class GUIMesh( addVertex(data, halfSize, x, y, texture ?: whiteTexture.texture, u, v, tint, options) } + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) { + addVertex(data, halfSize, x, y, textureId, u, v, tint, options) + } + override fun addCache(cache: GUIMeshCache) { data.add(cache.data) } @@ -60,14 +64,18 @@ class GUIMesh( } fun addVertex(data: AbstractFloatList, halfSize: Vec2, x: Float, y: Float, texture: ShaderIdentifiable, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) { + addVertex(data, halfSize, x, y, texture.shaderId.buffer(), u, v, tint.rgba, options) + } + + fun addVertex(data: AbstractFloatList, halfSize: Vec2, x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) { val x = x / halfSize.x - 1.0f val y = 1.0f - y / halfSize.y - var color = tint.rgba + var color = tint if (options != null) { - options.tintColor?.let { color = tint.mix(it).rgba } + options.tintColor?.let { color = RGBColor(tint).mix(it).rgba } if (options.alpha != 1.0f) { val alpha = color and 0xFF @@ -81,7 +89,7 @@ class GUIMesh( data.add(y) data.add(u) data.add(v) - data.add(texture.shaderId.buffer()) + data.add(textureId) data.add(color.buffer()) } } 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 5ea1bcf93..04e21c12a 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 @@ -49,6 +49,10 @@ class GUIMeshCache( revision++ } + override fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) { + GUIMesh.addVertex(data, halfSize, x, y, textureId, u, v, tint, options) + } + override fun addCache(cache: GUIMeshCache) { data.add(cache.data) revision++ 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 265d189d6..aeb83ed78 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 @@ -28,6 +28,7 @@ interface GUIVertexConsumer { fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) = addVertex(position.x, position.y, texture, uv.x, uv.y, tint, options) fun addVertex(x: Float, y: Float, texture: ShaderTexture?, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) + fun addVertex(x: Float, y: Float, textureId: Float, u: Float, v: Float, tint: Int, options: GUIVertexOptions?) fun addQuad(start: Vec2, end: Vec2, texture: ShaderTexture?, uvStart: Vec2 = UV_START, uvEnd: Vec2 = UV_END, tint: RGBColor, options: GUIVertexOptions?) { val start = start.array diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/BlockModelPrototype.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/BlockModelPrototype.kt index 37e49a9eb..5881db719 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/BlockModelPrototype.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/BlockModelPrototype.kt @@ -36,7 +36,8 @@ class BlockModelPrototype(val model: DirectBlockModel) : BlockRender { override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) = prototype() override fun getParticleTexture(random: Random?, position: Vec3i) = prototype() override fun getProperties(direction: Directions) = prototype() - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = prototype() + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = prototype() + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = prototype() private fun prototype(): Nothing = throw IllegalStateException("prototype") diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt index d9bca8bef..5150112f8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt @@ -13,7 +13,6 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked -import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.direction.Directions @@ -21,10 +20,6 @@ import de.bixilon.minosoft.data.entities.block.BlockEntity import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.world.positions.BlockPosition import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer -import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer -import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement -import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer -import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.FaceCulling import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.SideProperties import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender @@ -66,7 +61,7 @@ class BakedModel( return rendered } - override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) { + private fun render(mesh: BlockVertexConsumer, tints: IntArray?) { for (faces in faces) { for (face in faces) { face.render(mesh, tints) @@ -74,10 +69,6 @@ class BakedModel( } } - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { - val texture = particle ?: return - ImageElement(gui, texture, size = size).render(offset, consumer, options) - - // TODO: create projection/view matrix and look at the edge of the block. Then map the resulting 3d coordinates to 2d space - } + override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) = render(mesh, tints) + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = render(mesh, tints) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/builder/BuiltModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/builder/BuiltModel.kt index 923cb7000..e59d268eb 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/builder/BuiltModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/builder/BuiltModel.kt @@ -48,11 +48,11 @@ class BuiltModel( return rendered } - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { - model.render(gui, offset, consumer, options, size, stack) + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) { + model.render(gui, offset, consumer, options, size, stack, tints) for (dynamic in this.dynamic) { - dynamic.render(gui, offset, consumer, options, size, stack) + dynamic.render(gui, offset, consumer, options, size, stack, tints) } } @@ -63,6 +63,13 @@ class BuiltModel( } } + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) { + model.render(mesh, stack, tints) + for (dynamic in this.dynamic) { + dynamic.render(mesh, stack, tints) + } + } + override fun getProperties(direction: Directions): SideProperties? { return model.getProperties(direction) // TODO: dynamic? } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumer.kt new file mode 100644 index 000000000..99189d27a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockGUIConsumer.kt @@ -0,0 +1,74 @@ +/* + * 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.models.block.state.render + +import de.bixilon.kotlinglm.GLM +import de.bixilon.kotlinglm.func.rad +import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.kotlinglm.vec4.Vec4 +import de.bixilon.kutil.exception.Broken +import de.bixilon.minosoft.gui.rendering.camera.CameraDefinition +import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.models.block.element.FaceVertexData +import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture + +class BlockGUIConsumer( + val gui: GUIRenderer, + val offset: Vec2, + val consumer: GUIVertexConsumer, + val options: GUIVertexOptions?, + val size: Vec2, +) : BlockVertexConsumer { + override val order = consumer.order + + + override fun addVertex(position: FloatArray, uv: Vec2, texture: ShaderTexture, tintColor: Int, light: Int) = Broken("Not chunk rendering") + override fun addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, textureId: Float, lightTint: Float) = Broken("Not chunk rendering") + override fun addQuad(offset: FloatArray, positions: FaceVertexData, uvData: FaceVertexData, textureId: Float, lightTint: Float) = Broken("Not chunk rendering") + + override fun addQuad(positions: FaceVertexData, uvData: FaceVertexData, textureId: Float, lightTint: Float) { + val position = Vec3(0, 0, -1) // one block offset in north direction + val front = Vec3(0, 0, 1) // and directly looking onto the south side + // TODO: look from front (whatever that means) to the block in 45° angle from above + val view = GLM.lookAt(position, position + front, CameraDefinition.CAMERA_UP_VEC3) + val projection = GLM.perspective(45.0f.rad, size.x / size.y, CameraDefinition.NEAR_PLANE, CameraDefinition.FAR_PLANE) + + val viewProjection = view * projection + + val tint = (lightTint.toBits() shl 8) or 0xFF + + order.iterate { p, uv -> + val vertexOffset = p * Vec3.length + val uvOffset = uv * Vec2.length + + val xyz = Vec4(positions[vertexOffset], positions[vertexOffset + 1], positions[vertexOffset + 2], 1.0f) + + val a = viewProjection * xyz + + var x = (a.x * 0.5f) + 0.5f + x = (x * size.x) + offset.x + var y = (a.y * 0.5f) + 0.5f + y = (y * size.y) + offset.y + + consumer.addVertex(x, y, textureId, uvData[uvOffset], uvData[uvOffset + 1], tint, options) + } + + // block renders from (in normal cases) from 0 to 1 + // matrix should map those pixels into screen 2d space (offset until offset+size) + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt index c9b2120ce..f7d14bab9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt @@ -13,12 +13,17 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.render +import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.entities.block.BlockEntity import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.world.positions.BlockPosition import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer +import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.SideProperties import de.bixilon.minosoft.gui.rendering.models.item.ItemRender import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture @@ -30,5 +35,12 @@ interface BlockRender : ItemRender { fun render(position: BlockPosition, offset: FloatArray, mesh: BlockVertexConsumer, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, entity: BlockEntity?): Boolean fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) + + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) { + val consumer = BlockGUIConsumer(gui, offset, consumer, options, size) + + render(consumer, stack, tints) + } + fun getProperties(direction: Directions): SideProperties? = null } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/PickedBlockRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/PickedBlockRender.kt index 7bf296e7b..8383df8e9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/PickedBlockRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/PickedBlockRender.kt @@ -34,8 +34,8 @@ interface PickedBlockRender : BlockRender { fun pick(state: BlockState, neighbours: Array): BlockRender? - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { - default?.render(gui, offset, consumer, options, size, stack) + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) { + default?.render(gui, offset, consumer, options, size, stack, tints) } override fun render(position: BlockPosition, offset: FloatArray, mesh: BlockVertexConsumer, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, entity: BlockEntity?): Boolean { @@ -46,6 +46,10 @@ interface PickedBlockRender : BlockRender { default?.render(mesh, state, tints) } + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) { + default?.render(mesh, stack, tints) + } + override fun getProperties(direction: Directions): SideProperties? { return default?.getProperties(direction) // both models should have the same properties } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/WeightedBlockRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/WeightedBlockRender.kt index d3ff8584a..a38e85d59 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/WeightedBlockRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/WeightedBlockRender.kt @@ -66,14 +66,18 @@ class WeightedBlockRender( return getModel(random, position).render(position, offset, mesh, random, state, neighbours, light, tints, entity) } - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { - models.first().model.render(gui, offset, consumer, options, size, stack) + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) { + models.first().model.render(gui, offset, consumer, options, size, stack, tints) } override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) { models.first().model.render(mesh, state, tints) } + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) { + models.first().model.render(mesh, stack, tints) + } + data class WeightedEntry( val weight: Int, diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/property/PropertyOnlyBlockRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/property/PropertyOnlyBlockRender.kt index 657e8d001..24c7c6973 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/property/PropertyOnlyBlockRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/property/PropertyOnlyBlockRender.kt @@ -28,6 +28,7 @@ import java.util.* interface PropertyOnlyBlockRender : BlockRender { override fun render(position: BlockPosition, offset: FloatArray, mesh: BlockVertexConsumer, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, entity: BlockEntity?) = false - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = Unit + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = Unit override fun render(mesh: BlockVertexConsumer, state: BlockState, tints: IntArray?) = Unit + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = Unit } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/FlatItemRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/FlatItemRender.kt index e6e40fa5f..2d90a3a73 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/FlatItemRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/FlatItemRender.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.models.item import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.data.container.stack.ItemStack +import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer @@ -23,7 +24,11 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture class FlatItemRender(val texture: Texture) : ItemRender { - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) { ImageElement(gui, texture, size = size).render(offset, consumer, options) } + + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) { + // TODO: render items in world space + } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemModelPrototype.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemModelPrototype.kt index 6c823c4df..2c1892dbe 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemModelPrototype.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemModelPrototype.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.models.item import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.data.container.stack.ItemStack +import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions @@ -23,7 +24,8 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture class ItemModelPrototype( private var texture: Texture, ) : ItemRender { - override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) = prototype() + override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = prototype() + override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = prototype() private fun prototype(): Nothing = throw IllegalStateException("prototype") diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemRender.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemRender.kt index 300decb38..ee28ba683 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemRender.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/item/ItemRender.kt @@ -15,11 +15,13 @@ package de.bixilon.minosoft.gui.rendering.models.item import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.data.container.stack.ItemStack +import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions interface ItemRender { - fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) + fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) + fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) }