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.RandomOffsetBlock
import de.bixilon.minosoft.data.registries.blocks.types.properties.offset.RandomOffsetTypes 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.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.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.item.items.Item 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 legacyModelName get() = minecraft("tall_grass")
override val tintProvider: TintProvider? = null override val tintProvider: TintProvider? = null
companion object : BlockFactory<Grass> { companion object : BlockFactory<Grass>, AliasedIdentified {
override val identifier = minecraft("grass") override val identifier = minecraft("grass")
override val identifiers = setOf(minecraft("short_grass"))
override fun build(registries: Registries, settings: BlockSettings) = Grass(settings = settings) override fun build(registries: Registries, settings: BlockSettings) = Grass(settings = settings)
} }

View File

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

View File

@ -17,6 +17,8 @@ import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.data.direction.Directions 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.chunk.mesh.BlockVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer import de.bixilon.minosoft.gui.rendering.gui.GUIRenderer
import de.bixilon.minosoft.gui.rendering.gui.elements.primitive.ImageElement 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.MeshUtil.buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture 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?) { 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?) { 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: items have depth
// TODO: light, ... // 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.DisplayPositions
import de.bixilon.minosoft.gui.rendering.models.raw.display.ModelDisplay 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.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.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.get
class ItemModel( class ItemModel(
val display: Map<DisplayPositions, ModelDisplay>? = null, val display: Map<DisplayPositions, ModelDisplay>? = null,
@ -30,9 +30,20 @@ class ItemModel(
fun load(textures: TextureManager): ItemModelPrototype? { fun load(textures: TextureManager): ItemModelPrototype? {
if (this.textures == null) return null 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 { companion object {
@ -46,4 +57,5 @@ class ItemModel(
return ItemModel(display, textures) 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 import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
class ItemModelPrototype( class ItemModelPrototype(
private var texture: Texture, private var layers: Array<Texture>,
override val particle: Texture?,
) : ItemRender { ) : ItemRender {
override fun render(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?) = prototype() 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() override fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) = prototype()
@ -32,6 +33,6 @@ class ItemModelPrototype(
fun bake(): ItemRender { 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.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions 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.models.raw.display.ModelDisplay
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
interface ItemRender { 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(gui: GUIRenderer, offset: Vec2, consumer: GUIVertexConsumer, options: GUIVertexOptions?, size: Vec2, stack: ItemStack, tints: IntArray?)
fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?) fun render(mesh: BlockVertexConsumer, stack: ItemStack, tints: IntArray?)

View File

@ -147,8 +147,7 @@ class PlayInByteBuffer : InByteBuffer {
return readNBTTag(versionId < V_14W28B, versionId < V_23W31A) return readNBTTag(versionId < V_14W28B, versionId < V_23W31A)
} }
fun readItemStack(): ItemStack? { private fun readLegacyItemStack(): ItemStack? {
if (versionId < V_1_13_2_PRE1) {
val id = readShort().toInt() val id = readShort().toInt()
if (id <= ProtocolDefinition.AIR_BLOCK_ID) { if (id <= ProtocolDefinition.AIR_BLOCK_ID) {
return null return null
@ -169,6 +168,11 @@ class PlayInByteBuffer : InByteBuffer {
) )
} }
fun readItemStack(): ItemStack? {
if (versionId < V_1_13_2_PRE1) {
return readLegacyItemStack()
}
return readOptional { return readOptional {
ItemStackUtil.of( ItemStackUtil.of(
item = connection.registries.item[readVarInt()], item = connection.registries.item[readVarInt()],