mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-24 16:48:02 -05:00
Reuse TerrainFallbackConsumer to render vanilla models when (#870)
called from BlockModelRenderer. Fixes #869.
This commit is contained in:
parent
57b0bb7ac0
commit
a2a03a90f8
2 changed files with 39 additions and 31 deletions
|
@ -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<Random> 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<RenderLayer, VertexConsumer> bufferFunc, AoCalculator aoCalc, QuadTransform transform) {
|
||||
super(blockInfo, bufferFunc, aoCalc, transform);
|
||||
|
@ -133,7 +147,7 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC
|
|||
|
||||
@Override
|
||||
public Consumer<BakedModel> fallbackConsumer() {
|
||||
return this::acceptVanillaModel;
|
||||
return fallbackConsumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<BlockRenderContext> 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<Boolean> 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<Boolean> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue