it: load models, basic world renderer test

This commit is contained in:
Bixilon 2022-12-24 00:31:24 +01:00
parent 0b9b760894
commit 6f852af2f9
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 115 additions and 31 deletions

View File

@ -20,6 +20,7 @@ import de.bixilon.kutil.observer.DataObserver
import de.bixilon.kutil.reflection.ReflectionUtil.forceSet import de.bixilon.kutil.reflection.ReflectionUtil.forceSet
import de.bixilon.minosoft.data.registries.blocks.BlockState import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties 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.border.WorldBorder
import de.bixilon.minosoft.data.world.chunk.ChunkData import de.bixilon.minosoft.data.world.chunk.ChunkData
import de.bixilon.minosoft.data.world.positions.ChunkPosition import de.bixilon.minosoft.data.world.positions.ChunkPosition
@ -51,7 +52,7 @@ object WorldTestUtil {
for (x in -size..size) { for (x in -size..size) {
for (z in -size..size) { for (z in -size..size) {
val chunk = getOrCreateChunk(ChunkPosition(x, z)) val chunk = getOrCreateChunk(ChunkPosition(x, z))
chunk.setData(ChunkData(blocks = arrayOfNulls(16))) chunk.setData(ChunkData(blocks = arrayOfNulls(16), biomeSource = DummyBiomeSource(null)))
} }
} }
} }

View File

@ -14,15 +14,23 @@
package de.bixilon.minosoft.gui.rendering package de.bixilon.minosoft.gui.rendering
import de.bixilon.kutil.latch.CountUpAndDownLatch 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 import org.testng.annotations.Test
@Test(priority = 100, groups = ["rendering"]) @Test(priority = 100, groups = ["rendering"])
class RenderTestLoader { class RenderTestLoader {
fun init() { fun init() {
RenderTestUtil.rendering = Rendering(ConnectionTestUtil.createConnection(4)) val connection = createConnection(5)
val latch = CountUpAndDownLatch(1) 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) RenderTestUtil.rendering.start(latch, audio = false)
latch.dec() latch.dec()
latch.await() latch.await()

View File

@ -13,7 +13,9 @@
package de.bixilon.minosoft.gui.rendering 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.DefaultRenderer
import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer
import de.bixilon.minosoft.test.IT.reference import de.bixilon.minosoft.test.IT.reference
@ -26,4 +28,13 @@ object RenderTestUtil {
DefaultRenderer.list.clear() DefaultRenderer.list.clear()
reference() reference()
} }
fun Renderer.frame() {
this.prePrepareDraw()
if (this is AsyncRenderer) {
this.prepareDrawAsync()
}
this.postPrepareDraw()
// TODO: render normal
}
} }

View File

@ -32,11 +32,8 @@ class DummyTexture(
override var singlePixelSize: Vec2 = Vec2(1.0f) override var singlePixelSize: Vec2 = Vec2(1.0f)
override var state: TextureStates = TextureStates.DECLARED override var state: TextureStates = TextureStates.DECLARED
override val size: Vec2i = Vec2i(1, 1) override val size: Vec2i = Vec2i(1, 1)
override val transparency: TextureTransparencies override val transparency: TextureTransparencies get() = TextureTransparencies.OPAQUE
get() = TODO("Not yet implemented") override var properties: ImageProperties = ImageProperties()
override var properties: ImageProperties
get() = TODO("Not yet implemented")
set(value) {}
override var renderData: TextureRenderData = DummyTextureRenderData override var renderData: TextureRenderData = DummyTextureRenderData
override var data: ByteBuffer? override var data: ByteBuffer?
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
@ -44,9 +41,7 @@ class DummyTexture(
override var mipmapData: Array<ByteBuffer>? override var mipmapData: Array<ByteBuffer>?
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
set(value) {} set(value) {}
override var generateMipMaps: Boolean override var generateMipMaps: Boolean = false
get() = TODO("Not yet implemented")
set(value) {}
override fun load(assetsManager: AssetsManager) = TODO() override fun load(assetsManager: AssetsManager) = Unit
} }

View File

@ -45,7 +45,9 @@ class DummyWindow : BaseWindow {
override fun forceClose() = Unit override fun forceClose() = Unit
override fun swapBuffers() = Unit override fun swapBuffers() {
Thread.sleep(20)
}
override fun pollEvents() = Unit override fun pollEvents() = Unit

View File

@ -13,11 +13,16 @@
package de.bixilon.minosoft.gui.rendering.world 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
import de.bixilon.minosoft.gui.rendering.RenderTestUtil.frame
import org.testng.Assert import org.testng.Assert
import org.testng.annotations.Test import org.testng.annotations.Test
@Test(groups = ["world_renderer"], dependsOnGroups = ["rendering"]) @Test(groups = ["world_renderer"], dependsOnGroups = ["rendering", "block"])
class WorldRendererTest { class WorldRendererTest {
private fun create(): WorldRenderer { private fun create(): WorldRenderer {
@ -26,7 +31,45 @@ class WorldRendererTest {
return renderer 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() { fun testCreation() {
Assert.assertNotNull(create()) 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)
}
} }

View File

@ -18,14 +18,11 @@ import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.ResourceLocationAble import de.bixilon.minosoft.data.registries.ResourceLocationAble
open class DefaultFactory<T : ResourceLocationAble>(private vararg val factories: T) : Iterable<T> { open class DefaultFactory<T : ResourceLocationAble>(private vararg val factories: T) : Iterable<T> {
private val mapped: Map<ResourceLocation, T> private val map: MutableMap<ResourceLocation, T> = mutableMapOf()
val size: Int = factories.size val size: Int = factories.size
init { init {
val map: MutableMap<ResourceLocation, T> = mutableMapOf()
for (factory in factories) { for (factory in factories) {
map[factory.resourceLocation] = factory map[factory.resourceLocation] = factory
if (factory is MultiResourceLocationAble) { if (factory is MultiResourceLocationAble) {
@ -34,12 +31,22 @@ open class DefaultFactory<T : ResourceLocationAble>(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? { operator fun get(resourceLocation: ResourceLocation): T? {
return mapped[resourceLocation] return map[resourceLocation]
} }
operator fun get(index: Int): T { operator fun get(index: Int): T {

View File

@ -16,13 +16,13 @@ package de.bixilon.minosoft.data.world.biome.source
import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.registries.biomes.Biome 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? { override fun getBiome(x: Int, y: Int, z: Int): Biome? {
return biome return biome
} }
override fun getBiome(position: Vec3i): Biome { override fun getBiome(position: Vec3i): Biome? {
return biome return biome
} }
} }

View File

@ -13,15 +13,17 @@
package de.bixilon.minosoft.gui.rendering.font package de.bixilon.minosoft.gui.rendering.font
import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.concurrent.worker.unconditional.UnconditionalWorker
import de.bixilon.kutil.check.CheckUtil.check
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.kutil.latch.CountUpAndDownLatch
import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject
import de.bixilon.minosoft.data.registries.factory.DefaultFactory import de.bixilon.minosoft.data.registries.factory.DefaultFactory
import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.font.provider.* import de.bixilon.minosoft.gui.rendering.font.provider.*
import de.bixilon.minosoft.util.KUtil.toResourceLocation 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 import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
object FontLoader : DefaultFactory<FontProviderFactory<*>>( object FontLoader : DefaultFactory<FontProviderFactory<*>>(
@ -39,18 +41,22 @@ object FontLoader : DefaultFactory<FontProviderFactory<*>>(
val providersRaw = fontIndex["providers"].listCast<Map<String, Any>>()!! val providersRaw = fontIndex["providers"].listCast<Map<String, Any>>()!!
val providers: Array<FontProvider?> = arrayOfNulls(providersRaw.size) val providers: Array<FontProvider?> = arrayOfNulls(providersRaw.size)
val fontLatch = CountUpAndDownLatch(providersRaw.size, latch) val worker = UnconditionalWorker()
for ((index, provider) in providersRaw.withIndex()) { for ((index, provider) in providersRaw.withIndex()) {
val type = provider["type"].toResourceLocation() val type = provider["type"].toResourceLocation()
DefaultThreadPool += { worker += add@{
providers[index] = this[type].check { "Unknown font provider type $type" }.build(renderWindow, provider) val factory = this[type]
fontLatch.dec() 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( return Font(
providers = providers.unsafeCast(), providers = providers.trim(),
) )
} }
} }

View File

@ -344,4 +344,15 @@ object KUtil {
} }
return null return null
} }
inline fun <reified T> Array<T?>.trim(): Array<T> {
val list: MutableList<T> = mutableListOf()
for (entry in this) {
if (entry == null) {
continue
}
list += entry
}
return list.toTypedArray()
}
} }