Add item renderer with model transformation mode, deprecate old one. (#973)

* Add item renderer with model transformation mode, deprecate old one.

This PR simply adds a new interface which supplies the additional `Mode` parameter.
All old renderers are delegated to an implementation of the new renderer, thereby making this PR still backwards compatable with all existing renderers.

(cherry picked from commit 7c9162e99f48c6e3989eec9a46afaa935d65ce30)

* Update fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/BuiltinItemRendererWithMode.java

Co-authored-by: shartte <shartte@users.noreply.github.com>

* Rename new interfact to `DynamicItemRenderer`, make it an inner class of the registry class.

* Update fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/BuiltinItemRendererRegistryImpl.java

Co-authored-by: liach <7806504+liach@users.noreply.github.com>

* Update BuiltinItemRendererRegistryImpl.java

* Update BuiltinItemRendererRegistryImpl.java

* Imports

* Use ItemConvertible for new render method

* Rename new interfact to `DynamicItemRenderer`, make it an inner class of the registry class.

fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/BuiltinItemRendererRegistry.java

* Move inner class out, fix formatting issue in loot-tables with linux oses

* why was this multilined

* license header lol

* Apply suggestions from code review

Co-authored-by: liach <7806504+liach@users.noreply.github.com>

* Make renderer a nested class again

* putIfAbsent

Co-authored-by: shartte <shartte@users.noreply.github.com>
Co-authored-by: liach <7806504+liach@users.noreply.github.com>
This commit is contained in:
i509VCB 2020-09-03 13:47:50 -05:00 committed by GitHub
parent 15028e6f6c
commit 0ba3dd89ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 15 deletions

View file

@ -81,7 +81,7 @@ public class FabricLootSupplierBuilder extends LootTable.Builder {
} }
/** /**
* Copies the pools and functions of the {@code supplier} to this builder. * Copies the pools and functions of the {@code supplier} to this builder.
* If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied. * If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied.
*/ */
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) { public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.client.rendering.v1;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
@ -28,8 +29,11 @@ import net.fabricmc.api.Environment;
* They allow using non-model rendering, such as BERs, for items. * They allow using non-model rendering, such as BERs, for items.
* *
* <p>An item with a builtin renderer must have a model extending {@code minecraft:builtin/entity}. * <p>An item with a builtin renderer must have a model extending {@code minecraft:builtin/entity}.
* The renderers are registered with {@link BuiltinItemRendererRegistry#register}. * The renderers are registered with {@link BuiltinItemRendererRegistry#register(Item, BuiltinItemRenderer)}.
*
* @deprecated Please use {@link BuiltinItemRendererRegistry.DynamicItemRenderer} instead.
*/ */
@Deprecated
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@FunctionalInterface @FunctionalInterface
public interface BuiltinItemRenderer { public interface BuiltinItemRenderer {

View file

@ -16,15 +16,19 @@
package net.fabricmc.fabric.api.client.rendering.v1; package net.fabricmc.fabric.api.client.rendering.v1;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl; import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl;
/** /**
* This registry holds {@linkplain BuiltinItemRenderer builtin item renderers} for items. * This registry holds {@linkplain DynamicItemRenderer builtin item renderers} for items.
*/ */
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public interface BuiltinItemRendererRegistry { public interface BuiltinItemRendererRegistry {
@ -43,7 +47,9 @@ public interface BuiltinItemRendererRegistry {
* @param renderer the renderer * @param renderer the renderer
* @throws IllegalArgumentException if the item already has a registered renderer * @throws IllegalArgumentException if the item already has a registered renderer
* @throws NullPointerException if either the item or the renderer is null * @throws NullPointerException if either the item or the renderer is null
* @deprecated Please use {@link BuiltinItemRendererRegistry#register(ItemConvertible, DynamicItemRenderer)} instead.
*/ */
@Deprecated
void register(Item item, BuiltinItemRenderer renderer); void register(Item item, BuiltinItemRenderer renderer);
/** /**
@ -55,6 +61,43 @@ public interface BuiltinItemRendererRegistry {
* @param renderer the renderer * @param renderer the renderer
* @throws IllegalArgumentException if the item already has a registered renderer * @throws IllegalArgumentException if the item already has a registered renderer
* @throws NullPointerException if either the item or the renderer is null * @throws NullPointerException if either the item or the renderer is null
* @deprecated Please use {@link BuiltinItemRendererRegistry#register(ItemConvertible, DynamicItemRenderer)} instead.
*/ */
@Deprecated
void register(ItemConvertible item, BuiltinItemRenderer renderer); void register(ItemConvertible item, BuiltinItemRenderer renderer);
/**
* Registers the renderer for the item.
*
* <p>Note that the item's JSON model must also extend {@code minecraft:builtin/entity}.
*
* @param item the item
* @param renderer the renderer
* @throws IllegalArgumentException if the item already has a registered renderer
* @throws NullPointerException if either the item or the renderer is null
*/
void register(ItemConvertible item, DynamicItemRenderer renderer);
/**
* Dynamic item renderers render items with custom code.
* They allow using non-model rendering, such as BERs, for items.
*
* <p>An item with a dynamic renderer must have a model extending {@code minecraft:builtin/entity}.
* The renderers are registered with {@link BuiltinItemRendererRegistry#register(ItemConvertible, DynamicItemRenderer)}.
*/
@FunctionalInterface
@Environment(EnvType.CLIENT)
interface DynamicItemRenderer {
/**
* Renders an item stack.
*
* @param stack the rendered item stack
* @param mode the model transformation mode
* @param matrices the matrix stack
* @param vertexConsumers the vertex consumer provider
* @param light packed lightmap coordinates
* @param overlay the overlay UV passed to {@link net.minecraft.client.render.VertexConsumer#overlay(int)}
*/
void render(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay);
}
} }

View file

@ -33,21 +33,15 @@ import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
public final class BuiltinItemRendererRegistryImpl implements BuiltinItemRendererRegistry { public final class BuiltinItemRendererRegistryImpl implements BuiltinItemRendererRegistry {
public static final BuiltinItemRendererRegistryImpl INSTANCE = new BuiltinItemRendererRegistryImpl(); public static final BuiltinItemRendererRegistryImpl INSTANCE = new BuiltinItemRendererRegistryImpl();
private static final Map<Item, BuiltinItemRenderer> RENDERERS = new HashMap<>(); private static final Map<Item, DynamicItemRenderer> RENDERERS = new HashMap<>();
private BuiltinItemRendererRegistryImpl() { private BuiltinItemRendererRegistryImpl() {
} }
@Override @Override
public void register(Item item, BuiltinItemRenderer renderer) { public void register(Item item, BuiltinItemRenderer renderer) {
Objects.requireNonNull(item, "item is null");
Objects.requireNonNull(renderer, "renderer is null"); Objects.requireNonNull(renderer, "renderer is null");
this.register(item, (stack, mode, matrices, vertexConsumers, light, overlay) -> renderer.render(stack, matrices, vertexConsumers, light, overlay));
if (RENDERERS.containsKey(item)) {
throw new IllegalArgumentException("Item " + Registry.ITEM.getId(item) + " already has a builtin renderer!");
}
RENDERERS.put(item, renderer);
} }
@Override @Override
@ -56,8 +50,19 @@ public final class BuiltinItemRendererRegistryImpl implements BuiltinItemRendere
register(item.asItem(), renderer); register(item.asItem(), renderer);
} }
@Override
public void register(ItemConvertible item, DynamicItemRenderer renderer) {
Objects.requireNonNull(item, "item is null");
Objects.requireNonNull(item.asItem(), "item is null");
Objects.requireNonNull(renderer, "renderer is null");
if (RENDERERS.putIfAbsent(item.asItem(), renderer) != null) {
throw new IllegalArgumentException("Item " + Registry.ITEM.getId(item.asItem()) + " already has a builtin renderer!");
}
}
/* @Nullable */ /* @Nullable */
public static BuiltinItemRenderer getRenderer(Item item) { public static DynamicItemRenderer getRenderer(Item item) {
return RENDERERS.get(item); return RENDERERS.get(item);
} }
} }

View file

@ -27,17 +27,17 @@ import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRenderer; import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl; import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl;
@Mixin(BuiltinModelItemRenderer.class) @Mixin(BuiltinModelItemRenderer.class)
abstract class MixinBuiltinModelItemRenderer { abstract class MixinBuiltinModelItemRenderer {
@Inject(method = "render", at = @At("HEAD"), cancellable = true) @Inject(method = "render", at = @At("HEAD"), cancellable = true)
private void fabric_onRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo info) { private void fabric_onRender(ItemStack stack, ModelTransformation.Mode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo info) {
BuiltinItemRenderer renderer = BuiltinItemRendererRegistryImpl.getRenderer(stack.getItem()); /* @Nullable */ BuiltinItemRendererRegistry.DynamicItemRenderer renderer = BuiltinItemRendererRegistryImpl.getRenderer(stack.getItem());
if (renderer != null) { if (renderer != null) {
renderer.render(stack, matrices, vertexConsumers, light, overlay); renderer.render(stack, mode, matrices, vertexConsumers, light, overlay);
info.cancel(); info.cancel();
} }
} }