diff --git a/src/main/java/grondag/canvas/apiimpl/material/MeshMaterialLayer.java b/src/main/java/grondag/canvas/apiimpl/material/MeshMaterialLayer.java index 71f189211..554a274ca 100644 --- a/src/main/java/grondag/canvas/apiimpl/material/MeshMaterialLayer.java +++ b/src/main/java/grondag/canvas/apiimpl/material/MeshMaterialLayer.java @@ -13,15 +13,18 @@ public class MeshMaterialLayer { private final MeshMaterial meshMaterial; public final int shaderFlags; + public final boolean isTranslucent; + // WIP: remove + @Deprecated public final ShaderPass shaderType; private final MaterialShaderImpl shader; public MeshMaterialLayer(MeshMaterial meshMaterial, int depth) { this.meshMaterial = meshMaterial; - + isTranslucent = meshMaterial.isTranslucent; // determine how to buffer if (depth == 0) { - shaderType = this.meshMaterial.blendMode() == BlendMode.TRANSLUCENT ? ShaderPass.TRANSLUCENT : ShaderPass.SOLID; + shaderType = isTranslucent ? ShaderPass.TRANSLUCENT : ShaderPass.SOLID; } else { // +1 layers with cutout are expected to not share pixels with lower layers! Otherwise Z-fighting over overwrite will happen // anything other than cutout handled as non-sorting, no-depth translucent decal diff --git a/src/main/java/grondag/canvas/apiimpl/rendercontext/ItemRenderContext.java b/src/main/java/grondag/canvas/apiimpl/rendercontext/ItemRenderContext.java index 3561ae8c8..8ad87dbc0 100644 --- a/src/main/java/grondag/canvas/apiimpl/rendercontext/ItemRenderContext.java +++ b/src/main/java/grondag/canvas/apiimpl/rendercontext/ItemRenderContext.java @@ -22,14 +22,8 @@ import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.color.item.ItemColors; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.RenderLayers; -import net.minecraft.client.render.TexturedRenderLayers; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.client.render.model.BakedModel; -import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.render.model.json.ModelTransformation.Mode; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; @@ -44,7 +38,6 @@ import grondag.canvas.material.EncodingContext; import grondag.canvas.mixinterface.Matrix3fExt; import grondag.canvas.mixinterface.MinecraftClientExt; -import grondag.canvas.shader.ShaderPass; import grondag.fermion.sc.concurrency.SimpleConcurrentList; /** @@ -79,12 +72,7 @@ public static ItemRenderContext get() { private final ItemColors colorMap; private final Random random = new Random(); - private VertexConsumerProvider vertexConsumerProvider; private VertexConsumer modelVertexConsumer; - - private BlendMode quadBlendMode; - private VertexConsumer quadVertexConsumer; - private int lightmap; private ItemStack itemStack; private final EncodingContext context = EncodingContext.ITEM; @@ -102,18 +90,13 @@ public ItemRenderContext(ItemColors colorMap) { collectors.setContext(EncodingContext.ITEM); } - public void renderModel(ItemStack itemStack, Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int lightmap, int overlay, FabricBakedModel model) { + public void renderModel(ItemStack itemStack, Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, VertexConsumer modelConsumer, int lightmap, int overlay, FabricBakedModel model) { this.lightmap = lightmap; this.overlay = overlay; this.itemStack = itemStack; - this.vertexConsumerProvider = vertexConsumerProvider; - - quadBlendMode = BlendMode.DEFAULT; - modelVertexConsumer = selectVertexConsumer(RenderLayers.getItemLayer(itemStack, transformMode != ModelTransformation.Mode.GROUND)); + modelVertexConsumer = modelConsumer; matrixStack.push(); - ((BakedModel) model).getTransformation().getTransformation(transformMode).apply(invert, matrixStack); - matrixStack.translate(-0.5D, -0.5D, -0.5D); matrix = matrixStack.peek().getModel(); normalMatrix = (Matrix3fExt)(Object) matrixStack.peek().getNormal(); @@ -125,42 +108,6 @@ public void renderModel(ItemStack itemStack, Mode transformMode, boolean invert, modelVertexConsumer = null; } - /** - * Use non-culling translucent material in GUI to match vanilla behavior. If the item - * is enchanted then also select a dual-output vertex consumer. For models with layered - * coplanar polygons this means we will render the glint more than once. Indigo doesn't - * support sprite layers, so this can't be helped in this implementation. - */ - private VertexConsumer selectVertexConsumer(RenderLayer layer) { - return ItemRenderer.getArmorVertexConsumer(vertexConsumerProvider, layer, true, itemStack.hasGlint()); - } - - /** - * Caches custom blend mode / vertex consumers and mimics the logic - * in {@code RenderLayers.getEntityBlockLayer}. Layers other than - * translucent are mapped to cutout. - */ - private VertexConsumer quadVertexConsumer(BlendMode blendMode) { - if (blendMode == BlendMode.DEFAULT) { - return modelVertexConsumer; - } - - if (blendMode != BlendMode.TRANSLUCENT) { - blendMode = BlendMode.CUTOUT; - } - - if (blendMode == quadBlendMode) { - return quadVertexConsumer; - } else if (blendMode == BlendMode.TRANSLUCENT) { - quadVertexConsumer = selectVertexConsumer(TexturedRenderLayers.getEntityTranslucentCull()); - quadBlendMode = BlendMode.TRANSLUCENT; - } else { - quadVertexConsumer = selectVertexConsumer(TexturedRenderLayers.getEntityCutout()); - quadBlendMode = BlendMode.CUTOUT; - } - - return quadVertexConsumer; - } @Override public EncodingContext materialContext() { @@ -184,7 +131,12 @@ public BlockState blockState() { @Override public VertexConsumer consumer(MeshMaterialLayer mat) { - return quadVertexConsumer(mat.shaderType == ShaderPass.SOLID ? BlendMode.CUTOUT : BlendMode.TRANSLUCENT); + // WIP: really can't honor per-quad materials in the current setup + // and also honor default model render layer because default blend mode + // is transformed to something specific before we get here, and the + // vanilla logic for model default layer is monstrous - see ItemRenderer + // For now, always use the model default + return modelVertexConsumer; } @Override diff --git a/src/main/java/grondag/canvas/mixin/MixinItemRenderer.java b/src/main/java/grondag/canvas/mixin/MixinItemRenderer.java index 9c7f88950..74940b17f 100644 --- a/src/main/java/grondag/canvas/mixin/MixinItemRenderer.java +++ b/src/main/java/grondag/canvas/mixin/MixinItemRenderer.java @@ -19,53 +19,28 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.Redirect; +import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.BuiltinModelItemRenderer; import net.minecraft.client.render.item.ItemModels; import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.json.ModelTransformation; -import net.minecraft.client.util.ModelIdentifier; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; import grondag.canvas.apiimpl.rendercontext.ItemRenderContext; -import grondag.canvas.compat.SimpleDrawersHolder; @Mixin(ItemRenderer.class) public abstract class MixinItemRenderer { @Shadow private ItemModels models; - @Inject(at = @At("HEAD"), method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformation$Mode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V", cancellable = true) - private void onRenderItem(ItemStack stack, ModelTransformation.Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, BakedModel model, CallbackInfo ci) { - model = SimpleDrawersHolder.itemCallbackHandler.onRender(stack, transformMode, invert, model); - - if (!(stack.isEmpty())) { - // reproduce vanilla hard-coded hack for trident - final boolean isGuiGroundOrFixed = transformMode == ModelTransformation.Mode.GUI || transformMode == ModelTransformation.Mode.GROUND || transformMode == ModelTransformation.Mode.FIXED; - final boolean isTrident = stack.getItem() == Items.TRIDENT; - - if (isTrident && isGuiGroundOrFixed) { - model = models.getModelManager().getModel(new ModelIdentifier("minecraft:trident#inventory")); - } - - if (!model.isBuiltin() && (!isTrident || isGuiGroundOrFixed)) { - ItemRenderContext.get().renderModel(stack, transformMode, invert, matrixStack, vertexConsumerProvider, light, overlay, (FabricBakedModel) model); - } else { - matrixStack.push(); - model.getTransformation().getTransformation(transformMode).apply(invert, matrixStack); - matrixStack.translate(-0.5D, -0.5D, -0.5D); - BuiltinModelItemRenderer.INSTANCE.render(stack, transformMode, matrixStack, vertexConsumerProvider, light, overlay); - matrixStack.pop(); - } - - ci.cancel(); - } + @Redirect(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformation$Mode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V")) + private void onRenderItem(ItemRenderer self, BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer modelConsumer, ItemStack stack2, ModelTransformation.Mode renderMode, boolean leftHanded, MatrixStack matrixStack, VertexConsumerProvider vertexConsumers, int light2, int overlay2, BakedModel model2) { + ItemRenderContext.get().renderModel(stack2, renderMode, leftHanded, matrixStack, vertexConsumers, modelConsumer, light2, overlay2, (FabricBakedModel) model2); } }