multi layer item rendering

This commit is contained in:
Moritz Zwerger 2023-11-27 14:58:06 +01:00
parent f10184bad6
commit 064d384e30
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 59 additions and 28 deletions

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.registries.blocks.types.properties.item.BlockWit
import de.bixilon.minosoft.data.registries.blocks.types.properties.offset.RandomOffsetBlock
import de.bixilon.minosoft.data.registries.blocks.types.properties.offset.RandomOffsetTypes
import de.bixilon.minosoft.data.registries.blocks.types.properties.shape.outline.OutlinedBlock
import de.bixilon.minosoft.data.registries.identified.AliasedIdentified
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.item.items.Item
@ -58,8 +59,9 @@ abstract class FernBlock(identifier: ResourceLocation, settings: BlockSettings)
override val legacyModelName get() = minecraft("tall_grass")
override val tintProvider: TintProvider? = null
companion object : BlockFactory<Grass> {
companion object : BlockFactory<Grass>, AliasedIdentified {
override val identifier = minecraft("grass")
override val identifiers = setOf(minecraft("short_grass"))
override fun build(registries: Registries, settings: BlockSettings) = Grass(settings = settings)
}

View File

@ -32,7 +32,7 @@ class BakedModel(
val faces: Array<Array<BakedFace>>,
val properties: Array<SideProperties?>,
val display: Map<DisplayPositions, ModelDisplay>?,
val particle: Texture?,
override val particle: Texture?,
) : BlockRender {
init {

View File

@ -17,6 +17,8 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.chunk.mesh.BlockVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement
@ -27,14 +29,22 @@ import de.bixilon.minosoft.gui.rendering.models.util.CuboidUtil
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
class FlatItemRender(val texture: Texture) : ItemRender {
class FlatItemRender(
val layers: Array<Texture>,
override val particle: Texture?,
) : ItemRender {
override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) {
ImageElement(gui, texture, size = size).render(offset, consumer, options)
for ((index, layer) in layers.withIndex()) {
val tint = tints?.get(index)?.let { RGBColor(it shl 8) } ?: ChatColors.WHITE
ImageElement(gui, layer, size = size, tint = tint).render(offset, consumer, options)
}
}
override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) {
mesh.addQuad(POSITIONS, UV, texture.shaderId.buffer(), (tints?.get(0) ?: 0xFFFFFF).buffer())
for ((index, layer) in layers.withIndex()) {
mesh.addQuad(POSITIONS, UV, layer.shaderId.buffer(), (tints?.get(index) ?: 0xFFFFFF).buffer())
}
// TODO: items have depth
// TODO: light, ...
}

View File

@ -19,9 +19,9 @@ import de.bixilon.minosoft.gui.rendering.models.block.BlockModel
import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions
import de.bixilon.minosoft.gui.rendering.models.raw.display.ModelDisplay
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.get
class ItemModel(
val display: Map<DisplayPositions, ModelDisplay>? = null,
@ -30,9 +30,20 @@ class ItemModel(
fun load(textures: TextureManager): ItemModelPrototype? {
if (this.textures == null) return null
val texture = this.textures["layer0", "particle"]?.toResourceLocation()?.texture() ?: return null
val particle = this.textures["particle"]?.let { textures.static.create(it.toResourceLocation().texture()) }
return ItemModelPrototype(textures.static.create(texture))
val layers: MutableList<IndexedValue<Texture>> = mutableListOf()
for ((key, texture) in this.textures) {
if (!key.startsWith("layer")) continue
val index = key.removePrefix("layer").toInt()
layers += IndexedValue(index, textures.static.create(texture.toResourceLocation().texture()))
}
if (layers.isEmpty()) return null
layers.sortBy { it.index }
val array = layers.map { it.value }.toTypedArray()
return ItemModelPrototype(array, particle)
}
companion object {
@ -46,4 +57,5 @@ class ItemModel(
return ItemModel(display, textures)
}
}
}

View File

@ -22,7 +22,8 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
class ItemModelPrototype(
private var texture: Texture,
private var layers: Array<Texture>,
override val particle: Texture?,
) : ItemRender {
override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = prototype()
override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = prototype()
@ -32,6 +33,6 @@ class ItemModelPrototype(
fun bake(): ItemRender {
return FlatItemRender(this.texture)
return FlatItemRender(this.layers, this.particle)
}
}

View File

@ -21,8 +21,10 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions
import de.bixilon.minosoft.gui.rendering.models.raw.display.ModelDisplay
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
interface ItemRender {
val particle: Texture? get() = null
fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?)
fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?)

View File

@ -147,26 +147,30 @@ class PlayInByteBuffer : InByteBuffer {
return readNBTTag(versionId < V_14W28B, versionId < V_23W31A)
}
private fun readLegacyItemStack(): ItemStack? {
val id = readShort().toInt()
if (id <= ProtocolDefinition.AIR_BLOCK_ID) {
return null
}
val count = readUnsignedByte()
var meta = 0
if (!connection.version.flattened) {
meta = readUnsignedShort()
}
val nbt = readNBT()?.toMutableJsonObject()
val item = connection.registries.item.getOrNull(id shl 16 or meta) ?: return null // TODO: only if item is not an ItemWithMeta
return ItemStackUtil.of(
item = item,
connection = connection,
count = count,
meta = meta,
nbt = nbt ?: mutableMapOf(),
)
}
fun readItemStack(): ItemStack? {
if (versionId < V_1_13_2_PRE1) {
val id = readShort().toInt()
if (id <= ProtocolDefinition.AIR_BLOCK_ID) {
return null
}
val count = readUnsignedByte()
var meta = 0
if (!connection.version.flattened) {
meta = readUnsignedShort()
}
val nbt = readNBT()?.toMutableJsonObject()
val item = connection.registries.item.getOrNull(id shl 16 or meta) ?: return null // TODO: only if item is not an ItemWithMeta
return ItemStackUtil.of(
item = item,
connection = connection,
count = count,
meta = meta,
nbt = nbt ?: mutableMapOf(),
)
return readLegacyItemStack()
}
return readOptional {