diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt index 63cd9585d..f278ab820 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt @@ -54,7 +54,7 @@ object BakedModelTestUtil { } fun BakedModel.assertFace(direction: Directions, positions: FloatArray, uv: FloatArray, shade: Float, texture: String? = null) { - val faces = this.face[direction.ordinal] + val faces = this.faces[direction.ordinal] if (faces.size != 1) throw IllegalArgumentException("Model has more/less than once face!") val face = faces.first() diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/state/BlockState.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/state/BlockState.kt index d72db9e7e..0b5c30af9 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/state/BlockState.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/state/BlockState.kt @@ -17,13 +17,13 @@ import de.bixilon.minosoft.data.registries.blocks.state.builder.BlockStateSettin import de.bixilon.minosoft.data.registries.blocks.state.error.StatelessBlockError import de.bixilon.minosoft.data.registries.blocks.types.Block import de.bixilon.minosoft.data.registries.identified.ResourceLocation -import de.bixilon.minosoft.gui.rendering.models.block.legacy.BakedBlockModel +import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender open class BlockState( val block: Block, val luminance: Int, ) { - var model: BakedBlockModel? = null + var model: BlockRender? = null constructor(block: Block, settings: BlockStateSettings) : this(block, settings.luminance) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockStateModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockStateModel.kt deleted file mode 100644 index b31fb716f..000000000 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockStateModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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.models.block.legacy - -@Deprecated("legacy") - -interface BakedBlockStateModel : BakedBlockModel diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/SingleBlockRenderable.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/SingleBlockRenderable.kt deleted file mode 100644 index 1b46d92b3..000000000 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/SingleBlockRenderable.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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.models.block.legacy - -@Deprecated("legacy") -interface SingleBlockRenderable diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt index 989468f9d..837b7f5d7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.apply import de.bixilon.kutil.json.JsonObject import de.bixilon.kutil.primitive.BooleanUtil.toBoolean import de.bixilon.kutil.primitive.IntUtil.toInt +import de.bixilon.minosoft.data.Axes import de.bixilon.minosoft.data.direction.DirectionUtil.rotateY import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.gui.rendering.models.block.BlockModel @@ -55,19 +56,19 @@ data class SingleBlockStateApply( val positions = positions(rotatedDirection, element.from, element.to) - var uv = face.uv.toArray(direction, face.rotation) - if (y != 0 && !uvLock) { + var uv = face.uv.toArray(rotatedDirection, face.rotation) + if (direction.axis == Axes.Y && y != 0 && !uvLock) { uv = uv.pushRight(2, if (rotatedDirection.negative) -y else y) } - val shade = direction.shade + val shade = rotatedDirection.shade val bakedFace = BakedFace(positions, uv, shade, face.tintIndex, face.cull, texture) - bakedFaces[direction.ordinal] += bakedFace + bakedFaces[rotatedDirection.ordinal] += bakedFace } } - return BakedModel(bakedFaces.compact(), emptyArray()) + return BakedModel(bakedFaces.compact(), emptyArray(), null) // TODO } companion object { 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 093a858a1..488697c1d 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 @@ -13,8 +13,14 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked +import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.minosoft.data.direction.Directions +import de.bixilon.minosoft.data.text.formatting.color.RGBColor +import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture +import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rgb +import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh +import de.bixilon.minosoft.gui.rendering.world.preparer.cull.SolidCullSectionPreparer.Companion.SELF_LIGHT_INDEX class BakedFace( val positions: FloatArray, @@ -23,4 +29,38 @@ class BakedFace( val tintIndex: Int, val cull: Directions?, val texture: AbstractTexture, -) +) { + private var cullIndex = cull?.ordinal ?: SELF_LIGHT_INDEX + + private fun color(tint: Int): Int { + val color = Vec3(this.shade) + if (tint > 0) { + color.r *= (tint shr 16) / RGBColor.COLOR_FLOAT_DIVIDER + color.g *= ((tint shr 8) and 0xFF) / RGBColor.COLOR_FLOAT_DIVIDER + color.b *= (tint and 0xFF) / RGBColor.COLOR_FLOAT_DIVIDER + } + return color.rgb + } + + fun render(offset: FloatArray, mesh: WorldMesh, light: ByteArray, tints: IntArray?) { + val tint = color(tints?.getOrNull(tintIndex) ?: 0) + val tintLight = ((light[cullIndex].toInt() shl 24) or tint).buffer() + val textureId = this.texture.shaderId.buffer() + + + val mesh = mesh.opaqueMesh!! // TODO: use correct mesh + + for ((vertexIndex, textureIndex) in mesh.order) { + val vertexOffset = vertexIndex * 3 + val uvOffset = textureIndex * 2 + + mesh.addVertex( + x = offset[0] + positions[vertexOffset], y = offset[1] + positions[vertexOffset + 1], z = offset[2] + positions[vertexOffset + 2], + uv = floatArrayOf(uv[uvOffset], uv[uvOffset + 1]), + texture = this.texture, + shaderTextureId = textureId, + tintLight = tintLight, + ) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt index 880dccacd..cd61ef993 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt @@ -13,7 +13,38 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked +import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.minosoft.data.registries.blocks.state.BlockState +import de.bixilon.minosoft.data.world.positions.BlockPosition +import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender +import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture +import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3 +import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh +import java.util.* + class BakedModel( - val face: Array>, + val faces: Array>, val sizes: Array, -) + val particle: AbstractTexture?, +) : BlockRender { + + override fun getParticleTexture(random: Random, position: Vec3i) = particle + + override fun render(position: BlockPosition, mesh: WorldMesh, random: Random, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { + val float = position.toVec3 + + val array = float.array + + var rendered = true + + for ((index, faces) in faces.withIndex()) { + for (face in faces) { + face.render(array, mesh, light, tints) + + rendered = true + } + } + + return rendered + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt similarity index 67% rename from src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockModel.kt rename to src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt index 9bde48cb5..84e729259 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/legacy/BakedBlockModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/render/BlockRender.kt @@ -11,14 +11,17 @@ * 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.models.block.state.render import de.bixilon.kotlinglm.vec3.Vec3i +import de.bixilon.minosoft.data.registries.blocks.state.BlockState +import de.bixilon.minosoft.data.world.positions.BlockPosition import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture +import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh import java.util.* -@Deprecated("legacy") -interface BakedBlockModel { +interface BlockRender { + fun getParticleTexture(random: Random, position: Vec3i): AbstractTexture? = null - fun getParticleTexture(random: Random, position: Vec3i): AbstractTexture? + fun render(position: BlockPosition, mesh: WorldMesh, random: Random, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/MeshedBlockEntityRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/MeshedBlockEntityRenderer.kt index 7d840ae2c..1bc26bb9b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/MeshedBlockEntityRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/entities/MeshedBlockEntityRenderer.kt @@ -15,9 +15,9 @@ package de.bixilon.minosoft.gui.rendering.world.entities import de.bixilon.minosoft.data.entities.block.BlockEntity import de.bixilon.minosoft.gui.rendering.RenderContext -import de.bixilon.minosoft.gui.rendering.models.block.legacy.SingleBlockRenderable +import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender -interface MeshedBlockEntityRenderer : BlockEntityRenderer, SingleBlockRenderable { +interface MeshedBlockEntityRenderer : BlockEntityRenderer, BlockRender { override var light: Int get() = 0 set(value) {} 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 1e7161518..a9a930c84 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 @@ -26,6 +26,8 @@ import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties.Companion.getFacing import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.registries.blocks.state.PropertyBlockState +import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.entity.sign.StandingSignBlock +import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.entity.sign.WallSignBlock import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.font.Font import de.bixilon.minosoft.gui.rendering.font.renderer.ChatComponentRenderer @@ -35,6 +37,8 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign import de.bixilon.minosoft.gui.rendering.world.entities.OnlyMeshedBlockEntityRenderer import de.bixilon.minosoft.gui.rendering.world.mesh.SingleWorldMesh import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh +import de.bixilon.minosoft.gui.rendering.world.preparer.cull.SolidCullSectionPreparer.Companion.SELF_LIGHT_INDEX +import java.util.* class SignBlockEntityRenderer( val sign: SignBlockEntity, @@ -48,19 +52,16 @@ class SignBlockEntityRenderer( return rotation * 22.5f } - /* - override fun singleRender(position: Vec3i, mesh: WorldMesh, random: Random, blockState: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { + override fun render(position: Vec3i, mesh: WorldMesh, random: Random, state: BlockState, neighbours: Array, light: ByteArray, tints: IntArray?): Boolean { val block = this.blockState.block if (block is StandingSignBlock) { - renderStandingText(position, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt()) + renderStandingText(position, mesh, light[SELF_LIGHT_INDEX].toInt()) } else if (block is WallSignBlock) { - renderWallText(position, mesh, light[SolidCullSectionPreparer.SELF_LIGHT_INDEX].toInt()) + renderWallText(position, mesh, light[SELF_LIGHT_INDEX].toInt()) } return true } - // TODO - */ private fun renderText(position: Vec3i, rotationVector: Vec3, yRotation: Float, mesh: WorldMesh, light: Int) { val textPosition = position.toVec3 + rotationVector 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 7e6530e74..061e9d597 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 @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2022 Moritz Zwerger + * 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. * @@ -35,9 +35,9 @@ class SingleWorldMesh(context: RenderContext, initialCacheSize: Int, onDemand: B data.add((tintColor or (light shl 24)).buffer()) } - fun addVertex(x: Float, y: Float, z: Float, uv: Vec2, texture: AbstractTexture, shaderTextureId: Float, tintLight: Float) { + fun addVertex(x: Float, y: Float, z: Float, uv: FloatArray, texture: AbstractTexture, shaderTextureId: Float, tintLight: Float) { data.ensureSize(WorldMeshStruct.FLOATS_PER_VERTEX) - val transformedUV = texture.renderData.transformUV(uv.array) + val transformedUV = texture.renderData.transformUV(uv) data.add(x) data.add(y) data.add(z) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt index 8587ace61..c66ef51ea 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/preparer/cull/SolidCullSectionPreparer.kt @@ -34,7 +34,9 @@ import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbours import de.bixilon.minosoft.data.world.positions.BlockPosition import de.bixilon.minosoft.data.world.positions.BlockPositionUtil.positionHash import de.bixilon.minosoft.gui.rendering.RenderContext +import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender import de.bixilon.minosoft.gui.rendering.world.entities.BlockEntityRenderer +import de.bixilon.minosoft.gui.rendering.world.entities.MeshedBlockEntityRenderer import de.bixilon.minosoft.gui.rendering.world.entities.OnlyMeshedBlockEntityRenderer import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh import de.bixilon.minosoft.gui.rendering.world.preparer.SolidSectionPreparer @@ -66,7 +68,7 @@ class SolidCullSectionPreparer( val sectionLight = section.light val blockEntities: MutableSet> = mutableSetOf() var blockEntity: BlockEntity? - // var model: SingleBlockRenderable + var model: BlockRender var blockState: BlockState val position = BlockPosition() var rendered: Boolean @@ -104,13 +106,11 @@ class SolidCullSectionPreparer( blockEntities += blockEntityModel mesh.addBlock(x, y, z) } - /* model = blockState.model ?: if (blockEntityModel is MeshedBlockEntityRenderer) { blockEntityModel } else { continue } - */ if (y == 0) { if (fastBedrock && blockState === bedrock) { @@ -157,18 +157,16 @@ class SolidCullSectionPreparer( random.setSeed(0L) } tints = tintColorCalculator.getAverageBlockTint(chunk, neighbourChunks, blockState, x, y, z) - /* - rendered = model.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints) + rendered = model.render(position, mesh, random, blockState, neighbourBlocks, light, tints) if (blockEntityModel is MeshedBlockEntityRenderer<*>) { - rendered = blockEntityModel.singleRender(position, mesh, random, blockState, neighbourBlocks, light, tints) || rendered + rendered = blockEntityModel.render(position, mesh, random, blockState, neighbourBlocks, light, tints) || rendered } if (rendered) { mesh.addBlock(x, y, z) } - */ if (Thread.interrupted()) throw InterruptedException() } }