From 6f852af2f9bf024b9e7635fc8f4ec03fc8daf118 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sat, 24 Dec 2022 00:31:24 +0100 Subject: [PATCH] it: load models, basic world renderer test --- .../minosoft/data/world/WorldTestUtil.kt | 3 +- .../gui/rendering/RenderTestLoader.kt | 12 ++++- .../minosoft/gui/rendering/RenderTestUtil.kt | 11 +++++ .../system/dummy/texture/DummyTexture.kt | 13 ++---- .../system/window/dummy/DummyWindow.kt | 4 +- .../gui/rendering/world/WorldRendererTest.kt | 45 ++++++++++++++++++- .../data/registries/factory/DefaultFactory.kt | 19 +++++--- .../world/biome/source/DummyBiomeSource.kt | 4 +- .../minosoft/gui/rendering/font/FontLoader.kt | 24 ++++++---- .../java/de/bixilon/minosoft/util/KUtil.kt | 11 +++++ 10 files changed, 115 insertions(+), 31 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt index 53669cb16..3faf46a94 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/WorldTestUtil.kt @@ -20,6 +20,7 @@ import de.bixilon.kutil.observer.DataObserver import de.bixilon.kutil.reflection.ReflectionUtil.forceSet import de.bixilon.minosoft.data.registries.blocks.BlockState import de.bixilon.minosoft.data.registries.dimension.DimensionProperties +import de.bixilon.minosoft.data.world.biome.source.DummyBiomeSource import de.bixilon.minosoft.data.world.border.WorldBorder import de.bixilon.minosoft.data.world.chunk.ChunkData import de.bixilon.minosoft.data.world.positions.ChunkPosition @@ -51,7 +52,7 @@ object WorldTestUtil { for (x in -size..size) { for (z in -size..size) { val chunk = getOrCreateChunk(ChunkPosition(x, z)) - chunk.setData(ChunkData(blocks = arrayOfNulls(16))) + chunk.setData(ChunkData(blocks = arrayOfNulls(16), biomeSource = DummyBiomeSource(null))) } } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestLoader.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestLoader.kt index 61b67b428..e415b264f 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestLoader.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestLoader.kt @@ -14,15 +14,23 @@ package de.bixilon.minosoft.gui.rendering import de.bixilon.kutil.latch.CountUpAndDownLatch -import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil +import de.bixilon.kutil.reflection.ReflectionUtil.forceSet +import de.bixilon.minosoft.assets.AssetsLoader +import de.bixilon.minosoft.gui.rendering.font.FontLoader +import de.bixilon.minosoft.gui.rendering.font.provider.BitmapFontProvider +import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil.createConnection import org.testng.annotations.Test @Test(priority = 100, groups = ["rendering"]) class RenderTestLoader { fun init() { - RenderTestUtil.rendering = Rendering(ConnectionTestUtil.createConnection(4)) + val connection = createConnection(5) val latch = CountUpAndDownLatch(1) + connection::assetsManager.forceSet(AssetsLoader.create(connection.profiles.resources, connection.version, latch)) + FontLoader.remove(BitmapFontProvider) // TODO: remove + connection.assetsManager.load(latch) + RenderTestUtil.rendering = Rendering(connection) RenderTestUtil.rendering.start(latch, audio = false) latch.dec() latch.await() diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestUtil.kt index 0fa19b925..bf4c88da4 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/RenderTestUtil.kt @@ -13,7 +13,9 @@ package de.bixilon.minosoft.gui.rendering +import de.bixilon.minosoft.gui.rendering.renderer.renderer.AsyncRenderer import de.bixilon.minosoft.gui.rendering.renderer.renderer.DefaultRenderer +import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer import de.bixilon.minosoft.test.IT.reference @@ -26,4 +28,13 @@ object RenderTestUtil { DefaultRenderer.list.clear() reference() } + + fun Renderer.frame() { + this.prePrepareDraw() + if (this is AsyncRenderer) { + this.prepareDrawAsync() + } + this.postPrepareDraw() + // TODO: render normal + } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt index 1f9cd31ab..e0b77f30c 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/texture/DummyTexture.kt @@ -32,11 +32,8 @@ class DummyTexture( override var singlePixelSize: Vec2 = Vec2(1.0f) override var state: TextureStates = TextureStates.DECLARED override val size: Vec2i = Vec2i(1, 1) - override val transparency: TextureTransparencies - get() = TODO("Not yet implemented") - override var properties: ImageProperties - get() = TODO("Not yet implemented") - set(value) {} + override val transparency: TextureTransparencies get() = TextureTransparencies.OPAQUE + override var properties: ImageProperties = ImageProperties() override var renderData: TextureRenderData = DummyTextureRenderData override var data: ByteBuffer? get() = TODO("Not yet implemented") @@ -44,9 +41,7 @@ class DummyTexture( override var mipmapData: Array? get() = TODO("Not yet implemented") set(value) {} - override var generateMipMaps: Boolean - get() = TODO("Not yet implemented") - set(value) {} + override var generateMipMaps: Boolean = false - override fun load(assetsManager: AssetsManager) = TODO() + override fun load(assetsManager: AssetsManager) = Unit } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/window/dummy/DummyWindow.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/window/dummy/DummyWindow.kt index a27057401..872d7b0aa 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/window/dummy/DummyWindow.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/window/dummy/DummyWindow.kt @@ -45,7 +45,9 @@ class DummyWindow : BaseWindow { override fun forceClose() = Unit - override fun swapBuffers() = Unit + override fun swapBuffers() { + Thread.sleep(20) + } override fun pollEvents() = Unit diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/world/WorldRendererTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/world/WorldRendererTest.kt index 5cf64504b..2f9da1bb6 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/world/WorldRendererTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/world/WorldRendererTest.kt @@ -13,11 +13,16 @@ package de.bixilon.minosoft.gui.rendering.world +import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.kutil.latch.CountUpAndDownLatch +import de.bixilon.minosoft.data.registries.blocks.StoneTestO import de.bixilon.minosoft.gui.rendering.RenderTestUtil +import de.bixilon.minosoft.gui.rendering.RenderTestUtil.frame import org.testng.Assert import org.testng.annotations.Test -@Test(groups = ["world_renderer"], dependsOnGroups = ["rendering"]) +@Test(groups = ["world_renderer"], dependsOnGroups = ["rendering", "block"]) class WorldRendererTest { private fun create(): WorldRenderer { @@ -26,7 +31,45 @@ class WorldRendererTest { return renderer } + private fun WorldRenderer.awaitQueue(count: Int) { + for (i in 0 until 1000) { + Thread.sleep(10) + frame() + if (loaded.size == 1) { + break + } + } + } + + @Test(priority = -1) + fun loadModels() { + val latch = CountUpAndDownLatch(1) + RenderTestUtil.context.modelLoader.load(latch) + latch.dec() + latch.await() + } + fun testCreation() { Assert.assertNotNull(create()) } + + fun queueEmptyChunk() { + val chunk = RenderTestUtil.context.connection.world[Vec2i(0, 0)]!! + val renderer = create() + renderer.master.tryQueue(chunk, ignoreLoaded = true, force = true) + Thread.sleep(50) + renderer.frame() + renderer.awaitQueue(0) + Assert.assertEquals(renderer.loaded.size, 0) + } + + fun queueSingleChunk() { + val chunk = RenderTestUtil.context.connection.world[Vec2i(0, 0)]!! + chunk[Vec3i(0, 0, 0)] = StoneTestO.state + val renderer = create() + renderer.master.tryQueue(chunk, ignoreLoaded = true, force = true) + renderer.awaitQueue(1) + chunk[Vec3i(0, 0, 0)] = null + Assert.assertEquals(renderer.loaded.size, 1) + } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt b/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt index 08cdc9b8a..433a1b84c 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/factory/DefaultFactory.kt @@ -18,14 +18,11 @@ import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocationAble open class DefaultFactory(private vararg val factories: T) : Iterable { - private val mapped: Map + private val map: MutableMap = mutableMapOf() val size: Int = factories.size init { - val map: MutableMap = mutableMapOf() - - for (factory in factories) { map[factory.resourceLocation] = factory if (factory is MultiResourceLocationAble) { @@ -34,12 +31,22 @@ open class DefaultFactory(private vararg val factories } } } + } - mapped = map + fun add(factory: T) { + map[factory.resourceLocation] = factory + } + + fun remove(name: ResourceLocation) { + map -= name + } + + fun remove(factory: ResourceLocationAble) { + map -= factory.resourceLocation } operator fun get(resourceLocation: ResourceLocation): T? { - return mapped[resourceLocation] + return map[resourceLocation] } operator fun get(index: Int): T { diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt index d1d8babc4..b5abfaa11 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/source/DummyBiomeSource.kt @@ -16,13 +16,13 @@ package de.bixilon.minosoft.data.world.biome.source import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.minosoft.data.registries.biomes.Biome -class DummyBiomeSource(private val biome: Biome) : BiomeSource { +class DummyBiomeSource(private val biome: Biome?) : BiomeSource { override fun getBiome(x: Int, y: Int, z: Int): Biome? { return biome } - override fun getBiome(position: Vec3i): Biome { + override fun getBiome(position: Vec3i): Biome? { return biome } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/FontLoader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/FontLoader.kt index 004105542..31f03f2e1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/FontLoader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/FontLoader.kt @@ -13,15 +13,17 @@ package de.bixilon.minosoft.gui.rendering.font -import de.bixilon.kutil.cast.CastUtil.unsafeCast -import de.bixilon.kutil.check.CheckUtil.check -import de.bixilon.kutil.concurrent.pool.DefaultThreadPool +import de.bixilon.kutil.concurrent.worker.unconditional.UnconditionalWorker import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject import de.bixilon.minosoft.data.registries.factory.DefaultFactory import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.font.provider.* import de.bixilon.minosoft.util.KUtil.toResourceLocation +import de.bixilon.minosoft.util.KUtil.trim +import de.bixilon.minosoft.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast object FontLoader : DefaultFactory>( @@ -39,18 +41,22 @@ object FontLoader : DefaultFactory>( val providersRaw = fontIndex["providers"].listCast>()!! val providers: Array = arrayOfNulls(providersRaw.size) - val fontLatch = CountUpAndDownLatch(providersRaw.size, latch) + val worker = UnconditionalWorker() for ((index, provider) in providersRaw.withIndex()) { val type = provider["type"].toResourceLocation() - DefaultThreadPool += { - providers[index] = this[type].check { "Unknown font provider type $type" }.build(renderWindow, provider) - fontLatch.dec() + worker += add@{ + val factory = this[type] + if (factory == null) { + Log.log(LogMessageType.RENDERING_LOADING, LogLevels.WARN) { "Unknown font provider: $type" } + return@add + } + providers[index] = factory.build(renderWindow, provider) } } - fontLatch.await() + worker.work(latch) return Font( - providers = providers.unsafeCast(), + providers = providers.trim(), ) } } diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index dc7862d5e..ec1166f46 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -344,4 +344,15 @@ object KUtil { } return null } + + inline fun Array.trim(): Array { + val list: MutableList = mutableListOf() + for (entry in this) { + if (entry == null) { + continue + } + list += entry + } + return list.toTypedArray() + } }