tutorial:blockentityrenderers
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
tutorial:blockentityrenderers [2021/05/18 05:20] – [Introduction] solidblock | tutorial:blockentityrenderers [2022/02/07 07:32] – solidblock | ||
---|---|---|---|
Line 7: | Line 7: | ||
Blocks by themselves aren't that interesting, | Blocks by themselves aren't that interesting, | ||
===== Example ===== | ===== Example ===== | ||
- | In this tutorial we'll build off the block entity we created by adding a '' | + | In this tutorial we'll build off the block entity we created by adding a '' |
- | The renderer will display a jukebox floating above the block, going up and down and spinning. | + | |
| | ||
The first thing we need to do is create our '' | The first thing we need to do is create our '' | ||
<code java> | <code java> | ||
- | public class MyBlockEntityRenderer | + | public class DemoBlockEntityRenderer< |
// A jukebox itemstack | // A jukebox itemstack | ||
private static ItemStack stack = new ItemStack(Items.JUKEBOX, | private static ItemStack stack = new ItemStack(Items.JUKEBOX, | ||
| | ||
- | public | + | public |
- | super(dispatcher); | + | |
- | | + | |
- | + | ||
@Override | @Override | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
Line 25: | Line 22: | ||
} | } | ||
</ | </ | ||
- | We're going to need to register our '' | + | We're going to need to register our '' |
- | This wouldn' | + | |
- | However, in a multiplayer setting, where the server runs in a different process than the client, the server code | + | |
- | has no concept of a " | + | |
- | To run initialization code only for the client, we need to setup a '' | + | |
- | Create a new class next to your main class that implements '' | + | Create a new class next to your main class that implements '' |
<code java> | <code java> | ||
public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
Line 47: | Line 40: | ||
" | " | ||
{ | { | ||
- | " | + | " |
} | } | ||
] | ] | ||
Line 57: | Line 50: | ||
@Override | @Override | ||
public void onInitializeClient() { | public void onInitializeClient() { | ||
- | BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, | + | BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, |
} | } | ||
</ | </ | ||
Line 67: | Line 60: | ||
} | } | ||
</ | </ | ||
- | We then perform the movement of the jukebox (matrices.translate) and rotation (matrices.multiply). | + | We then perform the movement of the jukebox (matrices.translate) and rotation (matrices.multiply). There are two parts to the translation: |
- | There are two parts to the translation: | + | |
- | The second part is the part that changes: the offset in the y value. The offset is the height of the item for any given frame. | + | |
- | We recalculate this each time because we want it to be animating bouncing up and down. We calculate this by: | + | |
* Getting the current world time, which changes over time. | * Getting the current world time, which changes over time. | ||
* Adding the partial ticks. (The partial ticks is a fractional value representing the amount of time that’s passed between the last full tick and now. We use this because otherwise the animation would be jittery because there are fewer ticks per second than frames per second.) | * Adding the partial ticks. (The partial ticks is a fractional value representing the amount of time that’s passed between the last full tick and now. We use this because otherwise the animation would be jittery because there are fewer ticks per second than frames per second.) | ||
Line 85: | Line 75: | ||
// Rotate the item | // Rotate the item | ||
- | matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion((blockEntity.getWorld().getTime() + tickDelta) * 4)); | + | matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion((blockEntity.getWorld().getTime() + tickDelta) * 4)); |
} | } | ||
</ | </ | ||
- | Finally, we will get the Minecraft ' | + | Finally, we will get the Minecraft ' |
- | We also pass '' | + | |
- | an item lying on the ground. Try experimenting with this value and see what happens (it's an enum). | + | |
- | We also need to call '' | + | |
<code java> | <code java> | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
[...] | [...] | ||
- | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, | + | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, |
// Mandatory call after GL calls | // Mandatory call after GL calls | ||
Line 102: | Line 89: | ||
</ | </ | ||
- | You can try your newly created block entity renderer right now. | + | You can try your newly created block entity renderer right now. However, if you didn't make your block transparent, |
- | However, if you didn't make your block transparent, | + | |
- | This is because by default, //whatever you render in the block entity, will receive light as if it's in the same position as the block entity//. | + | |
- | So the floating block receives light from //inside// our opaque block, which means it receives no light! | + | |
- | To fix this, we will tell Minecraft to receive light from //one block above// the location of the block entity. | + | |
To get the light, we call '' | To get the light, we call '' | ||
Line 116: | Line 99: | ||
| | ||
int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), | int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), | ||
- | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, | + | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, |
| | ||
[...] | [...] | ||
Line 123: | Line 106: | ||
The jukebox should now have the proper lighting. | The jukebox should now have the proper lighting. | ||
+ | |||
+ | ===== Rendering according to block entity data ===== | ||
+ | Sometimes you wants to render according to the block entity data (nbt), and you find they are all empty, even if you can access the data through ''/ |
tutorial/blockentityrenderers.txt · Last modified: 2023/02/09 13:14 by mschae23