Fix gui item rendering (issue PR )

This commit is contained in:
grondag 2019-11-28 00:03:04 -08:00 committed by Player
parent 5a0f9a60f7
commit 1e5e53014d
3 changed files with 95 additions and 33 deletions
build.gradle
fabric-renderer-indigo/src/main/java/net/fabricmc/fabric
impl/client/indigo/renderer/render
mixin/client/indigo/renderer

View file

@ -4,7 +4,7 @@ plugins {
id 'idea'
id 'maven-publish'
id 'fabric-loom' version '0.2.5-SNAPSHOT' apply false
id 'net.minecrell.licenser' version '0.4.1'
id 'net.minecrell.licenser' version '0.4.1'
id "org.ajoberstar.grgit" version "3.1.1"
id 'com.matthewprenger.cursegradle' version "1.1.2"
}
@ -183,7 +183,7 @@ publishing {
depNode.appendNode("scope", "compile")
}
}
}
}
}
repositories {

View file

@ -17,21 +17,30 @@
package net.fabricmc.fabric.impl.client.indigo.renderer.render;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Supplier;
import net.minecraft.class_4722;
import net.minecraft.block.BlockState;
import net.minecraft.client.color.item.ItemColors;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderLayers;
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.BakedQuad;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.render.model.json.ModelTransformation.Type;
import net.minecraft.client.util.math.Matrix4f;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Direction;
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
@ -62,45 +71,69 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
private final ItemColors colorMap;
private final Random random = new Random();
private final Consumer<BakedModel> fallbackConsumer;
VertexConsumer bufferBuilder;
MatrixStack matrixStack;
Matrix4f matrix;
private final Vector3f normalVec = new Vector3f();
private MatrixStack matrixStack;
private Matrix4f matrix;
private VertexConsumerProvider vertexConsumerProvider;
private VertexConsumer modelVertexConsumer;
private BlendMode quadBlendMode;
private VertexConsumer quadVertexConsumer;
private Type transformType;
private int lightmap;
private int overlay;
private ItemStack itemStack;
private VanillaQuadHandler vanillaHandler;
protected final Vector3f normalVec = new Vector3f();
private final Supplier<Random> randomSupplier = () -> {
Random result = random;
final Random result = random;
result.setSeed(ITEM_RANDOM_SEED);
return random;
};
private final int[] quadData = new int[EncodingFormat.TOTAL_STRIDE];;
private final int[] quadData = new int[EncodingFormat.TOTAL_STRIDE];
public ItemRenderContext(ItemColors colorMap) {
this.colorMap = colorMap;
this.fallbackConsumer = this::fallbackConsumer;
fallbackConsumer = this::fallbackConsumer;
}
public void renderModel(FabricBakedModel model, ItemStack stack, int lightmap, int overlay, MatrixStack matrixStack, VertexConsumer buffer, VanillaQuadHandler vanillaHandler) {
public void renderModel(ItemStack itemStack, Type transformType, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int lightmap, int overlay, FabricBakedModel model, VanillaQuadHandler vanillaHandler) {
this.lightmap = lightmap;
this.overlay = overlay;
this.itemStack = stack;
this.bufferBuilder = buffer;
this.itemStack = itemStack;
this.vertexConsumerProvider = vertexConsumerProvider;
this.matrixStack = matrixStack;
this.matrix = matrixStack.peek().getModel();
this.normalMatrix = matrixStack.peek().getNormal();
this.overlay = overlay;
this.transformType = transformType;
this.vanillaHandler = vanillaHandler;
model.emitItemQuads(stack, randomSupplier, this);
quadBlendMode = BlendMode.DEFAULT;
modelVertexConsumer = selectVertexConsumer(RenderLayers.getItemLayer(itemStack));
matrixStack.push();
((BakedModel) model).getTransformation().getTransformation(transformType).method_23075(invert, matrixStack);
matrixStack.translate(-0.5D, -0.5D, -0.5D);
matrix = matrixStack.peek().getModel();
normalMatrix = matrixStack.peek().getNormal();
model.emitItemQuads(itemStack, randomSupplier, this);
matrixStack.pop();
this.bufferBuilder = null;
this.matrixStack = null;
this.itemStack = null;
this.vanillaHandler = null;
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 layerIn) {
final RenderLayer layer = transformType == ModelTransformation.Type.GUI && Objects.equals(layerIn, class_4722.method_24075()) ? class_4722.method_24076() : layerIn;
return ItemRenderer.getArmorVertexConsumer(vertexConsumerProvider, layer, true, itemStack.hasEnchantmentGlint());
}
private class Maker extends MutableQuadViewImpl implements QuadEmitter {
@ -122,7 +155,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
private final Maker editorQuad = new Maker();
private final Consumer<Mesh> meshConsumer = (mesh) -> {
MeshImpl m = (MeshImpl) mesh;
final MeshImpl m = (MeshImpl) mesh;
final int[] data = m.data();
final int limit = data.length;
int index = 0;
@ -147,7 +180,7 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
return;
}
RenderMaterialImpl.Value mat = quad.material();
final RenderMaterialImpl.Value mat = quad.material();
final int quadColor = mat.disableColorIndex(0) ? -1 : indexColor();
final int lightmap = mat.emissive(0) ? AbstractQuadRenderer.FULL_BRIGHTNESS : this.lightmap;
@ -158,7 +191,34 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
quad.lightmap(i, ColorHelper.maxBrightness(quad.lightmap(i), lightmap));
}
AbstractQuadRenderer.bufferQuad(bufferBuilder, quad, matrix, overlay, normalMatrix, normalVec);
AbstractQuadRenderer.bufferQuad(quadVertexConsumer(mat.blendMode(0)), quad, matrix, overlay, normalMatrix, normalVec);
}
/**
* 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(class_4722.method_24075());
quadBlendMode = BlendMode.TRANSLUCENT;
} else {
quadVertexConsumer = selectVertexConsumer(class_4722.method_24074());
quadBlendMode = BlendMode.CUTOUT;
}
return quadVertexConsumer;
}
@Override
@ -172,23 +232,23 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
random.setSeed(ITEM_RANDOM_SEED);
final Direction cullFace = ModelHelper.faceFromIndex(i);
renderFallbackWithTransform(bufferBuilder, model.getQuads((BlockState) null, cullFace, random), lightmap, itemStack, cullFace);
renderFallbackWithTransform(model.getQuads((BlockState) null, cullFace, random), cullFace);
}
} else {
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
vanillaHandler.accept(model, itemStack, lightmap, overlay, matrixStack, bufferBuilder);
vanillaHandler.accept(model, itemStack, lightmap, overlay, matrixStack, modelVertexConsumer);
}
}
};
}
private void renderFallbackWithTransform(VertexConsumer bufferBuilder, List<BakedQuad> quads, int color, ItemStack stack, Direction cullFace) {
private void renderFallbackWithTransform(List<BakedQuad> quads, Direction cullFace) {
if (quads.isEmpty()) {
return;
}
Maker editorQuad = this.editorQuad;
final Maker editorQuad = this.editorQuad;
for (BakedQuad q : quads) {
for (final BakedQuad q : quads) {
editorQuad.clear();
editorQuad.fromVanilla(q.getVertexData(), 0, false);
editorQuad.cullFace(cullFace);

View file

@ -24,8 +24,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.color.item.ItemColors;
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.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
@ -36,7 +38,7 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.
@Mixin(ItemRenderer.class)
public abstract class MixinItemRenderer {
@Shadow
protected abstract void method_23182(BakedModel model, ItemStack stack, int color, int overlay, MatrixStack matrixStack, VertexConsumer buffer);
protected abstract void method_23182(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrixStack, VertexConsumer buffer);
@Shadow
protected ItemColors colorMap;
@ -45,12 +47,12 @@ public abstract class MixinItemRenderer {
private final ThreadLocal<ItemRenderContext> CONTEXTS = ThreadLocal.withInitial(() -> new ItemRenderContext(colorMap));
@Inject(at = @At("HEAD"), method = "method_23182", cancellable = true)
private void hook_method_23182(BakedModel model, ItemStack stack, int lightmap, int overlay, MatrixStack matrixStack, VertexConsumer buffer, CallbackInfo ci) {
@Inject(at = @At("HEAD"), method = "method_23179", cancellable = true)
public void hook_method_23179(ItemStack stack, ModelTransformation.Type transformType, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, BakedModel model, CallbackInfo ci) {
final FabricBakedModel fabricModel = (FabricBakedModel) model;
if (!fabricModel.isVanillaAdapter()) {
CONTEXTS.get().renderModel(fabricModel, stack, lightmap, overlay, matrixStack, buffer, vanillaHandler);
if (!(stack.isEmpty() || fabricModel.isVanillaAdapter())) {
CONTEXTS.get().renderModel(stack, transformType, invert, matrixStack, vertexConsumerProvider, light, overlay, fabricModel, vanillaHandler);
ci.cancel();
}
}