From 206fcef5e1c60492de31e0762c2d81e4eb1a6d9c Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Fri, 15 Dec 2023 17:27:28 +0100 Subject: [PATCH] cleanup some Mesh code --- .../gui/mesh/DummyGUIVertexConsumer.kt | 16 ++--- .../rendering/models/baked/BakedFaceTest.kt | 5 +- .../chunk/border/WorldBorderRenderer.kt | 2 +- .../gui/rendering/chunk/mesh/ChunkMesh.kt | 2 +- .../gui/rendering/chunk/mesh/ChunkMeshes.kt | 10 ++-- .../gui/rendering/gui/gui/GUIMeshElement.kt | 4 +- .../gui/rendering/gui/mesh/GUIMesh.kt | 4 +- .../gui/rendering/particle/ParticleMesh.kt | 4 +- .../minosoft/gui/rendering/util/mesh/Mesh.kt | 59 ++++++++++--------- 9 files changed, 52 insertions(+), 54 deletions(-) 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 6da7875a50..de2b7fa7ea 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 @@ -25,17 +25,11 @@ open class DummyGUIVertexConsumer : GUIVertexConsumer { override val order: RenderOrder get() = MeshOrder.QUAD var char = 0 - override fun addCache(cache: GUIMeshCache) { - TODO("Not yet implemented") - } + override fun addCache(cache: GUIMeshCache) = Broken() - override fun ensureSize(size: Int) { - TODO("Not yet implemented") - } + override fun ensureSize(size: Int) = Broken() - override fun addVertex(x: Float, y: Float, texture: ShaderTexture?, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) { - TODO("Not yet implemented") - } + 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() @@ -43,7 +37,5 @@ open class DummyGUIVertexConsumer : GUIVertexConsumer { addChar(start, end, this.char++) } - open fun addChar(start: Vec2, end: Vec2, index: Int) { - TODO("Abstract") - } + open fun addChar(start: Vec2, end: Vec2, index: Int): Unit = Broken() } 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 9c60ee3c3e..60f81aec0d 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 @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.models.baked import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList import de.bixilon.kutil.reflection.ReflectionUtil.forceSet +import de.bixilon.kutil.reflection.ReflectionUtil.getFieldOrNull import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMeshes import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace @@ -39,10 +40,10 @@ class BakedFaceTest { private fun singleMesh(): ChunkMesh { val mesh = OBJENESIS.newInstance(ChunkMesh::class.java) - mesh::quadType.forceSet(PrimitiveTypes.QUAD) + mesh::primitive.forceSet(PrimitiveTypes.QUAD) mesh::order.forceSet(MeshOrder.QUAD) - mesh.data = HeapArrayFloatList(1000) + mesh::class.java.getFieldOrNull("_data")!!.forceSet(mesh, HeapArrayFloatList(1000)) mesh::initialCacheSize.forceSet(1000) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderRenderer.kt index a7c2290295..a9338984d6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderRenderer.kt @@ -117,7 +117,7 @@ class WorldBorderRenderer( val mesh = this.borderMesh ?: return update() - if (mesh.state == Mesh.MeshStates.PREPARING) { + if (mesh.state == Mesh.MeshStates.WAITING) { mesh.load() } mesh.draw() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt index 58da9e2451..217c70cfac 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMesh.kt @@ -21,7 +21,7 @@ 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 ChunkMesh(context: RenderContext, initialCacheSize: Int, onDemand: Boolean = false) : Mesh(context, ChunkMeshStruct, initialCacheSize = initialCacheSize, onDemand = onDemand), BlockVertexConsumer, Comparable { +class ChunkMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context, ChunkMeshStruct, initialCacheSize = initialCacheSize), BlockVertexConsumer, Comparable { var distance: Float = 0.0f // Used for sorting override val order = context.system.quadOrder diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMeshes.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMeshes.kt index 71a20a9e91..f45643e563 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMeshes.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/ChunkMeshes.kt @@ -33,8 +33,8 @@ class ChunkMeshes( ) : BlockVertexConsumer { val center: Vec3 = Vec3(Vec3i.of(chunkPosition, sectionHeight, Vec3i(8, 8, 8))) var opaqueMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 100000) - var translucentMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 10000, onDemand = true) - var textMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 5000 else 50000, onDemand = true) + var translucentMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 10000) + var textMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 5000 else 50000) var blockEntities: ArrayList>? = null // used for frustum culling @@ -42,9 +42,9 @@ class ChunkMeshes( val maxPosition = Vec3i(0) fun finish() { - this.opaqueMesh?.finish() - this.translucentMesh?.finish() - this.textMesh?.finish() + this.opaqueMesh?.preload() + this.translucentMesh?.preload() + this.textMesh?.preload() } @Synchronized diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt index 23c8e8095b..bf7ea8dd55 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/gui/GUIMeshElement.kt @@ -91,7 +91,7 @@ open class GUIMeshElement( if (this._mesh != null) throw MemoryLeakException("Mesh to unload is already set!") this._mesh = this.mesh this.mesh = GUIMesh(context, guiRenderer.halfSize, mesh.data) - this.mesh.finish() + this.mesh.preload() } fun prepare() = Unit @@ -112,7 +112,7 @@ open class GUIMeshElement( } this._mesh = null - if (this.mesh.state == Mesh.MeshStates.FINISHED) { + if (this.mesh.state == Mesh.MeshStates.PRELOADED) { mesh.load() } } 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 7c0c794337..d93d0d13a6 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 @@ -27,10 +27,12 @@ class GUIMesh( context: RenderContext, val halfSize: Vec2, data: AbstractFloatList, -) : Mesh(context, GUIMeshStruct, initialCacheSize = 40000, clearOnLoad = false, data = data), GUIVertexConsumer { +) : Mesh(context, GUIMeshStruct, initialCacheSize = 40000, data = data), GUIVertexConsumer { private val whiteTexture = context.textures.whiteTexture override val order = context.system.quadOrder + override fun clear() = Unit + override fun addVertex(x: Float, y: Float, texture: ShaderTexture?, u: Float, v: Float, tint: RGBColor, options: GUIVertexOptions?) { addVertex(data, halfSize, x, y, texture ?: whiteTexture.texture, u, v, tint, options) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt index e4fe83ebfb..a4a44ccbcc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt @@ -25,7 +25,9 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct -class ParticleMesh(context: RenderContext, data: AbstractFloatList) : Mesh(context, ParticleMeshStruct, PrimitiveTypes.POINT, -1, clearOnLoad = false, data = data) { +class ParticleMesh(context: RenderContext, data: AbstractFloatList) : Mesh(context, ParticleMeshStruct, PrimitiveTypes.POINT, -1, data = data) { + + override fun clear() = Unit fun addVertex(position: Vec3d, scale: Float, texture: Texture, tintColor: RGBColor, uvMin: FloatArray? = null, uvMax: FloatArray? = null, light: Int) { val minTransformedUV = if (uvMin == null) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt index afd7a71b56..f6ff5e8333 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/Mesh.kt @@ -28,68 +28,66 @@ import de.bixilon.minosoft.util.collections.floats.FloatListUtil abstract class Mesh( val context: RenderContext, private val struct: MeshStruct, - val quadType: PrimitiveTypes = context.system.quadType, + val primitive: PrimitiveTypes = context.system.quadType, var initialCacheSize: Int = 10000, - val clearOnLoad: Boolean = true, data: AbstractFloatList? = null, - val onDemand: Boolean = false, ) : AbstractVertexConsumer { override val order = context.system.legacyQuadOrder - private var _data: AbstractFloatList? = data ?: if (onDemand) null else FloatListUtil.direct(initialCacheSize) - var data: AbstractFloatList + private var _data = data + val data: AbstractFloatList get() { - if (_data == null && onDemand) { + if (_data == null) { _data = FloatListUtil.direct(initialCacheSize) } return _data.unsafeCast() } - set(value) { - _data = value - } protected lateinit var buffer: FloatVertexBuffer var vertices: Int = -1 protected set - var state = MeshStates.PREPARING + var state = MeshStates.WAITING protected set - fun finish() { - if (state != MeshStates.PREPARING) throw IllegalStateException("Mesh is not preparing: $state") + fun preload() { + if (state != MeshStates.WAITING) throw InvalidMeshState(state) val data = this.data - buffer = context.system.createVertexBuffer(struct, data, quadType) - state = MeshStates.FINISHED + buffer = context.system.createVertexBuffer(struct, data, primitive) + state = MeshStates.PRELOADED } fun load() { - if (state == MeshStates.PREPARING) { - finish() + if (state == MeshStates.WAITING) { + preload() } - if (state != MeshStates.FINISHED) throw IllegalStateException("Mesh is not finished: $state") + if (state != MeshStates.PRELOADED) throw InvalidMeshState(state) buffer.init() - if (clearOnLoad) { - val data = data - if (data is DirectArrayFloatList) { - data.unload() - } - _data = null - } + clear() + vertices = buffer.vertices state = MeshStates.LOADED } + protected open fun clear() { + val data = data + if (data is DirectArrayFloatList) { + data.unload() + } + _data = null + } + fun draw() { - check(state == MeshStates.LOADED) { "Can not draw $state mesh!" } + if (state != MeshStates.LOADED) throw InvalidMeshState(state) buffer.draw() } fun unload() { when (state) { MeshStates.LOADED -> buffer.unload() - MeshStates.PREPARING, MeshStates.FINISHED -> _data?.nullCast()?.unload() - else -> throw IllegalStateException("Mesh is already unloaded") + MeshStates.WAITING, MeshStates.PRELOADED -> _data?.nullCast()?.unload() + MeshStates.UNLOADED -> throw InvalidMeshState(state) } state = MeshStates.UNLOADED } @@ -140,9 +138,12 @@ abstract class Mesh( } enum class MeshStates { - PREPARING, - FINISHED, + WAITING, + PRELOADED, LOADED, UNLOADED, + ; } + + class InvalidMeshState(state: MeshStates) : Exception("Invalid mesh state: $state") }