Попытка реализовать IItemRenderer

Версия Minecraft
1.10.2
7,099
324
1,510
Понадобилось рисовать модель предмета так, чтобы можно было максимально свободно управлять отрисовкой. Это позволял делать IItemRenderer из 1.7.10.
Основная идея исходит из этого кода майна:
Java:
//net.minecraft.client.renderer.RenderItem

IBakedModel ibakedmodel = this.getItemModelWithOverrides(stack, entitylivingbaseIn.world, entitylivingbaseIn);
this.renderItemModel(stack, ibakedmodel, transform, leftHanded);

//getItemModelWithOverrides
return ibakedmodel.getOverrides().[COLOR=rgb(65, 168, 95)]handleItemState[/COLOR](ibakedmodel, stack, worldIn, entitylivingbaseIn);

//renderItemModel
GlStateManager.pushMatrix();
bakedmodel = net.minecraftforge.client.ForgeHooksClient.handleCameraTransforms(bakedmodel, transform, leftHanded);
GlStateManager.popMatrix();

//ForgeHooksClient#[COLOR=rgb(65, 168, 95)]handleCameraTransforms[/COLOR]
Pair<? extends IBakedModel, Matrix4f> pair = ((IPerspectiveAwareModel)model).[COLOR=rgb(65, 168, 95)]handlePerspective[/COLOR](cameraTransformType);
GlStateManager.popMatrix();
Зеленым помечены методы, которые нам интересны.
Сначала вызывается handleItemState и туда передается стак, мир и сущность, что держит предмет
После вызывается handlePerspective и туда предается cameraTransform
Кроме того, handleCameraTransforms находится между "скобками" push/popMatrix и там рядом отрисовывается ванильная модель, а значит, мы можем в метод handlePerspective нашей модели вставить код, рисующий то, че нам нужно.

Вот, че у мя получилось(весь код из 1.10.2, но, можно юзать и на более новых, возможно, с небольшими изменениями):
Scala:
abstract class IItemRenderer{
  val mc: Minecraft = Minecraft.getMinecraft
  val textureManager: TextureManager= mc.getTextureManager

  def render(cameraTransformType: TransformType,itemStack: ItemStack,entity: EntityLivingBase): Unit
}



class ItemRendererManager {
  val itemRendererIndex = new mutable.OpenHashMap[String,IItemRenderer]

  private val itemModelResourceLocation = new ModelResourceLocation(modId+":empty", "inventory")



  def registerItemRenderer(item: Item, itemRender: IItemRenderer): Unit = {
    itemRendererIndex += getItemName(item)->itemRender

    Minecraft.getMinecraft.getRenderItem.getItemModelMesher.register(item, 0, itemModelResourceLocation)
  }



  @SubscribeEvent def bakeModel(event: ModelBakeEvent): Unit = {
      event.getModelRegistry.putObject(itemModelResourceLocation, new WrappedModel(itemRendererIndex))
  }



  class WrappedModel(itemRendererIndex: mutable.OpenHashMap[String, IItemRenderer]) extends IBakedModel  with IPerspectiveAwareModel{
    var _entity:EntityLivingBase = null
    var _itemStack:ItemStack = null

    override def handlePerspective(cameraTransformType: TransformType): tuple.Pair[_ <: IBakedModel, Matrix4f] = {
      val itemCameraTransforms = getItemCameraTransforms
      val itemTransformVec3f = itemCameraTransforms.getTransform(cameraTransformType)
      val tr = new TRSRTransformation(itemTransformVec3f)
      val mat = tr.getMatrix

      GlStateManager.pushMatrix()
      GlStateManager.translate(0.5F, 0.5F, 0.5F)
      GlStateManager.scale(1.0F, 1.0F, 1.0F)

      itemRendererIndex.get(getItemName(_itemStack)).foreach(_.render(cameraTransformType,_itemStack,_entity))

      _itemStack=null
      _entity=null

      GlStateManager.popMatrix()

      org.apache.commons.lang3.tuple.Pair.of(this, mat)
    }

    override def getOverrides: ItemOverrideList = ItemStackCollectorItemOverrideList

    object ItemStackCollectorItemOverrideList extends ItemOverrideList(Collections.emptyList()) {
      override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = {
        _itemStack=stack
        _entity=entity

        super.handleItemState(originalModel,stack,world,entity)

      }

    }

    val mc: Minecraft = Minecraft.getMinecraft

    val textureManager: TextureManager= mc.getTextureManager

    override def isAmbientOcclusion = true

    override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = Collections.emptyList()

    override def isBuiltInRenderer: Boolean = false

    override def getParticleTexture: TextureAtlasSprite = mc.getTextureMapBlocks.getMissingSprite

    override def isGui3d: Boolean = true

    override def getItemCameraTransforms: ItemCameraTransforms = ItemCameraTransforms.DEFAULT
  }

  @inline private def getItemName(item: Item):String = item.delegate.name().toString

  @inline private def getItemName(itemStack: ItemStack):String = getItemName(itemStack.getItem)

}
Если кому хочется на весь экран: [Scala] abstract class IItemRenderer{ val mc: Minecraft = Minecraft.getMinecraf - Pastebin.com
Регать так:
Scala:
val itemRendererManager=new ItemRendererManager
MinecraftForge.EVENT_BUS.register(itemRendererManager)
itemRendererManager.registerItemRenderer(ItemTest,new TestRenderer())

А теперь вопрос и проблема:
когда в пределах одного гуи в слотах после моего предмета лежат предметы с полупрозрачной(жидкости, например) или зачарованной текстурой, то эти предметы выглядят темнее(зачарованные полностью черные, но мерцают). На месте слота левой руки какая-то хрень.
При этом, если навести на слот после моего предмета, то хрень исчезает ,а выделенный слот подсвечивается чисто-белым.
Скрины:
1517508831763.png
1517508997988.png
1517509019222.png
Есть у кого какие идеи, в чем причина и как исправить?
Мне кажется, это связано со слоями, но я их не юзал никогда и понимаю их смысл интуитивно( не помню, откуда узнал) и поэтому нуждаюсь в помощи.
Заранее спасибо, и надеюсь, эта тема пригодится другим(привет, @Agravaine :))
 
Последнее редактирование:
Сверху