From 2280c5b35fcf1995ce8b092704bb7186b7b56bca Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Fri, 20 Oct 2023 12:01:46 +0200 Subject: [PATCH] improve skeletal drawing, replace SkeletalVertexConsumer with SkeletalConsumer --- .../storage/chest/ChestAnimationTest.kt | 2 +- .../skeletal/DummySkeletalConsumer.kt | 12 +++------ .../gui/rendering/skeletal/SkeletalManager.kt | 19 +++++--------- .../skeletal/baked/BakedSkeletalModel.kt | 2 +- .../skeletal/baked/SkeletalBakeContext.kt | 4 +-- .../skeletal/instance/SkeletalInstance.kt | 21 ++++++++++------ .../SkeletalConsumer.kt} | 9 +++---- .../skeletal/{ => mesh}/SkeletalMesh.kt | 25 +++++++++++-------- .../rendering/skeletal/model/SkeletalModel.kt | 6 ++--- .../model/elements/SkeletalElement.kt | 4 +-- .../skeletal/model/elements/SkeletalFace.kt | 11 +------- 11 files changed, 52 insertions(+), 63 deletions(-) rename src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/{SkeletalVertexConsumer.kt => mesh/SkeletalConsumer.kt} (70%) rename src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/{ => mesh}/SkeletalMesh.kt (70%) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/storage/chest/ChestAnimationTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/storage/chest/ChestAnimationTest.kt index 13a459acb..be4c31bd8 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/storage/chest/ChestAnimationTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/chunk/entities/renderer/storage/chest/ChestAnimationTest.kt @@ -16,11 +16,11 @@ package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kutil.primitive.FloatUtil.matches import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalTransform import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.NOT_OVER import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.OVER +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMesh import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY import de.bixilon.minosoft.test.IT import org.testng.Assert.assertEquals diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/skeletal/DummySkeletalConsumer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/skeletal/DummySkeletalConsumer.kt index 590e6dc89..34a56f5b1 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/skeletal/DummySkeletalConsumer.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/skeletal/DummySkeletalConsumer.kt @@ -14,17 +14,13 @@ package de.bixilon.minosoft.gui.rendering.skeletal import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalConsumer import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture -class DummySkeletalConsumer : SkeletalVertexConsumer { - override val order: IntArray - get() = TODO("Not yet implemented") +class DummySkeletalConsumer : SkeletalConsumer { - override fun addVertex(position: FloatArray, transformedUV: Vec2, transform: Float, textureShaderId: Float) { - TODO("Not yet implemented") - } - - override fun addVertex(position: FloatArray, uv: Vec2, transform: Int, texture: ShaderTexture) { + override fun addQuad(positions: Array, uv: Array, transform: Int, texture: ShaderTexture) { TODO("Not yet implemented") } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt index c9f718510..24eeb3b72 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt @@ -22,7 +22,7 @@ import org.lwjgl.system.MemoryUtil.memAllocFloat class SkeletalManager( val context: RenderContext, ) { - private val uniformBuffer = context.system.createFloatUniformBuffer(memAllocFloat(TRANSFORMS * Mat4.length)) + private val uniformBuffer = context.system.createFloatUniformBuffer(memAllocFloat(MAX_TRANSFORMS * Mat4.length)) val shader = context.system.createShader(minosoft("skeletal")) { SkeletalShader(it, uniformBuffer) } fun init() { @@ -30,31 +30,24 @@ class SkeletalManager( } fun postInit() { - shader.native.defines["TRANSFORMS"] = TRANSFORMS + shader.native.defines["TRANSFORMS"] = MAX_TRANSFORMS shader.load() shader.light = 0xFF } - private fun prepareDraw() { - if (context.system.shader == shader.native) { - // probably already prepared - return - } - context.system.reset() - shader.use() + fun upload(instance: SkeletalInstance) { + instance.transform.pack(uniformBuffer.buffer, instance.position) + uniformBuffer.upload(0 until instance.model.transformCount * Mat4.length) } fun draw(instance: SkeletalInstance, light: Int) { - prepareDraw() shader.light = light - instance.transform.pack(uniformBuffer.buffer, instance.position) - uniformBuffer.upload(0 until instance.model.transformCount * Mat4.length) instance.model.mesh.draw() } companion object { - private const val TRANSFORMS = 128 + private const val MAX_TRANSFORMS = 128 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt index 30c096a0d..0fdab0f68 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt @@ -14,8 +14,8 @@ package de.bixilon.minosoft.gui.rendering.skeletal.baked import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation data class BakedSkeletalModel( diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/SkeletalBakeContext.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/SkeletalBakeContext.kt index fe01125ae..464fb5717 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/SkeletalBakeContext.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/SkeletalBakeContext.kt @@ -17,7 +17,7 @@ import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kutil.collections.CollectionUtil.extend import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Companion.BLOCK_SIZE -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalConsumer import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalRotation import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance @@ -31,7 +31,7 @@ data class SkeletalBakeContext( val rotations: List = emptyList(), val textures: Map, - val consumer: SkeletalVertexConsumer, + val consumer: SkeletalConsumer, ) { fun copy(element: SkeletalElement): SkeletalBakeContext { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt index 1ba059b14..a19c67cd2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt @@ -33,18 +33,25 @@ class SkeletalInstance( var light = 0xFF - fun draw() { - animation.draw() - context.skeletal.draw(this, light) - } - fun draw(light: Int) { this.light = light - context.skeletal.draw(this, light) + draw() + } + + fun draw() { + animation.draw() + + context.system.reset() + val shader = context.skeletal.shader + shader.use() + shader.light = light + draw(shader) } fun draw(shader: Shader) { - TODO() + shader.use() + context.skeletal.upload(this) + model.mesh.draw() } fun update(position: Vec3, rotation: Vec3) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalVertexConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalConsumer.kt similarity index 70% rename from src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalVertexConsumer.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalConsumer.kt index 4eb78d741..623228576 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalVertexConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalConsumer.kt @@ -11,14 +11,13 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.skeletal +package de.bixilon.minosoft.gui.rendering.skeletal.mesh import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture -import de.bixilon.minosoft.gui.rendering.util.mesh.AbstractVertexConsumer -interface SkeletalVertexConsumer : AbstractVertexConsumer { +interface SkeletalConsumer { - fun addVertex(position: FloatArray, uv: Vec2, transform: Int, texture: ShaderTexture) - fun addVertex(position: FloatArray, transformedUV: Vec2, transform: Float, textureShaderId: Float) + fun addQuad(positions: Array, uv: Array, transform: Int, texture: ShaderTexture) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt similarity index 70% rename from src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalMesh.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt index 38ddd586a..010c2b749 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt @@ -11,7 +11,7 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.skeletal +package de.bixilon.minosoft.gui.rendering.skeletal.mesh import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3 @@ -21,22 +21,25 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTextur import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct -class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context, SkeletalMeshStruct, initialCacheSize = initialCacheSize), SkeletalVertexConsumer { +class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context, SkeletalMeshStruct, initialCacheSize = initialCacheSize), SkeletalConsumer { - override fun addVertex(position: FloatArray, uv: Vec2, transform: Int, texture: ShaderTexture) { - val transformedUV = texture.transformUV(uv) - data.add(position) - data.add(transformedUV.array) - data.add(transform.buffer(), texture.shaderId.buffer()) - } - - @Deprecated("Pretty rendering specific") - override fun addVertex(position: FloatArray, transformedUV: Vec2, transform: Float, textureShaderId: Float) { + private fun addVertex(position: FloatArray, transformedUV: Vec2, transform: Float, textureShaderId: Float) { data.add(position) data.add(transformedUV.array) data.add(transform, textureShaderId) } + override fun addQuad(positions: Array, uv: Array, transform: Int, texture: ShaderTexture) { + val transform = transform.buffer() + val textureShaderId = texture.shaderId.buffer() + + for (index in 0 until order.size step 2) { + val indexPosition = positions[order[index]].array + val transformedUV = texture.transformUV(uv[order[index + 1]]) + addVertex(indexPosition, transformedUV, transform, textureShaderId) + } + } + data class SkeletalMeshStruct( val position: Vec3, diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt index 8f0e8aca4..7de75d033 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt @@ -16,10 +16,10 @@ package de.bixilon.minosoft.gui.rendering.skeletal.model import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalTransform +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalConsumer +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTexture @@ -76,7 +76,7 @@ data class SkeletalModel( return Pair(baseTransform, transformId.get()) } - private fun buildElements(consumer: SkeletalVertexConsumer, textures: Map, transform: BakedSkeletalTransform) { + private fun buildElements(consumer: SkeletalConsumer, textures: Map, transform: BakedSkeletalTransform) { for ((name, element) in elements) { element.bake(consumer, textures, transform) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt index 0ee8263c5..b3028d04b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt @@ -16,9 +16,9 @@ package de.bixilon.minosoft.gui.rendering.skeletal.model.elements import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.registries.identified.ResourceLocation -import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalTransform import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext +import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalConsumer import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY @@ -35,7 +35,7 @@ data class SkeletalElement( val children: Map = emptyMap(), ) { - fun bake(consumer: SkeletalVertexConsumer, textures: Map, transform: BakedSkeletalTransform) { + fun bake(consumer: SkeletalConsumer, textures: Map, transform: BakedSkeletalTransform) { if (!enabled) return val context = SkeletalBakeContext(transform = transform, textures = textures, consumer = consumer) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt index b53dac36d..e55072c5b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt @@ -22,7 +22,6 @@ import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Compa import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext -import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign data class SkeletalFace( @@ -51,14 +50,6 @@ data class SkeletalFace( } } - - val transform = transform.buffer() - val textureShaderId = texture.texture.shaderId.buffer() - - for (index in 0 until context.consumer.order.size step 2) { - val indexPosition = positions[context.consumer.order[index]].array - val transformedUV = texture.texture.transformUV(texturePositions[context.consumer.order[index + 1]]) - context.consumer.addVertex(indexPosition, transformedUV, transform, textureShaderId) - } + context.consumer.addQuad(positions, texturePositions, transform, texture.texture) } }