Add a hook for BuiltinModelItemRenderer (#563)

* Add builtin item renderers

Closes #488.

* Bump fabric-rendering-v1 to 1.0.0

* Code review

* Add comments

* Code review II

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

* Add missing license headers

* Switch to ugly class singletons

* Add null checks to BuiltinItemRendererRegistry.register

* Protect against overwriting others' renderers by catching exceptions

Co-authored-by: liach <liach@users.noreply.github.com>
This commit is contained in:
Juuxel 2020-04-30 02:05:39 +03:00 committed by modmuss50
parent 204c316b03
commit 24a100d8a9
5 changed files with 193 additions and 0 deletions

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.rendering.v1;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
/**
* Builtin item renderers render items with custom code.
* 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}.
* The renderers are registered with {@link BuiltinItemRendererRegistry#register}.
*/
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface BuiltinItemRenderer {
/**
* Renders an item stack.
*
* @param stack the rendered item stack
* @param matrices the matrix stack
* @param vertexConsumers the vertex consumer provider
* @param light the color light multiplier at the rendering position
* @param overlay the overlay UV passed to {@link net.minecraft.client.render.VertexConsumer#overlay(int)}
*/
void render(ItemStack stack, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay);
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.rendering.v1;
import net.minecraft.item.Item;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl;
/**
* This registry holds {@linkplain BuiltinItemRenderer builtin item renderers} for items.
*/
@Environment(EnvType.CLIENT)
public interface BuiltinItemRendererRegistry {
/**
* The singleton instance of the renderer registry.
* Use this instance to call the methods in this interface.
*/
BuiltinItemRendererRegistry INSTANCE = BuiltinItemRendererRegistryImpl.INSTANCE;
/**
* 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(Item item, BuiltinItemRenderer renderer);
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.client.rendering;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import net.minecraft.item.Item;
import net.minecraft.util.registry.Registry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRenderer;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
@Environment(EnvType.CLIENT)
public final class BuiltinItemRendererRegistryImpl implements BuiltinItemRendererRegistry {
public static final BuiltinItemRendererRegistryImpl INSTANCE = new BuiltinItemRendererRegistryImpl();
private static final Map<Item, BuiltinItemRenderer> RENDERERS = new HashMap<>();
private BuiltinItemRendererRegistryImpl() {
}
@Override
public void register(Item item, BuiltinItemRenderer renderer) {
Objects.requireNonNull(item, "item is null");
Objects.requireNonNull(renderer, "renderer is null");
if (RENDERERS.containsKey(item)) {
throw new IllegalArgumentException("Item " + Registry.ITEM.getId(item) + " already has a builtin renderer!");
}
RENDERERS.put(item, renderer);
}
/* @Nullable */
public static BuiltinItemRenderer getRenderer(Item item) {
return RENDERERS.get(item);
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.rendering;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.item.BuiltinModelItemRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRenderer;
import net.fabricmc.fabric.impl.client.rendering.BuiltinItemRendererRegistryImpl;
@Mixin(BuiltinModelItemRenderer.class)
abstract class MixinBuiltinModelItemRenderer {
@Inject(method = "render", at = @At("HEAD"), cancellable = true)
private void fabric_onRender(ItemStack stack, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo info) {
BuiltinItemRenderer renderer = BuiltinItemRendererRegistryImpl.getRenderer(stack.getItem());
if (renderer != null) {
renderer.render(stack, matrices, vertexConsumers, light, overlay);
info.cancel();
}
}
}

View file

@ -4,6 +4,7 @@
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"client": [ "client": [
"MixinBlockColorMap", "MixinBlockColorMap",
"MixinBuiltinModelItemRenderer",
"MixinInGameHud", "MixinInGameHud",
"MixinItemColorMap", "MixinItemColorMap",
"MixinWorldRenderer" "MixinWorldRenderer"