Thursday, 22 August 2013

Rendering Inventory Items

There are several different ways to render Inventory Items.  The parts of the code that do this are summarised in the diagram below.  If you aren't really interested in the details, you may as well jump straight to the sample code.

The top level is GuiContainer.drawScreen (and a couple of other methods in this class) which call
RenderItem.renderItemAndEffectIntoGUI().  This renders the item itself, and is followed by a call to renderItemOverlayIntoGUI, which adds the item count for multiple items (eg stack of 64 dirt) and the damage bar for damaged items (.isItemDamaged() and .getItemDamageForDisplay()).

Vanilla items:

  • Items which are also 3D Blocks (eg TNT, Dirt) are typically rendered in RenderBlocks.renderBlockAsItem. If the block's RenderType is 0 (default), then the block is drawn as a standard cube, using .getBlockTexture for each side. For unusual blocks (RenderType != 0), there is a massive switch() statement in .renderBlockAsItem() which selects the correct Tessellator commands.
  • There are some unusual 3D blocks (eg Bed) which render in 2D like an item. These Blocks override RenderBlocks.renderItemIn3D() to return false.
  • For non-block items (eg pickaxe), RenderBlocks.renderItemIntoGUI just draws the Item's getIcon() directly onto the screen.

Custom items:

  • If your item is simple, you can just provide an appropriate Icon or BlockTexture and it will render the same as vanilla items.
  • If your item is a custom block, you will probably have given it a special Block renderType to render it correctly. In this case, you can add code to your custom Renderer which implements ISimpleBlockRenderingHandler.renderInventoryBlock(). See .renderBlockAsItem for plenty of vanilla code showing how to render them. Use [0,0,0] to [1,1,1] as the extent of the block, it has already been scaled, rotated, and translated appropriately. If you tessellate directly, do not forget to .setNormal() to match each face otherwise the lighting will look strange. (See .renderBlockAsItem).
  • An alternative way to render custom items is to use a custom renderer implementing IItemRenderer. This same interface is used for all the different ways an item can render; it is quite complicated so I have covered it separately here.
Code tree showing the various places that different types of item renders are performed for Inventory items.