From d4a701583efa06726e333bc5832008dc63bc2495 Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Fri, 20 Oct 2023 21:09:04 +0200 Subject: [PATCH] custom render order class That makes it more efficient (memory wise), does not use magic IntArrays, is tested and fixes the reverse render order --- .../gui/rendering/RenderTestLoader.kt | 11 ----- .../component/DummyComponentConsumer.kt | 3 +- .../gui/mesh/DummyGUIVertexConsumer.kt | 3 +- .../rendering/system/base/RenderOrderTest.kt} | 32 ++++++++----- .../system/dummy/DummyRenderSystem.kt | 2 +- .../rendering/chunk/border/WorldBorderMesh.kt | 4 +- .../rendering/chunk/mesh/SingleChunkMesh.kt | 9 ++-- .../chunk/mesher/FluidSectionMesher.kt | 10 ++-- .../gui/rendering/font/WorldGUIConsumer.kt | 7 ++- .../rendering/framebuffer/FramebufferMesh.kt | 4 +- .../gui/rendering/gui/mesh/GUIMeshCache.kt | 3 +- .../rendering/gui/mesh/GUIVertexConsumer.kt | 11 ++--- .../models/block/state/baked/BakedFace.kt | 10 ++-- .../rendering/skeletal/mesh/SkeletalMesh.kt | 6 +-- .../rendering/skeletal/model/SkeletalModel.kt | 4 +- .../skeletal/model/elements/SkeletalFace.kt | 13 ++++- .../gui/rendering/system/base/RenderOrder.kt | 47 +++++++++++++++++++ .../gui/rendering/system/base/RenderSystem.kt | 2 +- .../system/opengl/OpenGLRenderSystem.kt | 10 ++-- .../util/mesh/AbstractVertexConsumer.kt | 4 +- .../gui/rendering/util/mesh/LineMesh.kt | 9 ++-- .../minosoft/gui/rendering/util/mesh/Mesh.kt | 5 +- 22 files changed, 125 insertions(+), 84 deletions(-) rename src/{main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/ModelBakeUtil.kt => integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/RenderOrderTest.kt} (50%) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderOrder.kt 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 6decb6153..443bd2557 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 @@ -44,15 +44,4 @@ class RenderTestLoader { assertTrue(context.system is DummyRenderSystem) RenderTestUtil.context = context } - - /* - fun loadModels() { - val latch = SimpleLatch(1) - RenderTestUtil.context.models.load(latch) - RenderTestUtil.context.models.entities.skeletal.clear() - RenderTestUtil.context.models.bake(latch) - latch.dec() - latch.await() - } - */ } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt index 381cff187..7cc602779 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/font/renderer/component/DummyComponentConsumer.kt @@ -22,6 +22,7 @@ import de.bixilon.minosoft.gui.rendering.font.types.FontType import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture import org.testng.Assert.assertEquals @@ -29,7 +30,7 @@ class DummyComponentConsumer : GUIVertexConsumer { val chars: MutableList = mutableListOf() val quads: MutableList = mutableListOf() - override val order: IntArray get() = IntArray(0) + override val order: RenderOrder get() = RenderOrder(IntArray(0)) override fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) = Broken() override fun addCache(cache: GUIMeshCache) = Broken() override fun ensureSize(size: Int) = Unit diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt index 3b645a486..10530d858 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/gui/mesh/DummyGUIVertexConsumer.kt @@ -15,12 +15,13 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.data.text.formatting.color.RGBColor +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem open class DummyGUIVertexConsumer : GUIVertexConsumer { - override val order: IntArray get() = OpenGLRenderSystem.QUAD_ORDER + override val order: RenderOrder get() = OpenGLRenderSystem.QUAD_ORDER var char = 0 override fun addCache(cache: GUIMeshCache) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/ModelBakeUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/RenderOrderTest.kt similarity index 50% rename from src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/ModelBakeUtil.kt rename to src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/RenderOrderTest.kt index b0b9ed7e8..9a861706c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/ModelBakeUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/base/RenderOrderTest.kt @@ -11,19 +11,29 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.gui.rendering.models.block.legacy +package de.bixilon.minosoft.gui.rendering.system.base -import de.bixilon.kotlinglm.vec2.Vec2 +import org.testng.Assert.assertEquals +import org.testng.annotations.Test -@Deprecated("legacy") -object ModelBakeUtil { +@Test(groups = ["rendering"]) +class RenderOrderTest { - fun getTextureCoordinates(uvStart: Vec2, uvEnd: Vec2): Array { - return arrayOf( - Vec2(uvEnd.x, uvStart.y), - uvStart, - Vec2(uvStart.x, uvEnd.y), - uvEnd, - ) + fun `simple iteration`() { + val order = RenderOrder(intArrayOf(0, 9, 1, 8, 2, 7, 3, 6)) + + val result: MutableList = mutableListOf() + order.iterate { position, uv -> result += position; result += uv } + + assertEquals(result, listOf(0, 9, 1, 8, 2, 7, 3, 6)) + } + + fun `reverse iteration`() { + val order = RenderOrder(intArrayOf(0, 9, 1, 8, 2, 7, 3, 6)) + + val result: MutableList = mutableListOf() + order.iterateReverse { position, uv -> result += position; result += uv } + + assertEquals(result, listOf(0, 9, 3, 6, 2, 7, 1, 8)) } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/DummyRenderSystem.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/DummyRenderSystem.kt index 3e8dbfd87..52b5d3534 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/DummyRenderSystem.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/system/dummy/DummyRenderSystem.kt @@ -80,7 +80,7 @@ class DummyRenderSystem( override var clearColor: RGBColor = Colors.TRANSPARENT override var quadType: PrimitiveTypes = PrimitiveTypes.QUAD - override var quadOrder: IntArray = if (quadType == PrimitiveTypes.QUAD) OpenGLRenderSystem.QUAD_ORDER else OpenGLRenderSystem.TRIANGLE_ORDER + override var quadOrder: RenderOrder = if (quadType == PrimitiveTypes.QUAD) OpenGLRenderSystem.QUAD_ORDER else OpenGLRenderSystem.TRIANGLE_ORDER override fun readPixels(start: Vec2i, end: Vec2i, type: PixelTypes): ByteBuffer { TODO("Not yet implemented") diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderMesh.kt index d5f13597f..15721a105 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/border/WorldBorderMesh.kt @@ -59,7 +59,7 @@ class WorldBorderMesh( } private fun addVertexX(x: Float, width: Float, positions: Array, rotated: Boolean) { - for (index in 0 until order.size step 2) { + for (index in 0 until order.order.size step 2) { val (z, y) = positions[index] val texture = if (rotated) textureIndex(index + 1) else index + 1 addVertex(x, y, z, textureIndex(texture), width) @@ -73,7 +73,7 @@ class WorldBorderMesh( } private fun addVertexZ(z: Float, width: Float, positions: Array, rotated: Boolean) { - for (index in 0 until order.size step 2) { + for (index in 0 until order.order.size step 2) { val (x, y) = positions[index] val texture = if (rotated) textureIndex(index + 1) else index + 1 addVertex(x, y, z, textureIndex(texture), width) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt index 4234aa0bd..02bc7af23 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesh/SingleChunkMesh.kt @@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh @@ -62,19 +63,19 @@ class SingleChunkMesh(context: RenderContext, initialCacheSize: Int, onDemand: B } companion object { - val TRIANGLE_ORDER = intArrayOf( + val TRIANGLE_ORDER = RenderOrder(intArrayOf( 0, 0, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0, - ) - val QUAD_ORDER = intArrayOf( + )) + val QUAD_ORDER = RenderOrder(intArrayOf( 0, 0, 3, 3, 2, 2, 1, 1, - ) + )) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt index d9f17d445..66ce2bfdd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/mesher/FluidSectionMesher.kt @@ -248,13 +248,9 @@ class FluidSectionMesher( } } - private inline fun addFluidVertices(meshToUse: SingleChunkMesh, positions: Array, texturePositions: Array, flowingTexture: Texture, fluidTint: Int, fluidLight: Int) { - for (index in 0 until meshToUse.order.size step 2) { - meshToUse.addVertex(positions[meshToUse.order[index]].array, texturePositions[meshToUse.order[index + 1]], flowingTexture, fluidTint, fluidLight) - } - for (index in (meshToUse.order.size - 2) downTo 0 step 2) { - meshToUse.addVertex(positions[meshToUse.order[index]].array, texturePositions[meshToUse.order[index + 1]], flowingTexture, fluidTint, fluidLight) - } + private inline fun addFluidVertices(mesh: SingleChunkMesh, positions: Array, texturePositions: Array, flowingTexture: Texture, fluidTint: Int, fluidLight: Int) { + mesh.order.iterate { position, uv -> mesh.addVertex(positions[position].array, texturePositions[uv], flowingTexture, fluidTint, fluidLight) } + mesh.order.iterateReverse { position, uv -> mesh.addVertex(positions[position].array, texturePositions[uv], flowingTexture, fluidTint, fluidLight) } } private fun getCornerHeight(providedChunk: Chunk, providedChunkPosition: Vec2i, position: Vec3i, fluid: Fluid): Float { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt index be4db1ff5..166a9893e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/font/WorldGUIConsumer.kt @@ -23,13 +23,14 @@ import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProp import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture class WorldGUIConsumer(val mesh: SingleChunkMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer { private val whiteTexture = mesh.context.textures.whiteTexture - override val order: IntArray get() = mesh.order + override val order: RenderOrder get() = mesh.order override fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) { val transformed = transform.fastTimes(position.x / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION, -position.y / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION) @@ -53,9 +54,7 @@ class WorldGUIConsumer(val mesh: SingleChunkMesh, val transform: Mat4, val light Vec2(uvStart.x, uvEnd.y), ) - for (index in 0 until order.size step 2) { - addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options) - } + order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) } } override fun addCache(cache: GUIMeshCache) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/FramebufferMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/FramebufferMesh.kt index 32a2221a8..587bd5870 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/FramebufferMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/FramebufferMesh.kt @@ -28,9 +28,7 @@ class FramebufferMesh(context: RenderContext) : Mesh(context, DefaultFramebuffer Vec2(+1.0f, +1.0f) to Vec2(1.0f, 0.0f), Vec2(+1.0f, -1.0f) to Vec2(1.0f, 1.0f), ) - for (index in 0 until order.size step 2) { - addVertex(vertices[order[index]].first, vertices[order[index + 1]].second) - } + order.iterate { position, uv -> addVertex(vertices[position].first, vertices[uv].second) } } private fun addVertex(position: Vec2, uv: Vec2) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt index a4cc1a519..bdf976b79 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIMeshCache.kt @@ -18,12 +18,13 @@ import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.gui.rendering.RenderContext +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY class GUIMeshCache( var halfSize: Vec2, - override val order: IntArray, + override val order: RenderOrder, val context: RenderContext, initialCacheSize: Int = 1000, var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize), diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt index 290b01c8d..9ef545ed2 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/mesh/GUIVertexConsumer.kt @@ -17,12 +17,13 @@ import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture interface GUIVertexConsumer { - val order: IntArray + val order: RenderOrder fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) @@ -43,9 +44,7 @@ interface GUIVertexConsumer { uvEnd, ) - for (index in 0 until order.size step 2) { - addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options) - } + order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) } } fun addQuad(start: Vec2, end: Vec2, texture: TexturePart, tint: RGBColor, options: GUIVertexOptions?) { @@ -73,9 +72,7 @@ interface GUIVertexConsumer { uvEnd, ) - for (index in 0 until order.size step 2) { - addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options) - } + order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) } } fun addCache(cache: GUIMeshCache) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt index 95f2d0728..e37496637 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt @@ -53,12 +53,9 @@ class BakedFace( val mesh = mesh.mesh(texture) mesh.data.ensureSize(SingleChunkMesh.WorldMeshStruct.FLOATS_PER_VERTEX * (mesh.order.size / 2)) - var index = 0 - val size = mesh.order.size - while (index < size) { - val vertexOffset = mesh.order[index] * 3 - val uvOffset = mesh.order[index + 1] * 2 - + mesh.order.iterate { position, uv -> + val vertexOffset = position * 3 + val uvOffset = uv * 2 mesh.addVertex( x = offset[0] + positions[vertexOffset], y = offset[1] + positions[vertexOffset + 1], z = offset[2] + positions[vertexOffset + 2], u = this.uv[uvOffset], @@ -66,7 +63,6 @@ class BakedFace( shaderTextureId = textureId, lightTint = lightTint, ) - index += 2 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt index 010c2b749..2642e0f09 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/mesh/SkeletalMesh.kt @@ -33,9 +33,9 @@ class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context val transform = transform.buffer() val textureShaderId = texture.shaderId.buffer() - for (index in 0 until order.size step 2) { - val indexPosition = positions[order[index]].array - val transformedUV = texture.transformUV(uv[order[index + 1]]) + order.iterate { position, uvIndex -> + val indexPosition = positions[position].array + val transformedUV = texture.transformUV(uv[uvIndex]) addVertex(indexPosition, transformedUV, transform, textureShaderId) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt index 7de75d033..e0cbdf57c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/SkeletalModel.kt @@ -33,8 +33,8 @@ import java.util.concurrent.atomic.AtomicInteger data class SkeletalModel( val elements: Map, val textures: Map, - val animations: Map, - val transforms: Map, + val animations: Map = emptyMap(), + val transforms: Map = emptyMap(), ) { val loadedTextures: MutableMap = mutableMapOf() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt index e55072c5b..b19033de4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt @@ -14,13 +14,13 @@ package de.bixilon.minosoft.gui.rendering.skeletal.model.elements import de.bixilon.kotlinglm.GLM +import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.data.Axes import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Companion.BLOCK_SIZE import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV -import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign @@ -29,12 +29,21 @@ data class SkeletalFace( val texture: ResourceLocation? = null, ) { + private fun getTexturePositions(uvStart: Vec2, uvEnd: Vec2): Array { + return arrayOf( + Vec2(uvEnd.x, uvStart.y), + uvStart, + Vec2(uvStart.x, uvEnd.y), + uvEnd, + ) + } + fun bake(context: SkeletalBakeContext, direction: Directions, element: SkeletalElement, transform: Int) { val positions = direction.getPositions(context.offset + (element.from - context.inflate) / BLOCK_SIZE, context.offset + (element.to + context.inflate) / BLOCK_SIZE) val texture = context.textures[texture ?: context.texture ?: throw IllegalStateException("Element has no texture set!")] ?: throw IllegalStateException("Texture not found!") - val texturePositions = ModelBakeUtil.getTextureCoordinates(uv.start / texture.properties.resolution, uv.end / texture.properties.resolution) + val texturePositions = getTexturePositions(uv.start / texture.properties.resolution, uv.end / texture.properties.resolution) for (rotation in context.rotations) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderOrder.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderOrder.kt new file mode 100644 index 000000000..68063165b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderOrder.kt @@ -0,0 +1,47 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.system.base + +class RenderOrder( + @JvmField val order: IntArray, +) { + val size = order.size / 2 + + init { + if (order.size % 2 != 0) throw IllegalStateException("Order must be position=>uv, ...") + } + + inline fun vertex(index: Int, vertex: (position: Int, uv: Int) -> Unit) { + vertex.invoke(order[index], order[index + 1]) + } + + inline fun iterate(vertex: (position: Int, uv: Int) -> Unit) { + var index = 0 + while (index < order.size) { + this.vertex(index, vertex) + index += 2 + } + } + + inline fun iterateReverse(vertex: (position: Int, uv: Int) -> Unit) { + if (size == 0) return + this.vertex(0, vertex) + + var index = order.size - 1 - 1 // index, element alignment + while (index > 1) { + this.vertex(index, vertex) + index -= 2 + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt index a37661423..573890ebc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt @@ -102,7 +102,7 @@ interface RenderSystem { var clearColor: RGBColor var quadType: PrimitiveTypes - var quadOrder: IntArray + var quadOrder: RenderOrder fun readPixels(start: Vec2i, end: Vec2i, type: PixelTypes): ByteBuffer diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt index 9c91f56cc..9fe8e6eed 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt @@ -69,7 +69,7 @@ class OpenGLRenderSystem( } else { PrimitiveTypes.TRIANGLE } - override var quadOrder: IntArray = if (quadType == PrimitiveTypes.QUAD) QUAD_ORDER else TRIANGLE_ORDER + override var quadOrder: RenderOrder = if (quadType == PrimitiveTypes.QUAD) QUAD_ORDER else TRIANGLE_ORDER var boundVao = -1 var boundBuffer = -1 var uniformBufferBindingIndex = 0 @@ -328,7 +328,7 @@ class OpenGLRenderSystem( } companion object { - val TRIANGLE_ORDER = intArrayOf( + val TRIANGLE_ORDER = RenderOrder(intArrayOf( // TOOD: they are all rotated 90° wrong, fix this for triangle and quad order 0, 1, 3, 2, @@ -336,13 +336,13 @@ class OpenGLRenderSystem( 2, 3, 1, 0, 0, 1, - ) - val QUAD_ORDER = intArrayOf( + )) + val QUAD_ORDER = RenderOrder(intArrayOf( 0, 1, 3, 2, 2, 3, 1, 0, - ) + )) private val RenderingCapabilities.gl: Int get() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/AbstractVertexConsumer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/AbstractVertexConsumer.kt index f0e5d7550..0123640ff 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/AbstractVertexConsumer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/AbstractVertexConsumer.kt @@ -13,6 +13,8 @@ package de.bixilon.minosoft.gui.rendering.util.mesh +import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder + interface AbstractVertexConsumer { - val order: IntArray + val order: RenderOrder } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt index 06e0c6b96..acab1a9e9 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mesh/LineMesh.kt @@ -69,9 +69,7 @@ open class LineMesh(context: RenderContext, initialCacheSize: Int = 1000) : Gene Vec3(end.x + normal1.x + directionWidth.x, end.y + normal1.y + directionWidth.y, end.z + normal1.z + directionWidth.z), Vec3(end.x + normal2.x + directionWidth.x, end.y + normal2.y + directionWidth.y, end.z + normal2.z + directionWidth.z), ) - for (index in 0 until order.size step 2) { - addVertex(positions[order[index]], color) - } + order.iterate { position, uv -> addVertex(positions[position], color) } } fun drawAABB(aabb: AABB, position: Vec3d, lineWidth: Float, color: RGBColor, margin: Float = 0.0f, shape: AbstractVoxelShape? = null) { @@ -83,9 +81,8 @@ open class LineMesh(context: RenderContext, initialCacheSize: Int = 1000) : Gene val offset = context.camera.offset.offset for (direction in Directions.VALUES) { val positions = direction.getPositions(Vec3(aabb.min - offset), Vec3(aabb.max - offset)) - for (index in 0 until order.size step 2) { - addVertex(positions[order[index]], color) - } + + order.iterate { position, uv -> addVertex(positions[position], color) } } } 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 52af99ae5..b07d31512 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 @@ -126,10 +126,7 @@ abstract class Mesh( uvEnd, Vec2(uvEnd.x, uvStart.y), ) - - for (index in 0 until order.size step 2) { - vertexConsumer.invoke(positions[order[index]], texturePositions[order[index + 1]]) - } + order.iterate { position, uv -> vertexConsumer.invoke(positions[position], texturePositions[uv]) } } enum class MeshStates {