From dce90431ee29cc68c1a3346fb48cc42669005af4 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 2 Sep 2022 19:31:44 +0200 Subject: [PATCH] world rendering: reduce memory footprint, improve performance --- .../blocks/properties/BlockProperties.kt | 33 +++++++++---------- .../font/renderer/ChatComponentRenderer.kt | 2 +- .../rendering/models/baked/block/BakedFace.kt | 6 ++-- .../renderer/sign/SignBlockEntityRenderer.kt | 2 +- .../rendering/world/mesh/SingleWorldMesh.kt | 19 +++++++++-- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/properties/BlockProperties.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/properties/BlockProperties.kt index 22e813d96..856b4fe8e 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/properties/BlockProperties.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/properties/BlockProperties.kt @@ -142,32 +142,31 @@ enum class BlockProperties { val map: MutableMap> = mutableMapOf() for (value in values()) { - val list = map.getOrPut(value.group) { mutableListOf() } - list.add(value) + map.getOrPut(value.group) { mutableListOf() } += value } return@run map } fun parseProperty(group: String, value: Any): Pair { - PROPERTIES[group]?.let { - var retProperty: BlockProperties? = null - var retValue: Any? = null + val properties = PROPERTIES[group] ?: throw IllegalArgumentException("Can not find group: $group, expected value $value") - for (blockProperty in it) { - retValue = try { - blockProperty.serializer.deserialize(value) - } catch (exception: Throwable) { - continue - } - retProperty = blockProperty - } + var property: BlockProperties? = null + var retValue: Any? = null - if (retProperty == null || retValue == null) { - throw IllegalArgumentException("Can not parse value $value for group $group") + for (blockProperty in properties) { + retValue = try { + blockProperty.serializer.deserialize(value) + } catch (exception: Throwable) { + continue } - return Pair(retProperty, retValue) - } ?: throw IllegalArgumentException("Can not find group: $group, expected value $value") + property = blockProperty + } + + if (property == null || retValue == null) { + throw IllegalArgumentException("Can not parse value $value for group $group") + } + return Pair(property, retValue) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt index 52fda19a3..0054e4aaf 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/renderer/ChatComponentRenderer.kt @@ -69,7 +69,7 @@ interface ChatComponentRenderer { val textMesh = mesh.textMesh!! val primitives = calculatePrimitiveCount(text) - textMesh.data.ensureSize(primitives * textMesh.order.size * SingleWorldMesh.SectionArrayMeshStruct.FLOATS_PER_VERTEX) + textMesh.data.ensureSize(primitives * textMesh.order.size * SingleWorldMesh.WorldMeshStruct.FLOATS_PER_VERTEX) val consumer = WorldGUIConsumer(textMesh, matrix, light) render3dFlat(renderWindow, Vec2i(), scale, maxSize, consumer, text, light) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedFace.kt index c77b2737c..f4979c03f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/baked/block/BakedFace.kt @@ -47,10 +47,12 @@ class BakedFace( color.g *= ((tint shr 8) and 0xFF) / RGBColor.COLOR_FLOAT_DIVIDER color.b *= (tint and 0xFF) / RGBColor.COLOR_FLOAT_DIVIDER } - val rgb = color.rgb + + val textureShaderId = Float.fromBits(texture.renderData.shaderTextureId) + val tintLight = Float.fromBits(color.rgb or (light shl 24)) for ((index, textureIndex) in meshToUse.order) { val indexOffset = index * 3 - meshToUse.addVertex(floatArrayOf(positions[indexOffset + 0] + position[0], positions[indexOffset + 1] + position[1], positions[indexOffset + 2] + position[2]), uv[textureIndex], texture, rgb, light) + meshToUse.addVertex(positions[indexOffset + 0] + position[0], positions[indexOffset + 1] + position[1], positions[indexOffset + 2] + position[2], uv[textureIndex], texture, textureShaderId, tintLight) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt index bb25e42fb..1e321af00 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/renderer/sign/SignBlockEntityRenderer.kt @@ -64,7 +64,7 @@ class SignBlockEntityRenderer( for (line in sign.lines) { primitives += ChatComponentRenderer.calculatePrimitiveCount(line) } - textMesh.data.ensureSize(primitives * textMesh.order.size * SingleWorldMesh.SectionArrayMeshStruct.FLOATS_PER_VERTEX) + textMesh.data.ensureSize(primitives * textMesh.order.size * SingleWorldMesh.WorldMeshStruct.FLOATS_PER_VERTEX) for (line in sign.lines) { ChatComponentRenderer.render3dFlat(renderWindow, textPosition, TEXT_SCALE, Vec3(0.0f, -yRotation, 0.0f), Vec2i(SIGN_MAX_WIDTH * TEXT_SCALE, Font.TOTAL_CHAR_HEIGHT * TEXT_SCALE), mesh, line, light) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/SingleWorldMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/SingleWorldMesh.kt index 751b59464..34d06ea97 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/SingleWorldMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/mesh/SingleWorldMesh.kt @@ -20,10 +20,11 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTex import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct -class SingleWorldMesh(renderWindow: RenderWindow, initialCacheSize: Int, onDemand: Boolean = false) : Mesh(renderWindow, SectionArrayMeshStruct, initialCacheSize = initialCacheSize, onDemand = onDemand) { +class SingleWorldMesh(renderWindow: RenderWindow, initialCacheSize: Int, onDemand: Boolean = false) : Mesh(renderWindow, WorldMeshStruct, initialCacheSize = initialCacheSize, onDemand = onDemand) { var distance: Float = 0.0f // Used for sorting fun addVertex(position: FloatArray, uv: Vec2, texture: AbstractTexture, tintColor: Int, light: Int) { + data.ensureSize(WorldMeshStruct.FLOATS_PER_VERTEX) val transformedUV = texture.renderData.transformUV(uv) data.add(position[0]) data.add(position[1]) @@ -34,13 +35,25 @@ class SingleWorldMesh(renderWindow: RenderWindow, initialCacheSize: Int, onDeman data.add(Float.fromBits(tintColor or (light shl 24))) } + fun addVertex(x: Float, y: Float, z: Float, uv: Vec2, texture: AbstractTexture, shaderTextureId: Float, tintLight: Float) { + data.ensureSize(WorldMeshStruct.FLOATS_PER_VERTEX) + val transformedUV = texture.renderData.transformUV(uv) + data.add(x) + data.add(y) + data.add(z) + data.add(transformedUV.x) + data.add(transformedUV.y) + data.add(shaderTextureId) + data.add(tintLight) + } - data class SectionArrayMeshStruct( + + data class WorldMeshStruct( val position: Vec3, val uv: Vec2, val indexLayerAnimation: Int, val tintLight: Int, ) { - companion object : MeshStruct(SectionArrayMeshStruct::class) + companion object : MeshStruct(WorldMeshStruct::class) } }