diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/QuadViewImpl.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/QuadViewImpl.java index a0f895cac..c386e3a39 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/QuadViewImpl.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/mesh/QuadViewImpl.java @@ -33,9 +33,10 @@ import static net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingForma import com.google.common.base.Preconditions; -import net.minecraft.util.math.Vec3f; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3f; +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.impl.client.indigo.renderer.RenderMaterialImpl; @@ -163,7 +164,9 @@ public class QuadViewImpl implements QuadView { final MutableQuadViewImpl quad = (MutableQuadViewImpl) target; // copy everything except the material - System.arraycopy(data, baseIndex + 1, quad.data, quad.baseIndex + 1, EncodingFormat.TOTAL_STRIDE - 1); + RenderMaterial material = quad.material(); + System.arraycopy(data, baseIndex, quad.data, quad.baseIndex, EncodingFormat.TOTAL_STRIDE); + quad.material(material); quad.faceNormal.set(faceNormal.getX(), faceNormal.getY(), faceNormal.getZ()); quad.nominalFace = this.nominalFace; quad.isGeometryInvalid = false; 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 c33d27688..d62654c65 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 @@ -34,7 +34,7 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MeshImpl; import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; /** - * Consumer for pre-baked meshes. Works by copying the mesh data to a + * Consumer for pre-baked meshes. Works by copying the mesh data to an * "editor" quad held in the instance, where all transformations are applied before buffering. */ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implements Consumer { @@ -46,7 +46,7 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen * Where we handle all pre-buffer coloring, lighting, transformation, etc. * Reused for all mesh quads. Fixed baking array sized to hold largest possible mesh quad. */ - private class Maker extends MutableQuadViewImpl implements QuadEmitter { + private class Maker extends MutableQuadViewImpl { { data = new int[EncodingFormat.TOTAL_STRIDE]; material(IndigoRenderer.MATERIAL_STANDARD); @@ -84,44 +84,44 @@ public abstract class AbstractMeshConsumer extends AbstractQuadRenderer implemen return editorQuad; } - private void renderQuad(MutableQuadViewImpl q) { - if (!transform.transform(editorQuad)) { + private void renderQuad(MutableQuadViewImpl quad) { + if (!transform.transform(quad)) { return; } - if (!blockInfo.shouldDrawFace(q.cullFace())) { + if (!blockInfo.shouldDrawFace(quad.cullFace())) { return; } - final RenderMaterialImpl.Value mat = q.material(); + final RenderMaterialImpl.Value mat = quad.material(); if (!mat.disableAo(0) && MinecraftClient.isAmbientOcclusionEnabled()) { // needs to happen before offsets are applied - aoCalc.compute(q, false); + aoCalc.compute(quad, false); } - tesselateQuad(q, mat, 0); + tessellateQuad(quad, mat, 0); } /** * Determines color index and render layer, then routes to appropriate - * tesselate routine based on material properties. + * tessellate routine based on material properties. */ - private void tesselateQuad(MutableQuadViewImpl quad, RenderMaterialImpl.Value mat, int textureIndex) { + private void tessellateQuad(MutableQuadViewImpl quad, RenderMaterialImpl.Value mat, int textureIndex) { final int colorIndex = mat.disableColorIndex(textureIndex) ? -1 : quad.colorIndex(); final RenderLayer renderLayer = blockInfo.effectiveRenderLayer(mat.blendMode(textureIndex)); if (blockInfo.defaultAo && !mat.disableAo(textureIndex)) { if (mat.emissive(textureIndex)) { - tesselateSmoothEmissive(quad, renderLayer, colorIndex); + tessellateSmoothEmissive(quad, renderLayer, colorIndex); } else { - tesselateSmooth(quad, renderLayer, colorIndex); + tessellateSmooth(quad, renderLayer, colorIndex); } } else { if (mat.emissive(textureIndex)) { - tesselateFlatEmissive(quad, renderLayer, colorIndex); + tessellateFlatEmissive(quad, renderLayer, colorIndex); } else { - tesselateFlat(quad, renderLayer, colorIndex); + 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 b0f5a4343..409dde259 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 @@ -22,14 +22,15 @@ import java.util.function.Function; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.WorldRenderer; -import net.minecraft.util.math.Vec3f; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Matrix3f; 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.aocalc.AoCalculator; @@ -42,8 +43,6 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; * Has most of the actual buffer-time lighting and coloring logic. */ public abstract class AbstractQuadRenderer { - static final int FULL_BRIGHTNESS = 0xF000F0; - protected final Function bufferFunc; protected final BlockRenderInfo blockInfo; protected final AoCalculator aoCalc; @@ -115,7 +114,7 @@ public abstract class AbstractQuadRenderer { // routines below have a bit of copy-paste code reuse to avoid conditional execution inside a hot loop /** for non-emissive mesh quads and all fallback quads with smooth lighting. */ - protected void tesselateSmooth(MutableQuadViewImpl q, RenderLayer renderLayer, int blockColorIndex) { + protected void tessellateSmooth(MutableQuadViewImpl q, RenderLayer renderLayer, int blockColorIndex) { colorizeQuad(q, blockColorIndex); for (int i = 0; i < 4; i++) { @@ -127,19 +126,19 @@ public abstract class AbstractQuadRenderer { } /** for emissive mesh quads with smooth lighting. */ - protected void tesselateSmoothEmissive(MutableQuadViewImpl q, RenderLayer renderLayer, int blockColorIndex) { + protected void tessellateSmoothEmissive(MutableQuadViewImpl q, RenderLayer renderLayer, int blockColorIndex) { colorizeQuad(q, blockColorIndex); for (int i = 0; i < 4; i++) { q.spriteColor(i, 0, ColorHelper.multiplyRGB(q.spriteColor(i, 0), aoCalc.ao[i])); - q.lightmap(i, FULL_BRIGHTNESS); + q.lightmap(i, LightmapTextureManager.MAX_LIGHT_COORDINATE); } bufferQuad(q, renderLayer); } /** for non-emissive mesh quads and all fallback quads with flat lighting. */ - protected void tesselateFlat(MutableQuadViewImpl quad, RenderLayer renderLayer, int blockColorIndex) { + protected void tessellateFlat(MutableQuadViewImpl quad, RenderLayer renderLayer, int blockColorIndex) { colorizeQuad(quad, blockColorIndex); shadeFlatQuad(quad); @@ -153,12 +152,12 @@ public abstract class AbstractQuadRenderer { } /** for emissive mesh quads with flat lighting. */ - protected void tesselateFlatEmissive(MutableQuadViewImpl quad, RenderLayer renderLayer, int blockColorIndex) { + protected void tessellateFlatEmissive(MutableQuadViewImpl quad, RenderLayer renderLayer, int blockColorIndex) { colorizeQuad(quad, blockColorIndex); shadeFlatQuad(quad); for (int i = 0; i < 4; i++) { - quad.lightmap(i, FULL_BRIGHTNESS); + quad.lightmap(i, LightmapTextureManager.MAX_LIGHT_COORDINATE); } bufferQuad(quad, renderLayer); diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractRenderContext.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractRenderContext.java index 13b2625f1..145a97b26 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractRenderContext.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractRenderContext.java @@ -18,19 +18,17 @@ package net.fabricmc.fabric.impl.client.indigo.renderer.render; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix3f; +import net.minecraft.util.math.Matrix4f; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; abstract class AbstractRenderContext implements RenderContext { - private final ObjectArrayList transformStack = new ObjectArrayList<>(); private static final QuadTransform NO_TRANSFORM = (q) -> true; - protected Matrix4f matrix; - protected Matrix3f normalMatrix; - protected int overlay; + private QuadTransform activeTransform = NO_TRANSFORM; + private final ObjectArrayList transformStack = new ObjectArrayList<>(); private final QuadTransform stackTransform = (q) -> { int i = transformStack.size() - 1; @@ -43,7 +41,9 @@ abstract class AbstractRenderContext implements RenderContext { return true; }; - private QuadTransform activeTransform = NO_TRANSFORM; + protected Matrix4f matrix; + protected Matrix3f normalMatrix; + protected int overlay; protected final boolean transform(MutableQuadView q) { return activeTransform.transform(q); 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 4ddd3b3c7..3f99c3119 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 @@ -18,37 +18,36 @@ 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.LightmapTextureManager; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.render.model.BakedModel; -import net.minecraft.util.math.Matrix4f; -import net.minecraft.util.math.Matrix3f; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Matrix3f; +import net.minecraft.util.math.Matrix4f; import net.minecraft.world.BlockRenderView; 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; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator; import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoLuminanceFix; /** * Context for non-terrain block rendering. */ -public class BlockRenderContext extends AbstractRenderContext implements RenderContext { +public class BlockRenderContext extends AbstractRenderContext { 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 VertexConsumer bufferBuilder; private boolean didOutput = false; - // These are kept as fields to avoid avoid the heap allocation for a supplier. + // These are kept as fields to 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; @@ -57,16 +56,7 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC return random; }; - /** - * 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; - } - + private final AbstractMeshConsumer meshConsumer = new AbstractMeshConsumer(blockInfo, this::outputBuffer, aoCalc, this::transform) { @Override protected Matrix4f matrix() { return matrix; @@ -76,11 +66,37 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC protected Matrix3f normalMatrix() { return normalMatrix; } + + @Override + protected int overlay() { + return overlay; + } + }; + + /** + * 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 Matrix4f matrix() { + return matrix; + } + + @Override + protected Matrix3f normalMatrix() { + return normalMatrix; + } + + @Override + protected int overlay() { + return overlay; + } }; private int brightness(BlockPos pos) { if (blockInfo.blockView == null) { - return 15 << 20 | 15 << 4; + return LightmapTextureManager.MAX_LIGHT_COORDINATE; } return WorldRenderer.getLightmapCoordinates(blockInfo.blockView, blockInfo.blockView.getBlockState(pos), pos); @@ -119,27 +135,6 @@ public class BlockRenderContext extends AbstractRenderContext implements RenderC return didOutput; } - private class MeshConsumer extends AbstractMeshConsumer { - MeshConsumer(BlockRenderInfo blockInfo, Function bufferFunc, AoCalculator aoCalc, QuadTransform transform) { - super(blockInfo, bufferFunc, aoCalc, transform); - } - - @Override - protected Matrix4f matrix() { - return matrix; - } - - @Override - protected Matrix3f normalMatrix() { - return normalMatrix; - } - - @Override - protected int overlay() { - return overlay; - } - } - @Override public Consumer meshConsumer() { return meshConsumer; diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java index fe1b80426..2f4ea7615 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/ChunkRenderInfo.java @@ -25,8 +25,8 @@ import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.render.chunk.BlockBufferBuilderStorage; -import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData; import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk; +import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData; import net.minecraft.client.render.chunk.ChunkRendererRegion; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockRenderView; diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/CompatibilityHelper.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/CompatibilityHelper.java deleted file mode 100644 index 1c275603d..000000000 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/impl/client/indigo/renderer/render/CompatibilityHelper.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016, 2017, 2018, 2019 FabricMC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.fabricmc.fabric.impl.client.indigo.renderer.render; - -import net.fabricmc.fabric.impl.client.indigo.Indigo; -import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat; - -/** - * Controls 1x warning for vanilla quad vertex format when running in compatibility mode. - */ -public abstract class CompatibilityHelper { - private CompatibilityHelper() { } - - private static boolean logCompatibilityWarning = true; - - private static boolean isCompatible(int[] vertexData) { - final boolean result = vertexData.length == EncodingFormat.QUAD_STRIDE; - - if (!result && logCompatibilityWarning) { - logCompatibilityWarning = false; - Indigo.LOGGER.warn("[Indigo] Encountered baked quad with non-standard vertex format. Some blocks will not be rendered"); - } - - return result; - } - - public static boolean canRender(int[] vertexData) { - return !Indigo.ENSURE_VERTEX_FORMAT_COMPATIBILITY || isCompatible(vertexData); - } -} 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 c1fb12f9a..1af497c06 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 @@ -22,7 +22,9 @@ import java.util.function.Consumer; import java.util.function.Supplier; import net.minecraft.block.BlockState; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.color.item.ItemColors; +import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayers; import net.minecraft.client.render.TexturedRenderLayers; @@ -31,20 +33,19 @@ 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.Mode; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.math.Vec3f; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Matrix4f; +import net.minecraft.util.math.Vec3f; 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; import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; 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.helper.ColorHelper; @@ -54,10 +55,8 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; /** * The render context used for item rendering. - * Does not implement emissive lighting for sake - * of simplicity in the default renderer. */ -public class ItemRenderContext extends AbstractRenderContext implements RenderContext { +public class ItemRenderContext extends AbstractRenderContext { /** Value vanilla uses for item rendering. The only sensible choice, of course. */ private static final long ITEM_RANDOM_SEED = 42L; @@ -69,127 +68,82 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo private final ItemColors colorMap; private final Random random = new Random(); - private final Consumer fallbackConsumer; private final Vec3f normalVec = new Vec3f(); - private MatrixStack matrixStack; - private Matrix4f matrix; - private VertexConsumerProvider vertexConsumerProvider; - private VertexConsumer modelVertexConsumer; - private BlendMode quadBlendMode; - private VertexConsumer quadVertexConsumer; - private Mode transformMode; - private int lightmap; - private int overlay; - private ItemStack itemStack; - private VanillaQuadHandler vanillaHandler; - private final Supplier randomSupplier = () -> { - final Random result = random; - result.setSeed(ITEM_RANDOM_SEED); + random.setSeed(ITEM_RANDOM_SEED); return random; }; - private final int[] quadData = new int[EncodingFormat.TOTAL_STRIDE]; + private final Maker editorQuad = new Maker(); + private final MeshConsumer meshConsumer = new MeshConsumer(); + private final FallbackConsumer fallbackConsumer = new FallbackConsumer(); + + private ItemStack itemStack; + private Mode transformMode; + private MatrixStack matrixStack; + private VertexConsumerProvider vertexConsumerProvider; + private int lightmap; + private VanillaQuadHandler vanillaHandler; + + private boolean isDefaultTranslucent; + private boolean isTranslucentDirect; + private VertexConsumer translucentVertexConsumer; + private VertexConsumer cutoutVertexConsumer; + private VertexConsumer modelVertexConsumer; public ItemRenderContext(ItemColors colorMap) { this.colorMap = colorMap; - fallbackConsumer = this::fallbackConsumer; } - public void renderModel(ItemStack itemStack, Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int lightmap, int overlay, FabricBakedModel model, VanillaQuadHandler vanillaHandler) { + public void renderModel(ItemStack itemStack, Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int lightmap, int overlay, BakedModel model, VanillaQuadHandler vanillaHandler) { + this.itemStack = itemStack; + this.transformMode = transformMode; + this.matrixStack = matrixStack; + this.vertexConsumerProvider = vertexConsumerProvider; this.lightmap = lightmap; this.overlay = overlay; - this.itemStack = itemStack; - this.vertexConsumerProvider = vertexConsumerProvider; - this.matrixStack = matrixStack; - this.transformMode = transformMode; this.vanillaHandler = vanillaHandler; - quadBlendMode = BlendMode.DEFAULT; - modelVertexConsumer = selectVertexConsumer(RenderLayers.getItemLayer(itemStack, transformMode != ModelTransformation.Mode.GROUND)); + computeOutputInfo(); matrixStack.push(); - ((BakedModel) model).getTransformation().getTransformation(transformMode).apply(invert, matrixStack); + model.getTransformation().getTransformation(transformMode).apply(invert, matrixStack); matrixStack.translate(-0.5D, -0.5D, -0.5D); matrix = matrixStack.peek().getPositionMatrix(); normalMatrix = matrixStack.peek().getNormalMatrix(); - model.emitItemQuads(itemStack, randomSupplier, this); + ((FabricBakedModel) model).emitItemQuads(itemStack, randomSupplier, this); matrixStack.pop(); - this.matrixStack = null; this.itemStack = null; + this.matrixStack = null; this.vanillaHandler = null; + translucentVertexConsumer = null; + cutoutVertexConsumer = 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 = transformMode == ModelTransformation.Mode.GUI ? TexturedRenderLayers.getEntityTranslucentCull() : layerIn; - return ItemRenderer.getArmorGlintConsumer(vertexConsumerProvider, layer, true, itemStack.hasGlint()); - } + private void computeOutputInfo() { + isDefaultTranslucent = true; + isTranslucentDirect = true; - private class Maker extends MutableQuadViewImpl implements QuadEmitter { - { - data = quadData; - clear(); + Item item = itemStack.getItem(); + + if (item instanceof BlockItem blockItem) { + BlockState state = blockItem.getBlock().getDefaultState(); + RenderLayer renderLayer = RenderLayers.getBlockLayer(state); + + if (renderLayer != RenderLayer.getTranslucent()) { + isDefaultTranslucent = false; + } + + if (transformMode != Mode.GUI && !transformMode.isFirstPerson()) { + isTranslucentDirect = false; + } } - @Override - public Maker emit() { - computeGeometry(); - renderQuad(); - clear(); - return this; - } - } - - private final Maker editorQuad = new Maker(); - - private final Consumer meshConsumer = (mesh) -> { - final MeshImpl m = (MeshImpl) mesh; - final int[] data = m.data(); - final int limit = data.length; - int index = 0; - - while (index < limit) { - System.arraycopy(data, index, editorQuad.data(), 0, EncodingFormat.TOTAL_STRIDE); - editorQuad.load(); - index += EncodingFormat.TOTAL_STRIDE; - renderQuad(); - } - }; - - private int indexColor() { - final int colorIndex = editorQuad.colorIndex(); - return colorIndex == -1 ? -1 : (colorMap.getColor(itemStack, colorIndex) | 0xFF000000); - } - - private void renderQuad() { - final MutableQuadViewImpl quad = editorQuad; - - if (!transform(editorQuad)) { - return; - } - - 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; - - for (int i = 0; i < 4; i++) { - int c = quad.spriteColor(i, 0); - c = ColorHelper.multiplyColor(quadColor, c); - quad.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(c)); - quad.lightmap(i, ColorHelper.maxBrightness(quad.lightmap(i), lightmap)); - } - - AbstractQuadRenderer.bufferQuad(quadVertexConsumer(mat.blendMode(0)), quad, matrix, overlay, normalMatrix, normalVec); + modelVertexConsumer = quadVertexConsumer(BlendMode.DEFAULT); } /** @@ -198,25 +152,157 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo * translucent are mapped to cutout. */ private VertexConsumer quadVertexConsumer(BlendMode blendMode) { + boolean translucent; + 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; + translucent = isDefaultTranslucent; } else { - quadVertexConsumer = selectVertexConsumer(TexturedRenderLayers.getEntityCutout()); - quadBlendMode = BlendMode.CUTOUT; + translucent = blendMode == BlendMode.TRANSLUCENT; } - return quadVertexConsumer; + if (translucent) { + if (translucentVertexConsumer == null) { + if (isTranslucentDirect) { + translucentVertexConsumer = ItemRenderer.getDirectItemGlintConsumer(vertexConsumerProvider, TexturedRenderLayers.getEntityTranslucentCull(), true, itemStack.hasGlint()); + } else if (MinecraftClient.isFabulousGraphicsOrBetter()) { + translucentVertexConsumer = ItemRenderer.getItemGlintConsumer(vertexConsumerProvider, TexturedRenderLayers.getItemEntityTranslucentCull(), true, itemStack.hasGlint()); + } else { + translucentVertexConsumer = ItemRenderer.getItemGlintConsumer(vertexConsumerProvider, TexturedRenderLayers.getEntityTranslucentCull(), true, itemStack.hasGlint()); + } + } + + return translucentVertexConsumer; + } else { + if (cutoutVertexConsumer == null) { + cutoutVertexConsumer = ItemRenderer.getDirectItemGlintConsumer(vertexConsumerProvider, TexturedRenderLayers.getEntityCutout(), true, itemStack.hasGlint()); + } + + return cutoutVertexConsumer; + } + } + + private void bufferQuad(MutableQuadViewImpl quad, BlendMode blendMode) { + AbstractQuadRenderer.bufferQuad(quadVertexConsumer(blendMode), quad, matrix, overlay, normalMatrix, normalVec); + } + + private void colorizeQuad(MutableQuadViewImpl q, int colorIndex) { + if (colorIndex == -1) { + for (int i = 0; i < 4; i++) { + q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(q.spriteColor(i, 0))); + } + } else { + final int itemColor = 0xFF000000 | colorMap.getColor(itemStack, colorIndex); + + for (int i = 0; i < 4; i++) { + q.spriteColor(i, 0, ColorHelper.swapRedBlueIfNeeded(ColorHelper.multiplyColor(itemColor, q.spriteColor(i, 0)))); + } + } + } + + private void renderQuad(MutableQuadViewImpl quad, BlendMode blendMode, int colorIndex) { + colorizeQuad(quad, colorIndex); + + final int lightmap = this.lightmap; + + for (int i = 0; i < 4; i++) { + quad.lightmap(i, ColorHelper.maxBrightness(quad.lightmap(i), lightmap)); + } + + bufferQuad(quad, blendMode); + } + + private void renderQuadEmissive(MutableQuadViewImpl quad, BlendMode blendMode, int colorIndex) { + colorizeQuad(quad, colorIndex); + + for (int i = 0; i < 4; i++) { + quad.lightmap(i, LightmapTextureManager.MAX_LIGHT_COORDINATE); + } + + bufferQuad(quad, blendMode); + } + + private void renderMeshQuad(MutableQuadViewImpl quad) { + if (!transform(quad)) { + return; + } + + final RenderMaterialImpl.Value mat = quad.material(); + + final int colorIndex = mat.disableColorIndex(0) ? -1 : quad.colorIndex(); + final BlendMode blendMode = mat.blendMode(0); + + if (mat.emissive(0)) { + renderQuadEmissive(quad, blendMode, colorIndex); + } else { + renderQuad(quad, blendMode, colorIndex); + } + } + + private class Maker extends MutableQuadViewImpl implements QuadEmitter { + { + data = new int[EncodingFormat.TOTAL_STRIDE]; + clear(); + } + + @Override + public Maker emit() { + computeGeometry(); + renderMeshQuad(this); + clear(); + return this; + } + } + + private class MeshConsumer implements Consumer { + @Override + public void accept(Mesh mesh) { + final MeshImpl m = (MeshImpl) mesh; + final int[] data = m.data(); + final int limit = data.length; + int index = 0; + + while (index < limit) { + System.arraycopy(data, index, editorQuad.data(), 0, EncodingFormat.TOTAL_STRIDE); + editorQuad.load(); + index += EncodingFormat.TOTAL_STRIDE; + renderMeshQuad(editorQuad); + } + } + } + + private class FallbackConsumer implements Consumer { + @Override + public void accept(BakedModel model) { + 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 quads = model.getQuads(null, 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); + } + } + } + } else { + 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 @@ -224,32 +310,6 @@ public class ItemRenderContext extends AbstractRenderContext implements RenderCo return meshConsumer; } - private void fallbackConsumer(BakedModel model) { - 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++) { - random.setSeed(ITEM_RANDOM_SEED); - final Direction cullFace = ModelHelper.faceFromIndex(i); - renderFallbackWithTransform(model.getQuads((BlockState) null, cullFace, random), cullFace); - } - } else { - vanillaHandler.accept(model, itemStack, lightmap, overlay, matrixStack, modelVertexConsumer); - } - } - - private void renderFallbackWithTransform(List quads, Direction cullFace) { - if (quads.isEmpty()) { - return; - } - - final Maker editorQuad = this.editorQuad; - - for (final BakedQuad q : quads) { - editorQuad.fromVanilla(q, IndigoRenderer.MATERIAL_STANDARD, cullFace); - renderQuad(); - } - } - @Override public Consumer fallbackConsumer() { 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 8c39fed0f..25162bbd3 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 @@ -58,10 +58,8 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl; * manipulating the data via NIO. */ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer implements Consumer { - private static Value MATERIAL_FLAT = (Value) IndigoRenderer.INSTANCE.materialFinder().disableAo(0, true).find(); - private static Value MATERIAL_SHADED = (Value) IndigoRenderer.INSTANCE.materialFinder().find(); - - private final int[] editorBuffer = new int[EncodingFormat.TOTAL_STRIDE]; + 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(); TerrainFallbackConsumer(BlockRenderInfo blockInfo, Function bufferFunc, AoCalculator aoCalc, QuadTransform transform) { super(blockInfo, bufferFunc, aoCalc, transform); @@ -69,7 +67,7 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() { { - data = editorBuffer; + data = new int[EncodingFormat.TOTAL_STRIDE]; material(MATERIAL_SHADED); } @@ -86,36 +84,21 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple final Value defaultMaterial = blockInfo.defaultAo && model.useAmbientOcclusion() ? MATERIAL_SHADED : MATERIAL_FLAT; final BlockState blockState = blockInfo.blockState; - for (int i = 0; i < 6; i++) { - final Direction face = ModelHelper.faceFromIndex(i); - final List quads = model.getQuads(blockState, face, random.get()); + for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) { + final Direction cullFace = ModelHelper.faceFromIndex(i); + final List quads = model.getQuads(blockState, cullFace, random.get()); final int count = quads.size(); if (count != 0) { for (int j = 0; j < count; j++) { final BakedQuad q = quads.get(j); - renderQuad(q, face, defaultMaterial); + renderQuad(q, cullFace, defaultMaterial); } } } - - final List quads = model.getQuads(blockState, null, random.get()); - final int count = quads.size(); - - if (count != 0) { - for (int j = 0; j < count; j++) { - final BakedQuad q = quads.get(j); - renderQuad(q, null, defaultMaterial); - } - } } private void renderQuad(BakedQuad quad, Direction cullFace, Value defaultMaterial) { - // TODO: should remove in 1.17 cycle, was for OF compat only - if (!CompatibilityHelper.canRender(quad.getVertexData())) { - return; - } - final MutableQuadViewImpl editorQuad = this.editorQuad; editorQuad.fromVanilla(quad, defaultMaterial, cullFace); @@ -132,16 +115,16 @@ public abstract class TerrainFallbackConsumer extends AbstractQuadRenderer imple if (!editorQuad.material().disableAo(0)) { // needs to happen before offsets are applied aoCalc.compute(editorQuad, true); - tesselateSmooth(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex()); + 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 tesselateFlat() because needs to happen before offsets are applied + // Can't rely on lazy computation in tessellateFlat() because needs to happen before offsets are applied editorQuad.geometryFlags(); } - tesselateFlat(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex()); + tessellateFlat(editorQuad, blockInfo.defaultLayer, editorQuad.colorIndex()); } } } 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 d272dcee1..25dc07a23 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 @@ -20,17 +20,17 @@ import java.util.function.Consumer; import net.minecraft.block.BlockState; import net.minecraft.client.render.chunk.BlockBufferBuilderStorage; -import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData; import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk; +import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData; import net.minecraft.client.render.chunk.ChunkRendererRegion; import net.minecraft.client.render.model.BakedModel; -import net.minecraft.util.math.Matrix4f; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.crash.CrashException; import net.minecraft.util.crash.CrashReport; import net.minecraft.util.crash.CrashReportSection; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Matrix3f; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.Matrix4f; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -43,8 +43,9 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator; * Dispatches calls from models during chunk rebuild to the appropriate consumer, * and holds/manages all of the state needed by them. */ -public class TerrainRenderContext extends AbstractRenderContext implements RenderContext { +public class TerrainRenderContext extends AbstractRenderContext { public static final ThreadLocal POOL = ThreadLocal.withInitial(TerrainRenderContext::new); + private final TerrainBlockRenderInfo blockInfo = new TerrainBlockRenderInfo(); private final ChunkRenderInfo chunkInfo = new ChunkRenderInfo(); private final AoCalculator aoCalc = new AoCalculator(blockInfo, chunkInfo::cachedBrightness, chunkInfo::cachedAoLevel); @@ -83,10 +84,9 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende } }; - public TerrainRenderContext prepare(ChunkRendererRegion blockView, BuiltChunk chunkRenderer, ChunkData chunkData, BlockBufferBuilderStorage builders) { + public void prepare(ChunkRendererRegion blockView, BuiltChunk chunkRenderer, ChunkData chunkData, BlockBufferBuilderStorage builders) { blockInfo.setBlockView(blockView); chunkInfo.prepare(blockView, chunkRenderer, chunkData, builders); - return this; } public void release() { @@ -95,7 +95,7 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende } /** Called from chunk renderer hook. */ - public boolean tesselateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, MatrixStack matrixStack) { + public boolean tessellateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, MatrixStack matrixStack) { this.matrix = matrixStack.peek().getPositionMatrix(); this.normalMatrix = matrixStack.peek().getNormalMatrix(); @@ -103,11 +103,11 @@ public class TerrainRenderContext extends AbstractRenderContext implements Rende aoCalc.clear(); blockInfo.prepareForBlock(blockState, blockPos, model.useAmbientOcclusion()); ((FabricBakedModel) model).emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); - } catch (Throwable var9) { - CrashReport crashReport_1 = CrashReport.create(var9, "Tesselating block in world - Indigo Renderer"); - CrashReportSection crashReportElement_1 = crashReport_1.addElement("Block being tesselated"); - CrashReportSection.addBlockInfo(crashReportElement_1, chunkInfo.blockView, blockPos, blockState); - throw new CrashException(crashReport_1); + } catch (Throwable throwable) { + CrashReport crashReport = CrashReport.create(throwable, "Tessellating block in world - Indigo Renderer"); + CrashReportSection crashReportSection = crashReport.addElement("Block being tessellated"); + CrashReportSection.addBlockInfo(crashReportSection, chunkInfo.blockView, blockPos, blockState); + throw new CrashException(crashReport); } // false because we've already marked the chunk as populated - caller doesn't need to diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinAmbientOcclusionCalculator.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinAmbientOcclusionCalculator.java index 9233b7545..b893a1186 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinAmbientOcclusionCalculator.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinAmbientOcclusionCalculator.java @@ -30,8 +30,10 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessAmbientOcc @Mixin(targets = "net.minecraft.client.render.block.BlockModelRenderer$AmbientOcclusionCalculator") public abstract class MixinAmbientOcclusionCalculator implements AccessAmbientOcclusionCalculator { - @Shadow private float[] brightness; - @Shadow private int[] light; + @Shadow + private float[] brightness; + @Shadow + private int[] light; @Shadow public abstract void apply(BlockRenderView blockRenderView, BlockState blockState, BlockPos pos, Direction face, float[] aoData, BitSet controlBits, boolean shade); 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 9b0891c5a..5ca38118a 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 @@ -21,6 +21,7 @@ import java.util.Random; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -42,15 +43,16 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderContext @Mixin(BlockModelRenderer.class) public abstract class MixinBlockModelRenderer implements AccessBlockModelRenderer { + @Unique + private final ThreadLocal fabric_contexts = ThreadLocal.withInitial(BlockRenderContext::new); + @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 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(); + BlockRenderContext context = fabric_contexts.get(); // 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)); } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRebuildTask.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRebuildTask.java index d0554b337..694a28eb1 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRebuildTask.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRebuildTask.java @@ -29,7 +29,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.block.BlockRenderManager; import net.minecraft.client.render.chunk.BlockBufferBuilderStorage; @@ -64,14 +63,14 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderConte * (Though they can use these as an example if they wish.) */ @Mixin(targets = "net.minecraft.client.render.chunk.ChunkBuilder$BuiltChunk$RebuildTask") -public class MixinChunkRebuildTask { +public abstract class MixinChunkRebuildTask { @Shadow protected ChunkRendererRegion region; @Shadow protected BuiltChunk field_20839; @Inject(at = @At("HEAD"), method = "Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask;render(FFFLnet/minecraft/client/render/chunk/ChunkBuilder$ChunkData;Lnet/minecraft/client/render/chunk/BlockBufferBuilderStorage;)Ljava/util/Set;") - private void hookChunkBuild(float float_1, float float_2, float float_3, ChunkBuilder.ChunkData renderData, BlockBufferBuilderStorage builder, CallbackInfoReturnable> ci) { + private void hookChunkBuild(float cameraX, float cameraY, float cameraZ, ChunkBuilder.ChunkData renderData, BlockBufferBuilderStorage builder, CallbackInfoReturnable> ci) { ChunkRendererRegion region = this.region; if (region != null) { @@ -85,14 +84,14 @@ public class MixinChunkRebuildTask { * This is the hook that actually implements the rendering API for terrain rendering. * *

It's unusual to have a @Redirect in a Fabric library, but in this case - * it is our explicit intention that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)} + * it is our explicit intention that {@link BlockRenderManager#renderBlock(BlockState, BlockPos, BlockRenderView, MatrixStack, VertexConsumer, boolean, Random)} * does not execute for models that will be rendered by our renderer. * *

Any mod that wants to redirect this specific call is likely also a renderer, in which case this * renderer should not be present, or the mod should probably instead be relying on the renderer API * which was specifically created to provide for enhanced terrain rendering. * - *

Note also that {@link BlockRenderManager#tesselateBlock(BlockState, BlockPos, BlockRenderView, BufferBuilder, Random)} + *

Note also that {@link BlockRenderManager#renderBlock(BlockState, BlockPos, BlockRenderView, MatrixStack, VertexConsumer, boolean, Random)} * IS called if the block render type is something other than {@link BlockRenderType#MODEL}. * Normally this does nothing but will allow mods to create rendering hooks that are * driven off of render type. (Not recommended or encouraged, but also not prevented.) @@ -106,7 +105,7 @@ public class MixinChunkRebuildTask { if (Indigo.ALWAYS_TESSELATE_INDIGO || !((FabricBakedModel) model).isVanillaAdapter()) { Vec3d vec3d = blockState.getModelOffset(blockView, blockPos); matrix.translate(vec3d.x, vec3d.y, vec3d.z); - return ((AccessChunkRendererRegion) blockView).fabric_getRenderer().tesselateBlock(blockState, blockPos, model, matrix); + return ((AccessChunkRendererRegion) blockView).fabric_getRenderer().tessellateBlock(blockState, blockPos, model, matrix); } } diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRenderData.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRenderData.java index 383b54639..5e7e677ed 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRenderData.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRenderData.java @@ -27,7 +27,7 @@ import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData; import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessChunkRendererData; @Mixin(ChunkData.class) -public class MixinChunkRenderData implements AccessChunkRendererData { +public abstract class MixinChunkRenderData implements AccessChunkRendererData { @Shadow private Set initializedLayers; @Shadow diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRendererRegion.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRendererRegion.java index ffebba643..7b973c71d 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRendererRegion.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinChunkRendererRegion.java @@ -17,6 +17,7 @@ package net.fabricmc.fabric.mixin.client.indigo.renderer; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import net.minecraft.client.render.chunk.ChunkRendererRegion; @@ -25,6 +26,7 @@ import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderConte @Mixin(ChunkRendererRegion.class) public abstract class MixinChunkRendererRegion implements AccessChunkRendererRegion { + @Unique private TerrainRenderContext fabric_renderer; @Override diff --git a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinItemRenderer.java b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinItemRenderer.java index 2bbb314bb..f88636795 100644 --- a/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinItemRenderer.java +++ b/fabric-renderer-indigo/src/main/java/net/fabricmc/fabric/mixin/client/indigo/renderer/MixinItemRenderer.java @@ -18,6 +18,7 @@ package net.fabricmc.fabric.mixin.client.indigo.renderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -32,29 +33,29 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; -import net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext; -import net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.VanillaQuadHandler; import net.fabricmc.fabric.impl.client.indigo.renderer.accessor.AccessItemRenderer; import net.fabricmc.fabric.impl.client.indigo.renderer.render.IndigoQuadHandler; +import net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext; +import net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.VanillaQuadHandler; @Mixin(ItemRenderer.class) public abstract class MixinItemRenderer implements AccessItemRenderer { - @Shadow - protected abstract void renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrixStack, VertexConsumer buffer); - @Shadow protected ItemColors colors; - private final VanillaQuadHandler vanillaHandler = new IndigoQuadHandler(this); + @Unique + private final ThreadLocal fabric_contexts = ThreadLocal.withInitial(() -> new ItemRenderContext(colors)); - private final ThreadLocal CONTEXTS = ThreadLocal.withInitial(() -> new ItemRenderContext(colors)); + @Unique + private final VanillaQuadHandler fabric_vanillaHandler = new IndigoQuadHandler(this); + + @Shadow + protected abstract void renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrixStack, VertexConsumer buffer); @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) - public void hook_method_23179(ItemStack stack, ModelTransformation.Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, BakedModel model, CallbackInfo ci) { - final FabricBakedModel fabricModel = (FabricBakedModel) model; - - if (!(stack.isEmpty() || fabricModel.isVanillaAdapter())) { - CONTEXTS.get().renderModel(stack, transformMode, invert, matrixStack, vertexConsumerProvider, light, overlay, fabricModel, vanillaHandler); + public void hook_renderItem(ItemStack stack, ModelTransformation.Mode transformMode, boolean invert, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int light, int overlay, BakedModel model, CallbackInfo ci) { + if (!stack.isEmpty() && !((FabricBakedModel) model).isVanillaAdapter()) { + fabric_contexts.get().renderModel(stack, transformMode, invert, matrixStack, vertexConsumerProvider, light, overlay, model, fabric_vanillaHandler); ci.cancel(); } }