Monday, 19 August 2013

Rendering Dropped Items

Dropped Items are stored in the game world as an Entity (EntityItem) which has an associated [x,y,z] position.  As described in the Rendering Items overview, there are a number of different ways that Dropped Items can be rendered.  These are summarised in the diagram below.

The render starts in RenderManager.renderEntityWithPosYaw(), which draws the Entity at a given position with a given yaw angle (you have probably noticed that most dropped items slowly rotate around the y axis, this rotation is called yaw).

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: if fancy graphics are off (yellow pickaxe), RenderItem.renderDroppedItem() just draws the Item's getIcon() directly onto the screen.
  • If fancy graphics are on (purple pickaxe), ItemRenderer.renderItemIn2D() is used to render the Item's .getIcon() as a 2D sheet with "thickness".

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, also sample code here.
    Use [-0.5, -0.5, -0.5] to [0.5,0.5,0.5] 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 dropped items.