Skip to content

Commit

Permalink
Partial fix for missing item glint
Browse files Browse the repository at this point in the history
  • Loading branch information
grondag committed Sep 4, 2020
1 parent d03906e commit 5527113
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

/**
Expand Down Expand Up @@ -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;
Expand All @@ -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();

Expand All @@ -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() {
Expand All @@ -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
Expand Down
37 changes: 6 additions & 31 deletions src/main/java/grondag/canvas/mixin/MixinItemRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 5527113

Please sign in to comment.