From 6bd39c990ed7f8aa66aab747f63f38665c292a8f Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+technici4n@users.noreply.github.com> Date: Mon, 2 Jan 2023 13:05:49 +0000 Subject: [PATCH] Indigo and Renderer API fixes related to fallback consumers (#2775) * Fix #2639: Indigo fallback consumer does not respect BlendMode or emissivity * Change renderer testmod to test material change * Remove presumably unneeded `quad.geometryFlags()` call * Also test emissivity * Call emitBlockQuads in the testmod * Allow passing the block state explicitly to the fallback consumer. Fixes #1871 * Expand testmod to also test item models * Also fix fallback consumer ignoring material for items * Slight changes * Introduce new interface for the expanded fallback consumer * Add javadoc to ModelHelper (cherry picked from commit 9f179aa14c7d4d1ab3799349316a1c83f29e8830) (cherry picked from commit 2e5408b56300a62167f898c3b9f7006327dd4c40) --- .../renderer/v1/model/FabricBakedModel.java | 4 +- .../api/renderer/v1/render/RenderContext.java | 58 ++++++++++- .../renderer/client/MixinBakedModel.java | 5 +- .../simple/client/FrameBakedModel.java | 96 +++++++++++++++---- .../client/FrameModelResourceProvider.java | 7 +- .../simple/client/RendererClientTest.java | 10 ++ .../renderer/render/AbstractMeshConsumer.java | 44 +-------- .../renderer/render/AbstractQuadRenderer.java | 40 ++++++++ .../renderer/render/BlockRenderContext.java | 2 +- .../renderer/render/ItemRenderContext.java | 27 +++--- .../render/TerrainFallbackConsumer.java | 38 +++----- .../renderer/render/TerrainRenderContext.java | 2 +- 12 files changed, 220 insertions(+), 113 deletions(-) diff --git a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java index b6b00a692..352df0182 100644 --- a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java +++ b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/model/FabricBakedModel.java @@ -36,6 +36,8 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; * Can also be used to generate or customize outputs based on world state instead of * or in addition to block state when render chunks are rebuilt. * + * <p>Implementors should have a look at {@link ModelHelper} as it contains many useful functions. + * * <p>Note for {@link Renderer} implementors: Fabric causes BakedModel to extend this * interface with {@link #isVanillaAdapter()} == true and to produce standard vertex data. * This means any BakedModel instance can be safely cast to this interface without an instanceof check. @@ -82,7 +84,7 @@ public interface FabricBakedModel { * parameter is normally initialized with the same seed prior to each face layer. * Model authors should note this method is called only once per block, and call the provided * Random supplier multiple times if re-seeding is necessary. For wrapped vanilla baked models, - * it will probably be easier to use {@link RenderContext#fallbackConsumer} which handles + * it will probably be easier to use {@link RenderContext#bakedModelConsumer()} which handles * re-seeding per face automatically. * * @param blockView Access to world state. Using {@link net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView#getBlockEntityRenderAttachment(BlockPos)} to diff --git a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/render/RenderContext.java b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/render/RenderContext.java index fa0de2bdf..946fb5f35 100644 --- a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/render/RenderContext.java +++ b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/api/renderer/v1/render/RenderContext.java @@ -18,6 +18,9 @@ package net.fabricmc.fabric.api.renderer.v1.render; import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; @@ -39,11 +42,64 @@ public interface RenderContext { Consumer<Mesh> meshConsumer(); /** + * Fallback consumer that can process a vanilla {@link BakedModel}. * Fabric causes vanilla baked models to send themselves * via this interface. Can also be used by compound models that contain a mix * of vanilla baked models, packaged quads and/or dynamic elements. */ - Consumer<BakedModel> fallbackConsumer(); + default BakedModelConsumer bakedModelConsumer() { + // Default implementation is provided for compat with older renderer implementations, + // but they should always override this function. + Consumer<BakedModel> fallback = fallbackConsumer(); + return new BakedModelConsumer() { + @Override + public void accept(BakedModel model) { + fallback.accept(model); + } + + @Override + public void accept(BakedModel model, @Nullable BlockState state) { + fallback.accept(model); + } + }; + } + + interface BakedModelConsumer extends Consumer<BakedModel> { + /** + * Render a baked model by processing its {@linkplain BakedModel#getQuads} using the rendered block state. + * + * <p>For block contexts, this will pass the block state being rendered to {@link BakedModel#getQuads}. + * For item contexts, this will pass a {@code null} block state to {@link BakedModel#getQuads}. + * {@link #accept(BakedModel, BlockState)} can be used instead to pass the block state explicitly. + */ + @Override + void accept(BakedModel model); + + /** + * Render a baked model by processing its {@linkplain BakedModel#getQuads} with an explicit block state. + * + * <p>This overload allows passing the block state (or {@code null} to query the item quads). + * This is useful when a model is being wrapped, and expects a different + * block state than the one of the block being rendered. + * + * <p>For item render contexts, you can use this function if you want to render the model with a specific block state. + * Otherwise, use {@linkplain #accept(BakedModel)} the other overload} to render the usual item quads. + */ + void accept(BakedModel model, @Nullable BlockState state); + } + + /** + * Fabric causes vanilla baked models to send themselves + * via this interface. Can also be used by compound models that contain a mix + * of vanilla baked models, packaged quads and/or dynamic elements. + * + * @deprecated Prefer using the more flexible {@link #bakedModelConsumer}. + */ + @Deprecated + default Consumer<BakedModel> fallbackConsumer() { + // This default implementation relies on implementors overriding bakedModelConsumer(). + return bakedModelConsumer(); + } /** * Returns a {@link QuadEmitter} instance that emits directly to the render buffer. diff --git a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/mixin/renderer/client/MixinBakedModel.java b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/mixin/renderer/client/MixinBakedModel.java index d76678150..ecc3c3ace 100644 --- a/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/mixin/renderer/client/MixinBakedModel.java +++ b/fabric-renderer-api-v1/src/main/java/net/fabricmc/fabric/mixin/renderer/client/MixinBakedModel.java @@ -42,11 +42,12 @@ public interface MixinBakedModel extends FabricBakedModel { @Override default void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) { - context.fallbackConsumer().accept((BakedModel) this); + context.bakedModelConsumer().accept((BakedModel) this, state); } @Override default void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { - context.fallbackConsumer().accept((BakedModel) this); + // Pass null state to enforce item quads in block render contexts + context.bakedModelConsumer().accept((BakedModel) this, null); } } diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameBakedModel.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameBakedModel.java index 1b994d15a..58c7a6cf3 100644 --- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameBakedModel.java +++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameBakedModel.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedQuad; @@ -36,20 +37,29 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; final class FrameBakedModel implements BakedModel, FabricBakedModel { private final Mesh frameMesh; private final Sprite frameSprite; + private final RenderMaterial translucentMaterial; + private final RenderMaterial translucentEmissiveMaterial; FrameBakedModel(Mesh frameMesh, Sprite frameSprite) { this.frameMesh = frameMesh; this.frameSprite = frameSprite; + + Renderer renderer = RendererAccess.INSTANCE.getRenderer(); + this.translucentMaterial = renderer.materialFinder().blendMode(0, BlendMode.TRANSLUCENT).find(); + this.translucentEmissiveMaterial = renderer.materialFinder().blendMode(0, BlendMode.TRANSLUCENT).emissive(0, true).find(); } @Override @@ -69,7 +79,7 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel { @Override public boolean isSideLit() { - return false; + return true; // we want the block to be lit from the side when rendered as an item } @Override @@ -84,7 +94,7 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel { @Override public ModelTransformation getTransformation() { - return ModelTransformation.NONE; + return ModelHelper.MODEL_TRANSFORM_BLOCK; } @Override @@ -112,27 +122,71 @@ final class FrameBakedModel implements BakedModel, FabricBakedModel { return; // No inner block to render } - Sprite sprite = MinecraftClient.getInstance().getBlockRenderManager().getModels().getModelManager().getBlockModels().getModelParticleSprite(data.getDefaultState()); - QuadEmitter emitter = context.getEmitter(); + BlockState innerState = data.getDefaultState(); - // We can emit our quads outside of the mesh as the block being put in the frame is very much dynamic. - // Emit the quads for each face of the block inside the frame - for (Direction direction : Direction.values()) { - // Add a face, with an inset to give the appearance of the block being in a frame. - emitter.square(direction, 0.1F, 0.1F, 0.9F, 0.9F, 0.1F) - // Set the sprite of the fact, use whole texture via BAKE_LOCK_UV - .spriteBake(0, sprite, MutableQuadView.BAKE_LOCK_UV) - // Allow textures - // TODO: the magic values here are not documented at all and probably should be - .spriteColor(0, -1, -1, -1, -1) - // Emit the quad - .emit(); - } + // Now, we emit a transparent scaled-down version of the inner model + // Try both emissive and non-emissive versions of the translucent material + RenderMaterial material = pos.getX() % 2 == 0 ? translucentMaterial : translucentEmissiveMaterial; + + emitInnerQuads(context, material, () -> { + // Use emitBlockQuads to allow for Renderer API features + ((FabricBakedModel) MinecraftClient.getInstance().getBlockRenderManager().getModel(innerState)).emitBlockQuads(blockView, innerState, pos, randomSupplier, context); + }); } @Override public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { - // TODO: Implement an item test. - // For now we will just leave this as I have not added a block item yet + // Emit our frame mesh + context.meshConsumer().accept(this.frameMesh); + + // Emit a scaled-down fence for testing, trying both materials again. + RenderMaterial material = stack.hasCustomName() ? translucentEmissiveMaterial : translucentMaterial; + + BlockState innerState = Blocks.OAK_FENCE.getDefaultState(); + + emitInnerQuads(context, material, () -> { + // Need to use the fallback consumer directly: + // - we can't use emitBlockQuads because we don't have a blockView + // - we can't use emitItemQuads because multipart models don't have item quads + context.bakedModelConsumer().accept(MinecraftClient.getInstance().getBlockRenderManager().getModel(innerState), innerState); + }); + } + + /** + * Emit a scaled-down version of the inner model. + */ + private void emitInnerQuads(RenderContext context, RenderMaterial material, Runnable innerModelEmitter) { + // Let's push a transform to scale the model down and make it transparent + context.pushTransform(quad -> { + // Scale model down + for (int vertex = 0; vertex < 4; ++vertex) { + float x = quad.x(vertex) * 0.8f + 0.1f; + float y = quad.y(vertex) * 0.8f + 0.1f; + float z = quad.z(vertex) * 0.8f + 0.1f; + quad.pos(vertex, x, y, z); + } + + // Make the quad partially transparent + // Change material to translucent + quad.material(material); + + // Change vertex colors to be partially transparent + for (int vertex = 0; vertex < 4; ++vertex) { + int color = quad.spriteColor(vertex, 0); + int alpha = (color >> 24) & 0xFF; + alpha = alpha * 3 / 4; + color = (color & 0xFFFFFF) | (alpha << 24); + quad.spriteColor(vertex, 0, color); + } + + // Return true because we want the quad to be rendered + return true; + }); + + // Emit the inner block model + innerModelEmitter.run(); + + // Let's not forget to pop the transform! + context.popTransform(); } } diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameModelResourceProvider.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameModelResourceProvider.java index d9a1844f3..34ff995ba 100644 --- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameModelResourceProvider.java +++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/FrameModelResourceProvider.java @@ -16,6 +16,9 @@ package net.fabricmc.fabric.test.renderer.simple.client; +import java.util.HashSet; +import java.util.Set; + import org.jetbrains.annotations.Nullable; import net.minecraft.client.render.model.UnbakedModel; @@ -28,12 +31,12 @@ import net.fabricmc.fabric.api.client.model.ModelResourceProvider; * Provides the unbaked model for use with the frame block. */ final class FrameModelResourceProvider implements ModelResourceProvider { - private static final Identifier FRAME_MODEL_ID = new Identifier("fabric-renderer-api-v1-testmod", "block/frame"); + static final Set<Identifier> FRAME_MODELS = new HashSet<>(); @Nullable @Override public UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context) { - if (resourceId.equals(FRAME_MODEL_ID)) { + if (FRAME_MODELS.contains(resourceId)) { return new FrameUnbakedModel(); } diff --git a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/RendererClientTest.java b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/RendererClientTest.java index e74daf9e4..75c785529 100644 --- a/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/RendererClientTest.java +++ b/fabric-renderer-api-v1/src/testmod/java/net/fabricmc/fabric/test/renderer/simple/client/RendererClientTest.java @@ -16,7 +16,10 @@ package net.fabricmc.fabric.test.renderer.simple.client; +import static net.fabricmc.fabric.test.renderer.simple.RendererTest.id; + import net.minecraft.client.render.RenderLayer; +import net.minecraft.util.registry.Registry; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; @@ -31,7 +34,14 @@ public final class RendererClientTest implements ClientModInitializer { ModelLoadingRegistry.INSTANCE.registerVariantProvider(manager -> new PillarModelVariantProvider()); for (FrameBlock frameBlock : RendererTest.FRAMES) { + // We don't specify a material for the frame mesh, + // so it will use the default material, i.e. the one from BlockRenderLayerMap. BlockRenderLayerMap.INSTANCE.putBlock(frameBlock, RenderLayer.getCutoutMipped()); + + String itemPath = Registry.ITEM.getId(frameBlock.asItem()).getPath(); + FrameModelResourceProvider.FRAME_MODELS.add(id("item/" + itemPath)); } + + FrameModelResourceProvider.FRAME_MODELS.add(id("block/frame")); } } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractMeshConsumer.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractMeshConsumer.java index d0853abbf..bb35c4479 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractMeshConsumer.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractMeshConsumer.java @@ -26,7 +26,6 @@ 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.render.RenderContext.QuadTransform; import net.fabricmc.fabric.impl.client.indigo.renderer.IndigoRenderer; -import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl; import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator; import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat; import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MeshImpl; @@ -55,7 +54,7 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen @Override public Maker emit() { computeGeometry(); - renderQuad(this); + renderQuad(this, false); clear(); return this; } @@ -74,7 +73,7 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen System.arraycopy(data, index, editorQuad.data(), 0, EncodingFormat.TOTAL_STRIDE); editorQuad.load(); index += EncodingFormat.TOTAL_STRIDE; - renderQuad(editorQuad); + renderQuad(editorQuad, false); } } @@ -82,43 +81,4 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen editorQuad.clear(); return editorQuad; } - - private void renderQuad(MutableQuadViewImpl quad) { - if (!transform.transform(quad)) { - return; - } - - if (!blockInfo.shouldDrawFace(quad.cullFace())) { - return; - } - - tessellateQuad(quad, 0); - } - - /** - * Determines color index and render layer, then routes to appropriate - * tessellate routine based on material properties. - */ - private void tessellateQuad(MutableQuadViewImpl quad, int textureIndex) { - final RenderMaterialImpl.Value mat = quad.material(); - final int colorIndex = mat.disableColorIndex(textureIndex) ? -1 : quad.colorIndex(); - final RenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode(textureIndex)); - - if (blockInfo.defaultAo && !mat.disableAo(textureIndex)) { - // needs to happen before offsets are applied - aoCalc.compute(quad, false); - - if (mat.emissive(textureIndex)) { - tessellateSmoothEmissive(quad, renderLayer, colorIndex); - } else { - tessellateSmooth(quad, renderLayer, colorIndex); - } - } else { - if (mat.emissive(textureIndex)) { - tessellateFlatEmissive(quad, renderLayer, colorIndex); - } else { - tessellateFlat(quad, renderLayer, colorIndex); - } - } - } } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractQuadRenderer.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractQuadRenderer.java index 0a7e9c27b..2fb815bd1 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractQuadRenderer.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractQuadRenderer.java @@ -33,6 +33,7 @@ import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Vec3f; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform; +import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl; import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator; import net.fabricmc.fabric.impl.client.indigo.renderer.helper.ColorHelper; import net.fabricmc.fabric.impl.client.indigo.renderer.helper.GeometryHelper; @@ -62,6 +63,45 @@ public abstract class AbstractQuadRenderer { this.transform = transform; } + protected void renderQuad(MutableQuadViewImpl quad, boolean isVanilla) { + if (!transform.transform(quad)) { + return; + } + + if (!blockInfo.shouldDrawFace(quad.cullFace())) { + return; + } + + tessellateQuad(quad, 0, isVanilla); + } + + /** + * Determines color index and render layer, then routes to appropriate + * tessellate routine based on material properties. + */ + private void tessellateQuad(MutableQuadViewImpl quad, int textureIndex, boolean isVanilla) { + final RenderMaterialImpl.Value mat = quad.material(); + final int colorIndex = mat.disableColorIndex(textureIndex) ? -1 : quad.colorIndex(); + final RenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode(textureIndex)); + + if (blockInfo.defaultAo && !mat.disableAo(textureIndex)) { + // needs to happen before offsets are applied + aoCalc.compute(quad, isVanilla); + + if (mat.emissive(textureIndex)) { + tessellateSmoothEmissive(quad, renderLayer, colorIndex); + } else { + tessellateSmooth(quad, renderLayer, colorIndex); + } + } else { + if (mat.emissive(textureIndex)) { + tessellateFlatEmissive(quad, renderLayer, colorIndex); + } else { + tessellateFlat(quad, renderLayer, colorIndex); + } + } + } + /** handles block color and red-blue swizzle, common to all renders. */ private void colorizeQuad(MutableQuadViewImpl q, int blockColorIndex) { if (blockColorIndex == -1) { 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 40d013672..7d6b8831a 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 @@ -141,7 +141,7 @@ public class BlockRenderContext extends AbstractRenderContext { } @Override - public Consumer<BakedModel> fallbackConsumer() { + public BakedModelConsumer bakedModelConsumer() { return fallbackConsumer; } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ItemRenderContext.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ItemRenderContext.java index f454a51f6..7d982988a 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ItemRenderContext.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ItemRenderContext.java @@ -21,6 +21,8 @@ import java.util.Random; import java.util.function.Consumer; import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.color.item.ItemColors; @@ -265,21 +267,27 @@ public class ItemRenderContext extends AbstractRenderContext { } } - private class FallbackConsumer implements Consumer<BakedModel> { + private class FallbackConsumer implements BakedModelConsumer { @Override public void accept(BakedModel model) { + accept(model, null); + } + + @Override + public void accept(BakedModel model, @Nullable BlockState state) { if (hasTransform()) { // if there's a transform in effect, convert to mesh-based quads so that we can apply it for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { final Direction cullFace = ModelHelper.faceFromIndex(i); random.setSeed(ITEM_RANDOM_SEED); - final List<BakedQuad> quads = model.getQuads(null, cullFace, random); + final List<BakedQuad> quads = model.getQuads(state, cullFace, random); final int count = quads.size(); if (count != 0) { for (int j = 0; j < count; j++) { final BakedQuad q = quads.get(j); - renderQuadWithTransform(q, cullFace); + editorQuad.fromVanilla(q, IndigoRenderer.MATERIAL_STANDARD, cullFace); + renderMeshQuad(editorQuad); } } } @@ -287,17 +295,6 @@ public class ItemRenderContext extends AbstractRenderContext { vanillaHandler.accept(model, itemStack, lightmap, overlay, matrixStack, modelVertexConsumer); } } - - private void renderQuadWithTransform(BakedQuad quad, Direction cullFace) { - final Maker editorQuad = ItemRenderContext.this.editorQuad; - editorQuad.fromVanilla(quad, IndigoRenderer.MATERIAL_STANDARD, cullFace); - - if (!transform(editorQuad)) { - return; - } - - renderQuad(editorQuad, BlendMode.DEFAULT, editorQuad.colorIndex()); - } } @Override @@ -306,7 +303,7 @@ public class ItemRenderContext extends AbstractRenderContext { } @Override - public Consumer<BakedModel> fallbackConsumer() { + public BakedModelConsumer bakedModelConsumer() { return fallbackConsumer; } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainFallbackConsumer.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainFallbackConsumer.java index 25162bbd3..4dd8b7d9f 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainFallbackConsumer.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainFallbackConsumer.java @@ -22,6 +22,8 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import net.minecraft.block.BlockState; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; @@ -31,6 +33,7 @@ import net.minecraft.util.math.Direction; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform; import net.fabricmc.fabric.impl.client.indigo.renderer.IndigoRenderer; import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl.Value; @@ -57,7 +60,7 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; * vertex data is sent to the byte buffer. Generally POJO array access will be faster than * manipulating the data via NIO. */ -public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer implements Consumer<BakedModel> { +public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer implements RenderContext.BakedModelConsumer { private static final Value MATERIAL_FLAT = (Value) IndigoRenderer.INSTANCE.materialFinder().disableAo(0, true).find(); private static final Value MATERIAL_SHADED = (Value) IndigoRenderer.INSTANCE.materialFinder().find(); @@ -79,10 +82,14 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple }; @Override - public void accept(BakedModel model) { + public void accept(BakedModel bakedModel) { + accept(bakedModel, blockInfo.blockState); + } + + @Override + public void accept(BakedModel model, @Nullable BlockState blockState) { final Supplier<Random> random = blockInfo.randomSupplier; final Value defaultMaterial = blockInfo.defaultAo && model.useAmbientOcclusion() ? MATERIAL_SHADED : MATERIAL_FLAT; - final BlockState blockState = blockInfo.blockState; for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { final Direction cullFace = ModelHelper.faceFromIndex(i); @@ -102,29 +109,6 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple final MutableQuadViewImpl editorQuad = this.editorQuad; editorQuad.fromVanilla(quad, defaultMaterial, cullFace); - if (!transform.transform(editorQuad)) { - return; - } - - cullFace = editorQuad.cullFace(); - - if (cullFace != null && !blockInfo.shouldDrawFace(cullFace)) { - return; - } - - if (!editorQuad.material().disableAo(0)) { - // needs to happen before offsets are applied - aoCalc.compute(editorQuad, true); - tessellateSmooth(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex()); - } else { - // Recomputing whether the quad has a light face is only needed if it doesn't also have a cull face, - // as in those cases, the cull face will always be used to offset the light sampling position - if (cullFace == null) { - // Can't rely on lazy computation in tessellateFlat() because needs to happen before offsets are applied - editorQuad.geometryFlags(); - } - - tessellateFlat(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex()); - } + renderQuad(editorQuad, true); } } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java index 25dc07a23..0df538529 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/TerrainRenderContext.java @@ -120,7 +120,7 @@ public class TerrainRenderContext extends AbstractRenderContext { } @Override - public Consumer<BakedModel> fallbackConsumer() { + public BakedModelConsumer bakedModelConsumer() { return fallbackConsumer; }