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 18fb96106..b85fb6602 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 @@ -15,7 +15,6 @@ package de.bixilon.minosoft.gui.rendering.gui.gui import de.bixilon.kotlinglm.vec2.Vec2d import de.bixilon.kotlinglm.vec2.Vec2i -import de.bixilon.kutil.time.TimeUtil import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.minosoft.config.key.KeyCodes import de.bixilon.minosoft.gui.rendering.RenderWindow @@ -31,6 +30,7 @@ import de.bixilon.minosoft.gui.rendering.input.count.MouseClickCounter import de.bixilon.minosoft.gui.rendering.renderer.drawable.AsyncDrawable import de.bixilon.minosoft.gui.rendering.renderer.drawable.BaseDrawable import de.bixilon.minosoft.gui.rendering.renderer.drawable.Drawable +import de.bixilon.minosoft.gui.rendering.system.opengl.MemoryLeakException import de.bixilon.minosoft.gui.rendering.system.window.KeyChangeTypes import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY @@ -42,6 +42,7 @@ open class GUIMeshElement( override val guiRenderer: GUIRenderer = element.guiRenderer override val renderWindow: RenderWindow = guiRenderer.renderWindow private val clickCounter = MouseClickCounter() + private var _mesh: GUIMesh? = null var mesh: GUIMesh = GUIMesh(renderWindow, guiRenderer.matrix, FloatListUtil.direct(1000)) override val skipDraw: Boolean get() = if (element is BaseDrawable) element.skipDraw else false @@ -88,28 +89,35 @@ open class GUIMeshElement( } protected fun createNewMesh() { - val mesh = this.mesh - if (mesh.state == Mesh.MeshStates.LOADED) { - mesh.unload() - } + if (this._mesh != null) throw MemoryLeakException("Mesh to unload is already set!") + this._mesh = this.mesh this.mesh = GUIMesh(renderWindow, guiRenderer.matrix, mesh.data) + this.mesh.finish() } fun prepare() = Unit fun prepareAsync(offset: Vec2i) { element.render(offset, mesh, null) - } - - open fun postPrepare() { val revision = element.cache.revision if (revision != lastRevision) { createNewMesh() - this.mesh.load() this.lastRevision = revision } } + open fun postPrepare() { + val _mesh = this._mesh ?: return + if (_mesh.state == Mesh.MeshStates.LOADED) { + _mesh.unload() + } + this._mesh = null + + if (this.mesh.state == Mesh.MeshStates.FINISHED) { + mesh.load() + } + } + open fun prepareAsync() { prepareAsync(Vec2i.EMPTY) } 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 923cb9fac..638aeb54d 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 @@ -55,11 +55,21 @@ abstract class Mesh( protected set - fun load() { + fun finish() { + if (state != MeshStates.PREPARING) throw IllegalStateException("Mesh is not preparing: $state") val data = this.data buffer = renderWindow.renderSystem.createVertexBuffer(struct, data, primitiveType) + state = MeshStates.FINISHED + } + + fun load() { + if (state == MeshStates.PREPARING) { + finish() + } + if (state != MeshStates.FINISHED) throw IllegalStateException("Mesh is not finished: $state") buffer.init() if (clearOnLoad) { + val data = data if (data is DirectArrayFloatList) { data.unload() } @@ -126,6 +136,7 @@ abstract class Mesh( enum class MeshStates { PREPARING, + FINISHED, LOADED, UNLOADED, } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt index 8ef51c402..916b529f8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt @@ -484,6 +484,7 @@ class WorldRenderer( if (mesh.clearEmpty() == 0) { return queueItemUnload(item) } + mesh.finish() item.mesh = mesh meshesToLoadLock.lock() if (meshesToLoadSet.remove(item)) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/WorldMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/WorldMesh.kt index b60e8ffe8..2de200aa3 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/WorldMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/WorldMesh.kt @@ -38,6 +38,13 @@ class WorldMesh( val minPosition = Vec3i(16) val maxPosition = Vec3i(0) + fun finish() { + this.opaqueMesh?.finish() + this.translucentMesh?.finish() + this.transparentMesh?.finish() + this.textMesh?.finish() + } + @Synchronized fun load() { this.opaqueMesh?.load()