custom render order class

That makes it more efficient (memory wise), does not use magic IntArrays, is tested and fixes the reverse render order
This commit is contained in:
Moritz Zwerger 2023-10-20 21:09:04 +02:00
parent 2280c5b35f
commit d4a701583e
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
22 changed files with 125 additions and 84 deletions

View File

@ -44,15 +44,4 @@ class RenderTestLoader {
assertTrue(context.system is DummyRenderSystem) assertTrue(context.system is DummyRenderSystem)
RenderTestUtil.context = context 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()
}
*/
} }

View File

@ -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.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions 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.shader.ShaderTexture
import org.testng.Assert.assertEquals import org.testng.Assert.assertEquals
@ -29,7 +30,7 @@ class DummyComponentConsumer : GUIVertexConsumer {
val chars: MutableList<RendererdCodePoint> = mutableListOf() val chars: MutableList<RendererdCodePoint> = mutableListOf()
val quads: MutableList<RendererdQuad> = mutableListOf() val quads: MutableList<RendererdQuad> = 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 addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) = Broken()
override fun addCache(cache: GUIMeshCache) = Broken() override fun addCache(cache: GUIMeshCache) = Broken()
override fun ensureSize(size: Int) = Unit override fun ensureSize(size: Int) = Unit

View File

@ -15,12 +15,13 @@ package de.bixilon.minosoft.gui.rendering.gui.mesh
import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.text.formatting.color.RGBColor 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.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem import de.bixilon.minosoft.gui.rendering.system.opengl.OpenGLRenderSystem
open class DummyGUIVertexConsumer : GUIVertexConsumer { open class DummyGUIVertexConsumer : GUIVertexConsumer {
override val order: IntArray get() = OpenGLRenderSystem.QUAD_ORDER override val order: RenderOrder get() = OpenGLRenderSystem.QUAD_ORDER
var char = 0 var char = 0
override fun addCache(cache: GUIMeshCache) { override fun addCache(cache: GUIMeshCache) {

View File

@ -11,19 +11,29 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * 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") @Test(groups = ["rendering"])
object ModelBakeUtil { class RenderOrderTest {
fun getTextureCoordinates(uvStart: Vec2, uvEnd: Vec2): Array<Vec2> { fun `simple iteration`() {
return arrayOf( val order = RenderOrder(intArrayOf(0, 9, 1, 8, 2, 7, 3, 6))
Vec2(uvEnd.x, uvStart.y),
uvStart, val result: MutableList<Int> = mutableListOf()
Vec2(uvStart.x, uvEnd.y), order.iterate { position, uv -> result += position; result += uv }
uvEnd,
) 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<Int> = mutableListOf()
order.iterateReverse { position, uv -> result += position; result += uv }
assertEquals(result, listOf(0, 9, 3, 6, 2, 7, 1, 8))
} }
} }

View File

@ -80,7 +80,7 @@ class DummyRenderSystem(
override var clearColor: RGBColor = Colors.TRANSPARENT override var clearColor: RGBColor = Colors.TRANSPARENT
override var quadType: PrimitiveTypes = PrimitiveTypes.QUAD 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 { override fun readPixels(start: Vec2i, end: Vec2i, type: PixelTypes): ByteBuffer {
TODO("Not yet implemented") TODO("Not yet implemented")

View File

@ -59,7 +59,7 @@ class WorldBorderMesh(
} }
private fun addVertexX(x: Float, width: Float, positions: Array<Vec2>, rotated: Boolean) { private fun addVertexX(x: Float, width: Float, positions: Array<Vec2>, 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 (z, y) = positions[index]
val texture = if (rotated) textureIndex(index + 1) else index + 1 val texture = if (rotated) textureIndex(index + 1) else index + 1
addVertex(x, y, z, textureIndex(texture), width) addVertex(x, y, z, textureIndex(texture), width)
@ -73,7 +73,7 @@ class WorldBorderMesh(
} }
private fun addVertexZ(z: Float, width: Float, positions: Array<Vec2>, rotated: Boolean) { private fun addVertexZ(z: Float, width: Float, positions: Array<Vec2>, 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 (x, y) = positions[index]
val texture = if (rotated) textureIndex(index + 1) else index + 1 val texture = if (rotated) textureIndex(index + 1) else index + 1
addVertex(x, y, z, textureIndex(texture), width) addVertex(x, y, z, textureIndex(texture), width)

View File

@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.RenderContext 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.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.buffer.vertex.PrimitiveTypes
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
@ -62,19 +63,19 @@ class SingleChunkMesh(context: RenderContext, initialCacheSize: Int, onDemand: B
} }
companion object { companion object {
val TRIANGLE_ORDER = intArrayOf( val TRIANGLE_ORDER = RenderOrder(intArrayOf(
0, 0, 0, 0,
3, 3, 3, 3,
2, 2, 2, 2,
2, 2, 2, 2,
1, 1, 1, 1,
0, 0, 0, 0,
) ))
val QUAD_ORDER = intArrayOf( val QUAD_ORDER = RenderOrder(intArrayOf(
0, 0, 0, 0,
3, 3, 3, 3,
2, 2, 2, 2,
1, 1, 1, 1,
) ))
} }
} }

View File

@ -248,13 +248,9 @@ class FluidSectionMesher(
} }
} }
private inline fun addFluidVertices(meshToUse: SingleChunkMesh, positions: Array<Vec3>, texturePositions: Array<Vec2>, flowingTexture: Texture, fluidTint: Int, fluidLight: Int) { private inline fun addFluidVertices(mesh: SingleChunkMesh, positions: Array<Vec3>, texturePositions: Array<Vec2>, flowingTexture: Texture, fluidTint: Int, fluidLight: Int) {
for (index in 0 until meshToUse.order.size step 2) { mesh.order.iterate { position, uv -> mesh.addVertex(positions[position].array, texturePositions[uv], flowingTexture, fluidTint, fluidLight) }
meshToUse.addVertex(positions[meshToUse.order[index]].array, texturePositions[meshToUse.order[index + 1]], flowingTexture, fluidTint, fluidLight) mesh.order.iterateReverse { position, uv -> mesh.addVertex(positions[position].array, texturePositions[uv], 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 fun getCornerHeight(providedChunk: Chunk, providedChunkPosition: Vec2i, position: Vec3i, fluid: Fluid): Float { private fun getCornerHeight(providedChunk: Chunk, providedChunkPosition: Vec2i, position: Vec3i, fluid: Fluid): Float {

View File

@ -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.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions 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.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
class WorldGUIConsumer(val mesh: SingleChunkMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer { class WorldGUIConsumer(val mesh: SingleChunkMesh, val transform: Mat4, val light: Int) : GUIVertexConsumer {
private val whiteTexture = mesh.context.textures.whiteTexture 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?) { 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) 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), Vec2(uvStart.x, uvEnd.y),
) )
for (index in 0 until order.size step 2) { order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) }
addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options)
}
} }
override fun addCache(cache: GUIMeshCache) { override fun addCache(cache: GUIMeshCache) {

View File

@ -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, 0.0f),
Vec2(+1.0f, -1.0f) to Vec2(1.0f, 1.0f), Vec2(+1.0f, -1.0f) to Vec2(1.0f, 1.0f),
) )
for (index in 0 until order.size step 2) { order.iterate { position, uv -> addVertex(vertices[position].first, vertices[uv].second) }
addVertex(vertices[order[index]].first, vertices[order[index + 1]].second)
}
} }
private fun addVertex(position: Vec2, uv: Vec2) { private fun addVertex(position: Vec2, uv: Vec2) {

View File

@ -18,12 +18,13 @@ import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList
import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList
import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderContext 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.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class GUIMeshCache( class GUIMeshCache(
var halfSize: Vec2, var halfSize: Vec2,
override val order: IntArray, override val order: RenderOrder,
val context: RenderContext, val context: RenderContext,
initialCacheSize: Int = 1000, initialCacheSize: Int = 1000,
var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize), var data: AbstractFloatList = HeapArrayFloatList(initialCacheSize),

View File

@ -17,12 +17,13 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.minosoft.data.text.formatting.color.RGBColor 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.FontProperties
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties 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.TexturePart
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture 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.base.texture.texture.Texture
interface GUIVertexConsumer { interface GUIVertexConsumer {
val order: IntArray val order: RenderOrder
fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
@ -43,9 +44,7 @@ interface GUIVertexConsumer {
uvEnd, uvEnd,
) )
for (index in 0 until order.size step 2) { order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) }
addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options)
}
} }
fun addQuad(start: Vec2, end: Vec2, texture: TexturePart, tint: RGBColor, options: GUIVertexOptions?) { fun addQuad(start: Vec2, end: Vec2, texture: TexturePart, tint: RGBColor, options: GUIVertexOptions?) {
@ -73,9 +72,7 @@ interface GUIVertexConsumer {
uvEnd, uvEnd,
) )
for (index in 0 until order.size step 2) { order.iterate { position, uv -> addVertex(positions[position], texture, texturePositions[uv], tint, options) }
addVertex(positions[order[index]], texture, texturePositions[order[index + 1]], tint, options)
}
} }
fun addCache(cache: GUIMeshCache) fun addCache(cache: GUIMeshCache)

View File

@ -53,12 +53,9 @@ class BakedFace(
val mesh = mesh.mesh(texture) val mesh = mesh.mesh(texture)
mesh.data.ensureSize(SingleChunkMesh.WorldMeshStruct.FLOATS_PER_VERTEX * (mesh.order.size / 2)) mesh.data.ensureSize(SingleChunkMesh.WorldMeshStruct.FLOATS_PER_VERTEX * (mesh.order.size / 2))
var index = 0 mesh.order.iterate { position, uv ->
val size = mesh.order.size val vertexOffset = position * 3
while (index < size) { val uvOffset = uv * 2
val vertexOffset = mesh.order[index] * 3
val uvOffset = mesh.order[index + 1] * 2
mesh.addVertex( mesh.addVertex(
x = offset[0] + positions[vertexOffset], y = offset[1] + positions[vertexOffset + 1], z = offset[2] + positions[vertexOffset + 2], x = offset[0] + positions[vertexOffset], y = offset[1] + positions[vertexOffset + 1], z = offset[2] + positions[vertexOffset + 2],
u = this.uv[uvOffset], u = this.uv[uvOffset],
@ -66,7 +63,6 @@ class BakedFace(
shaderTextureId = textureId, shaderTextureId = textureId,
lightTint = lightTint, lightTint = lightTint,
) )
index += 2
} }
} }

View File

@ -33,9 +33,9 @@ class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context
val transform = transform.buffer() val transform = transform.buffer()
val textureShaderId = texture.shaderId.buffer() val textureShaderId = texture.shaderId.buffer()
for (index in 0 until order.size step 2) { order.iterate { position, uvIndex ->
val indexPosition = positions[order[index]].array val indexPosition = positions[position].array
val transformedUV = texture.transformUV(uv[order[index + 1]]) val transformedUV = texture.transformUV(uv[uvIndex])
addVertex(indexPosition, transformedUV, transform, textureShaderId) addVertex(indexPosition, transformedUV, transform, textureShaderId)
} }
} }

View File

@ -33,8 +33,8 @@ import java.util.concurrent.atomic.AtomicInteger
data class SkeletalModel( data class SkeletalModel(
val elements: Map<String, SkeletalElement>, val elements: Map<String, SkeletalElement>,
val textures: Map<ResourceLocation, SkeletalTexture>, val textures: Map<ResourceLocation, SkeletalTexture>,
val animations: Map<String, SkeletalAnimation>, val animations: Map<String, SkeletalAnimation> = emptyMap(),
val transforms: Map<String, SkeletalTransform>, val transforms: Map<String, SkeletalTransform> = emptyMap(),
) { ) {
val loadedTextures: MutableMap<ResourceLocation, SkeletalTextureInstance> = mutableMapOf() val loadedTextures: MutableMap<ResourceLocation, SkeletalTextureInstance> = mutableMapOf()

View File

@ -14,13 +14,13 @@
package de.bixilon.minosoft.gui.rendering.skeletal.model.elements package de.bixilon.minosoft.gui.rendering.skeletal.model.elements
import de.bixilon.kotlinglm.GLM import de.bixilon.kotlinglm.GLM
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.Axes import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.ResourceLocation 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.ModelElement.Companion.BLOCK_SIZE
import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV 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.skeletal.baked.SkeletalBakeContext
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
@ -29,12 +29,21 @@ data class SkeletalFace(
val texture: ResourceLocation? = null, val texture: ResourceLocation? = null,
) { ) {
private fun getTexturePositions(uvStart: Vec2, uvEnd: Vec2): Array<Vec2> {
return arrayOf(
Vec2(uvEnd.x, uvStart.y),
uvStart,
Vec2(uvStart.x, uvEnd.y),
uvEnd,
)
}
fun bake(context: SkeletalBakeContext, direction: Directions, element: SkeletalElement, transform: Int) { 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 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 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) { for (rotation in context.rotations) {

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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
}
}
}

View File

@ -102,7 +102,7 @@ interface RenderSystem {
var clearColor: RGBColor var clearColor: RGBColor
var quadType: PrimitiveTypes var quadType: PrimitiveTypes
var quadOrder: IntArray var quadOrder: RenderOrder
fun readPixels(start: Vec2i, end: Vec2i, type: PixelTypes): ByteBuffer fun readPixels(start: Vec2i, end: Vec2i, type: PixelTypes): ByteBuffer

View File

@ -69,7 +69,7 @@ class OpenGLRenderSystem(
} else { } else {
PrimitiveTypes.TRIANGLE 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 boundVao = -1
var boundBuffer = -1 var boundBuffer = -1
var uniformBufferBindingIndex = 0 var uniformBufferBindingIndex = 0
@ -328,7 +328,7 @@ class OpenGLRenderSystem(
} }
companion object { 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 // TOOD: they are all rotated 90° wrong, fix this for triangle and quad order
0, 1, 0, 1,
3, 2, 3, 2,
@ -336,13 +336,13 @@ class OpenGLRenderSystem(
2, 3, 2, 3,
1, 0, 1, 0,
0, 1, 0, 1,
) ))
val QUAD_ORDER = intArrayOf( val QUAD_ORDER = RenderOrder(intArrayOf(
0, 1, 0, 1,
3, 2, 3, 2,
2, 3, 2, 3,
1, 0, 1, 0,
) ))
private val RenderingCapabilities.gl: Int private val RenderingCapabilities.gl: Int
get() { get() {

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.gui.rendering.util.mesh package de.bixilon.minosoft.gui.rendering.util.mesh
import de.bixilon.minosoft.gui.rendering.system.base.RenderOrder
interface AbstractVertexConsumer { interface AbstractVertexConsumer {
val order: IntArray val order: RenderOrder
} }

View File

@ -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 + 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), 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) { order.iterate { position, uv -> addVertex(positions[position], color) }
addVertex(positions[order[index]], color)
}
} }
fun drawAABB(aabb: AABB, position: Vec3d, lineWidth: Float, color: RGBColor, margin: Float = 0.0f, shape: AbstractVoxelShape? = null) { 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 val offset = context.camera.offset.offset
for (direction in Directions.VALUES) { for (direction in Directions.VALUES) {
val positions = direction.getPositions(Vec3(aabb.min - offset), Vec3(aabb.max - offset)) 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) }
}
} }
} }

View File

@ -126,10 +126,7 @@ abstract class Mesh(
uvEnd, uvEnd,
Vec2(uvEnd.x, uvStart.y), Vec2(uvEnd.x, uvStart.y),
) )
order.iterate { position, uv -> vertexConsumer.invoke(positions[position], texturePositions[uv]) }
for (index in 0 until order.size step 2) {
vertexConsumer.invoke(positions[order[index]], texturePositions[order[index + 1]])
}
} }
enum class MeshStates { enum class MeshStates {