From a2a03a90f8f99bcedaf24557eedcb0f97f015237 Mon Sep 17 00:00:00 2001 From: shartte Date: Fri, 17 Jul 2020 15:49:30 +0200 Subject: [PATCH] Reuse TerrainFallbackConsumer to render vanilla models when (#870) called from BlockModelRenderer. Fixes #869. --- .../renderer/render/BlockRenderContext.java | 58 ++++++++++++------- .../renderer/MixinBlockModelRenderer.java | 12 +--- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/BlockRenderContext.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/BlockRenderContext.java index bf734e834..2cb1dac6d 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/BlockRenderContext.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/BlockRenderContext.java @@ -19,12 +19,12 @@ package net.fabricmc.fabric.impl.client.indigo.renderer.render; import java.util.Random; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import net.minecraft.block.BlockState; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.WorldRenderer; -import net.minecraft.client.render.block.BlockModelRenderer; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.util.math.Matrix4f; import net.minecraft.client.util.math.Matrix3f; @@ -46,17 +46,37 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC private final BlockRenderInfo blockInfo = new BlockRenderInfo(); private final AoCalculator aoCalc = new AoCalculator(blockInfo, this::brightness, this::aoLevel); private final MeshConsumer meshConsumer = new MeshConsumer(blockInfo, this::outputBuffer, aoCalc, this::transform); - private final Random random = new Random(); - private BlockModelRenderer vanillaRenderer; private VertexConsumer bufferBuilder; - private long seed; - private boolean isCallingVanilla = false; private boolean didOutput = false; - private MatrixStack matrixStack; + // These are kept as fields to avoid avoid the heap allocation for a supplier. + // BlockModelRenderer allows the caller to supply both the random object and seed. + private Random random; + private long seed; + private final Supplier randomSupplier = () -> { + random.setSeed(seed); + return random; + }; - public boolean isCallingVanilla() { - return isCallingVanilla; - } + /** + * Reuse the fallback consumer from the render context used during chunk rebuild to make it properly + * apply the current transforms to vanilla models. + */ + private final TerrainFallbackConsumer fallbackConsumer = new TerrainFallbackConsumer(blockInfo, this::outputBuffer, aoCalc, this::transform) { + @Override + protected int overlay() { + return overlay; + } + + @Override + protected Matrix4f matrix() { + return matrix; + } + + @Override + protected Matrix3f normalMatrix() { + return normalMatrix; + } + }; private int brightness(BlockPos pos) { if (blockInfo.blockView == null) { @@ -76,35 +96,29 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC return bufferBuilder; } - public boolean tesselate(BlockModelRenderer vanillaRenderer, BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean checkSides, long seed, int overlay) { - this.vanillaRenderer = vanillaRenderer; + public boolean render(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, Random random, long seed, int overlay) { this.bufferBuilder = buffer; - this.matrixStack = matrixStack; this.matrix = matrixStack.peek().getModel(); this.normalMatrix = matrixStack.peek().getNormal(); - + this.random = random; this.seed = seed; + this.overlay = overlay; this.didOutput = false; aoCalc.clear(); blockInfo.setBlockView(blockView); blockInfo.prepareForBlock(state, pos, model.useAmbientOcclusion()); - ((FabricBakedModel) model).emitBlockQuads(blockView, state, pos, blockInfo.randomSupplier, this); + ((FabricBakedModel) model).emitBlockQuads(blockView, state, pos, randomSupplier, this); - this.vanillaRenderer = null; blockInfo.release(); this.bufferBuilder = null; + this.random = null; + this.seed = seed; return didOutput; } - protected void acceptVanillaModel(BakedModel model) { - isCallingVanilla = true; - didOutput = didOutput && vanillaRenderer.render(blockInfo.blockView, model, blockInfo.blockState, blockInfo.blockPos, matrixStack, bufferBuilder, false, random, seed, overlay); - isCallingVanilla = false; - } - private class MeshConsumer extends AbstractMeshConsumer { MeshConsumer(BlockRenderInfo blockInfo, Function bufferFunc, AoCalculator aoCalc, QuadTransform transform) { super(blockInfo, bufferFunc, aoCalc, transform); @@ -133,7 +147,7 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC @Override public Consumer fallbackConsumer() { - return this::acceptVanillaModel; + return fallbackConsumer; } @Override diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinBlockModelRenderer.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinBlockModelRenderer.java index a44ac5881..9b0891c5a 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinBlockModelRenderer.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinBlockModelRenderer.java @@ -27,7 +27,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.block.BlockState; -import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.block.BlockModelRenderer; import net.minecraft.client.render.model.BakedModel; @@ -43,22 +42,17 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderContext @Mixin(BlockModelRenderer.class) public abstract class MixinBlockModelRenderer implements AccessBlockModelRenderer { - @Shadow - protected BlockColors colorMap; - @Shadow protected abstract void getQuadDimensions(BlockRenderView blockView, BlockState blockState, BlockPos blockPos, int[] vertexData, Direction face, float[] aoData, BitSet controlBits); private final ThreadLocal CONTEXTS = ThreadLocal.withInitial(BlockRenderContext::new); @Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZLjava/util/Random;JI)Z", cancellable = true) - private void hookTesselate(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrix, VertexConsumer buffer, boolean checkSides, Random rand, long seed, int overlay, CallbackInfoReturnable ci) { + private void hookRender(BlockRenderView blockView, BakedModel model, BlockState state, BlockPos pos, MatrixStack matrix, VertexConsumer buffer, boolean checkSides, Random rand, long seed, int overlay, CallbackInfoReturnable ci) { if (!((FabricBakedModel) model).isVanillaAdapter()) { BlockRenderContext context = CONTEXTS.get(); - - if (!context.isCallingVanilla()) { - ci.setReturnValue(CONTEXTS.get().tesselate((BlockModelRenderer) (Object) this, blockView, model, state, pos, matrix, buffer, checkSides, seed, overlay)); - } + // Note that we do not support face-culling here (so checkSides is ignored) + ci.setReturnValue(context.render(blockView, model, state, pos, matrix, buffer, rand, seed, overlay)); } }