mesh: allow creation of vertex buffer async

This introduces a new state and function for it: `FINISHED`
This commit is contained in:
Bixilon 2022-12-16 15:44:05 +01:00
parent b8088c18b9
commit a37d6d69a7
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 37 additions and 10 deletions

View File

@ -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<T : Element>(
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<T : Element>(
}
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)
}

View File

@ -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,
}

View File

@ -484,6 +484,7 @@ class WorldRenderer(
if (mesh.clearEmpty() == 0) {
return queueItemUnload(item)
}
mesh.finish()
item.mesh = mesh
meshesToLoadLock.lock()
if (meshesToLoadSet.remove(item)) {

View File

@ -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()