From e9bc701c581173cce89531ad67a6fb2dbb90874c Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Wed, 11 Oct 2023 20:43:48 +0200 Subject: [PATCH] baked face: pre transform uv coordinates --- .../gui/rendering/models/baked/BakedFaceTest.kt | 4 ++-- .../renderer/sign/SignBlockEntityRenderer.kt | 2 +- .../gui/rendering/chunk/mesh/SingleChunkMesh.kt | 11 ++++++----- .../rendering/chunk/mesher/SolidSectionMesher.kt | 5 ++--- .../rendering/models/block/BlockModelPrototype.kt | 2 +- .../block/state/apply/SingleBlockStateApply.kt | 8 ++++++++ .../models/block/state/baked/BakedFace.kt | 15 ++++++++------- .../models/block/state/baked/BakedModel.kt | 4 ++-- .../models/block/state/builder/BuiltModel.kt | 6 +++--- .../models/block/state/render/BlockRender.kt | 2 +- .../block/state/render/PickedBlockRender.kt | 4 ++-- .../block/state/render/WeightedBlockRender.kt | 4 ++-- .../floats/FragmentedArrayFloatList.kt | 15 +++++++++++++++ 13 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedFaceTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedFaceTest.kt index aef9e2603..6863c376b 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedFaceTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedFaceTest.kt @@ -61,7 +61,7 @@ class BakedFaceTest { val mesh = mesh() - face.render(floatArrayOf(0.0f, 0.0f, 0.0f), mesh, byteArrayOf(0, 0, 0, 0, 0, 0, 0), null, FloatArray(2)) + face.render(floatArrayOf(0.0f, 0.0f, 0.0f), mesh, byteArrayOf(0, 0, 0, 0, 0, 0, 0), null) val texture = 0.buffer() val lightTint = 0xFFFFFF.buffer() @@ -83,7 +83,7 @@ class BakedFaceTest { val mesh = mesh() - face.render(floatArrayOf(0.0f, 0.0f, 0.0f), mesh, byteArrayOf(0, 0, 0, 0, 0, 0, 0), null, FloatArray(2)) + face.render(floatArrayOf(0.0f, 0.0f, 0.0f), mesh, byteArrayOf(0, 0, 0, 0, 0, 0, 0), null) val texture = 0.buffer() val lightTint = 0xFFFFFF.buffer() 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 19ab1c97a..016530105 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 @@ -58,7 +58,7 @@ class SignBlockEntityRenderer( return rotation * 22.5f } - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean { + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { val block = this.blockState.block if (block is StandingSignBlock) { renderStandingText(offset, mesh, light[SELF_LIGHT_INDEX].toInt()) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt index f5c15ca2d..710d487b3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt @@ -38,12 +38,13 @@ class SingleChunkMesh(context: RenderContext, initialCacheSize: Int, onDemand: B ) } - fun addVertex(x: Float, y: Float, z: Float, uv: FloatArray, texture: Texture, shaderTextureId: Float, lightTint: Float) { + fun addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, shaderTextureId: Float, lightTint: Float) { data.ensureSize(WorldMeshStruct.FLOATS_PER_VERTEX) - val transformedUV = texture.renderData.transformUV(uv) - data.add(x, y, z) - data.add(transformedUV) - data.add(shaderTextureId, lightTint) + data.add( + x, y, z, + u, v, + shaderTextureId, lightTint, + ) } override fun compareTo(other: SingleChunkMesh): Int { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt index 7633499b2..b05b39a55 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/SolidSectionMesher.kt @@ -65,7 +65,6 @@ class SolidSectionMesher( val entities: MutableList> = ArrayList() val position = BlockPosition() - val temp = FloatArray(2) val neighbourBlocks: Array = arrayOfNulls(Directions.SIZE) val light = ByteArray(Directions.SIZE + 1) // last index (6) for the current block @@ -148,10 +147,10 @@ class SolidSectionMesher( val tints = tints.getAverageBlockTint(chunk, neighbourChunks, state, x, y, z) - var rendered = model.render(position, floatOffset, mesh, random, state, neighbourBlocks, light, tints, temp) + var rendered = model.render(position, floatOffset, mesh, random, state, neighbourBlocks, light, tints) if (entity is BlockRender) { - rendered = entity.render(position, floatOffset, mesh, random, state, neighbourBlocks, light, tints, temp) || rendered + rendered = entity.render(position, floatOffset, mesh, random, state, neighbourBlocks, light, tints) || rendered } if (offset != null) { 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 80ba6c4cf..6a0804180 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 @@ -31,7 +31,7 @@ import de.bixilon.minosoft.gui.rendering.models.loader.legacy.ModelChooser import java.util.* class BlockModelPrototype(val model: DirectBlockModel) : BlockRender { - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray) = prototype() + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, 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() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt index f22c30cc3..a36796203 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt @@ -168,6 +168,14 @@ data class SingleBlockStateApply( uv = uv.pushRight(2, getTextureRotation(direction, rotatedX)) } + val vec = Vec2(0, uv) + for (ofs in 0 until 4) { + vec.ofs = ofs * 2 + val transformed = texture.transformUV(vec) + uv[ofs * 2 + 0] = transformed.x + uv[ofs * 2 + 1] = transformed.y + } + val faceProperties = if (rotation == null && this@SingleBlockStateApply.rotation == null) positions.properties(rotatedXY, texture) else null val bakedFace = BakedFace(positions, uv, this.shade, face.tintIndex, texture, rotatedXY, faceProperties) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt index 06db5b540..112977c8b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt @@ -21,6 +21,7 @@ import de.bixilon.minosoft.gui.rendering.models.block.element.FaceVertexData import de.bixilon.minosoft.gui.rendering.models.block.state.baked.Shades.Companion.shade import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.side.FaceProperties import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureStates import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.tint.TintUtil @@ -36,6 +37,10 @@ class BakedFace( ) { private val lightIndex = cull?.ordinal ?: SELF_LIGHT_INDEX + init { + check(texture.state == TextureStates.LOADED) + } + constructor(positions: FaceVertexData, uv: FaceVertexData, shade: Boolean, tintIndex: Int, texture: Texture, direction: Directions, properties: FaceProperties?) : this(positions, uv, if (shade) direction.shade else Shades.NONE, tintIndex, if (properties == null) null else direction, texture, properties) @@ -44,7 +49,7 @@ class BakedFace( return TintUtil.calculateTint(tint, shade) } - fun render(offset: FloatArray, mesh: ChunkMesh, light: ByteArray, tints: IntArray?, temp: FloatArray) { + fun render(offset: FloatArray, mesh: ChunkMesh, light: ByteArray, tints: IntArray?) { val tint = color(tints?.getOrNull(tintIndex) ?: 0) val lightTint = ((light[lightIndex].toInt() shl 24) or tint).buffer() val textureId = this.texture.shaderId.buffer() @@ -52,20 +57,16 @@ class BakedFace( val mesh = mesh.mesh(texture) - val uv = temp - var index = 0 val size = mesh.order.size while (index < size) { val vertexOffset = mesh.order[index] * 3 val uvOffset = mesh.order[index + 1] * 2 - uv[0] = this.uv[uvOffset] - uv[1] = this.uv[uvOffset + 1] mesh.addVertex( x = offset[0] + positions[vertexOffset], y = offset[1] + positions[vertexOffset + 1], z = offset[2] + positions[vertexOffset + 2], - uv = uv, - texture = this.texture, + u = this.uv[uvOffset], + v = this.uv[uvOffset + 1], shaderTextureId = textureId, lightTint = lightTint, ) 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 98731777d..71ade7b33 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 @@ -45,7 +45,7 @@ class BakedModel( override fun getParticleTexture(random: Random?, position: Vec3i) = particle - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean { + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { var rendered = false for ((directionIndex, faces) in faces.withIndex()) { @@ -56,7 +56,7 @@ class BakedModel( if (FaceCulling.canCull(state, face.properties, direction, neighbour)) { continue } - face.render(offset, mesh, light, tints, temp) + face.render(offset, mesh, light, tints) rendered = true } 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 6067f371f..67c10d130 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 @@ -35,11 +35,11 @@ class BuiltModel( val dynamic: Array, ) : BlockRender { - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean { - var rendered = model.render(position, offset, mesh, random, state, neighbours, light, tints, temp) + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { + var rendered = model.render(position, offset, mesh, random, state, neighbours, light, tints) for (dynamic in this.dynamic) { - if (dynamic.render(position, offset, mesh, random, state, neighbours, light, tints, temp)) { + if (dynamic.render(position, offset, mesh, random, state, neighbours, light, tints)) { rendered = true } } 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 40093032b..46a2da40b 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 @@ -26,7 +26,7 @@ import java.util.* interface BlockRender : ItemRender { fun getParticleTexture(random: Random?, position: Vec3i): Texture? = null - fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean + fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean 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 1429c7a59..408874bd4 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 @@ -37,8 +37,8 @@ interface PickedBlockRender : BlockRender { default?.render(gui, offset, consumer, options, size, stack) } - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean { - return pick(neighbours)?.render(position, offset, mesh, random, state, neighbours, light, tints, temp) ?: false + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { + return pick(neighbours)?.render(position, offset, mesh, random, state, neighbours, light, tints) ?: false } override fun getProperties(direction: Directions): SideProperties? { 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 b675e1363..0b5af2e9e 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 @@ -61,8 +61,8 @@ class WeightedBlockRender( return getModel(random, position).getParticleTexture(random, position) } - override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?, temp: FloatArray): Boolean { - return getModel(random, position).render(position, offset, mesh, random, state, neighbours, light, tints, temp) + override fun render(position: BlockPosition, offset: FloatArray, mesh: ChunkMesh, random: Random?, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { + return getModel(random, position).render(position, offset, mesh, random, state, neighbours, light, tints) } override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack) { diff --git a/src/main/java/de/bixilon/minosoft/util/collections/floats/FragmentedArrayFloatList.kt b/src/main/java/de/bixilon/minosoft/util/collections/floats/FragmentedArrayFloatList.kt index 1f4796703..12426331d 100644 --- a/src/main/java/de/bixilon/minosoft/util/collections/floats/FragmentedArrayFloatList.kt +++ b/src/main/java/de/bixilon/minosoft/util/collections/floats/FragmentedArrayFloatList.kt @@ -99,6 +99,21 @@ class FragmentedArrayFloatList( invalidateOutput() } + fun add(value1: Float, value2: Float, value3: Float, value4: Float, value5: Float, value6: Float, value7: Float) { + var buffer = grow(7) + buffer.put(value1); if (tryPush(buffer)) buffer = grow(6) + buffer.put(value2); if (tryPush(buffer)) buffer = grow(5) + buffer.put(value3); if (tryPush(buffer)) buffer = grow(4) + buffer.put(value4); if (tryPush(buffer)) buffer = grow(3) + buffer.put(value5); if (tryPush(buffer)) buffer = grow(2) + buffer.put(value6); if (tryPush(buffer)) buffer = grow(1) + buffer.put(value7) + + size += 7 + tryPush(buffer) + invalidateOutput() + } + private fun tryPush(fragment: FloatBuffer): Boolean { if (fragment.position() != fragment.limit()) { return false