mirror of
https://github.com/FabricMC/fabric
synced 2026-08-19 06:26:07 -04:00
Port renderer api and indigo to 26.2 (#5406)
* Ported renderer api and indigo to 26.2-snapshot-8 This commit updates the `fabric-renderer-api-v1` and `fabric-renderer-indigo` modules to 26.2-snapshot-8. The code was changed to remove all usages of `MultiBufferSource`, and use the new `RenderTypeFeatureRenderer` system instead. * Fixed coding style and javadoc * Replaced a static assignment with a ScopedValue * Implemented outline rendertype for models & some cleanup * Fixes, cleanup, optimizations * Fix block breaking and checkstyle * Require renderers to implement extended block model feature renderer * refactor!: move submits to `submit` sub-package --------- Co-authored-by: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Co-authored-by: sylv256 <contact@sylv.gay>
This commit is contained in:
parent
3568f873c4
commit
e73ab60dfd
28 changed files with 861 additions and 641 deletions
|
|
@ -25,8 +25,8 @@ import net.minecraft.client.renderer.block.BlockQuadOutput;
|
|||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
|
||||
import net.minecraft.client.renderer.chunk.SectionCompiler;
|
||||
import net.minecraft.client.renderer.feature.BlockModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.FeatureRenderDispatcher;
|
||||
import net.minecraft.client.renderer.feature.FeatureRenderer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
|
@ -36,7 +36,8 @@ import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableMesh;
|
|||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.AltModelBlockRenderer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricSubmitNodeCollection;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedBlockModelSubmit;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedItemSubmit;
|
||||
import net.fabricmc.fabric.impl.client.renderer.RendererManager;
|
||||
|
||||
/**
|
||||
|
|
@ -54,9 +55,9 @@ import net.fabricmc.fabric.impl.client.renderer.RendererManager;
|
|||
* {@link AltModelBlockRenderer#tesselateBlock(QuadEmitter, float, float, float, BlockAndTintGetter, BlockPos, BlockState, BlockStateModel, long)},
|
||||
* respectively, instead.
|
||||
*
|
||||
* <p>Renderers must patch {@link ItemFeatureRenderer} to support
|
||||
* {@link FabricSubmitNodeCollection#getExtendedItemSubmits()}. {@link BlockModelFeatureRenderer} is automatically patched
|
||||
* to support {@link FabricSubmitNodeCollection#getExtendedBlockModelSubmits()} and {@link BlockStateModel#emitQuads}.
|
||||
* <p>Renderers must implement {@link FeatureRenderer}s to support {@link ExtendedBlockModelSubmit}
|
||||
* and {@link ExtendedItemSubmit}. This is typically done by adding them to
|
||||
* {@link FeatureRenderDispatcher}'s map with a mixin.
|
||||
*/
|
||||
public interface Renderer {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -59,7 +59,22 @@ public interface FabricOrderedSubmitNodeCollector {
|
|||
}
|
||||
|
||||
/**
|
||||
* Alternative to {@link OrderedSubmitNodeCollector#submitItem(PoseStack, ItemDisplayContext, int, int, int, int[], List, ItemStackRenderState.FoilType)} that also accepts a {@link MeshView}.
|
||||
* Alternative to
|
||||
* {@link OrderedSubmitNodeCollector#submitBreakingBlockModel(PoseStack, List, int)} that also
|
||||
* accepts a {@link Mesh}.
|
||||
*
|
||||
* @param poseStack the pose stack
|
||||
* @param parts the vanilla {@linkplain BlockStateModelPart parts}
|
||||
* @param mesh the mesh
|
||||
* @param progress the breaking progress
|
||||
*/
|
||||
default void submitBreakingBlockModel(PoseStack poseStack, List<BlockStateModelPart> parts, Mesh mesh, int progress) {
|
||||
((OrderedSubmitNodeCollector) this).submitBreakingBlockModel(poseStack, parts, progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative to {@link OrderedSubmitNodeCollector#submitItem(PoseStack, ItemDisplayContext, int, int, int, int[], List, ItemStackRenderState.FoilType)}
|
||||
* that also accepts a {@link MeshView}.
|
||||
*
|
||||
* @param poseStack the pose stack
|
||||
* @param displayContext the item display context
|
||||
|
|
|
|||
|
|
@ -1,72 +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.api.client.renderer.v1.render;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.feature.BlockModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MeshView;
|
||||
|
||||
/**
|
||||
* Note: This interface is automatically implemented on {@link SubmitNodeCollection} via Mixin and interface injection.
|
||||
*/
|
||||
public interface FabricSubmitNodeCollection {
|
||||
/**
|
||||
* @return {@linkplain ExtendedBlockModelSubmit extended block model submits} in this
|
||||
* {@link SubmitNodeCollection}.
|
||||
*/
|
||||
default List<ExtendedBlockModelSubmit> getExtendedBlockModelSubmits() {
|
||||
throw new UnsupportedOperationException("Implemented via Mixin.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@linkplain ExtendedItemSubmit extended item submits} in this
|
||||
* {@link SubmitNodeCollection}.
|
||||
*/
|
||||
default List<ExtendedItemSubmit> getExtendedItemSubmits() {
|
||||
throw new UnsupportedOperationException("Implemented via Mixin.");
|
||||
}
|
||||
|
||||
// CHECKSTYLE:OFF MatchXpath
|
||||
/**
|
||||
* An alternative to {@link BlockModelFeatureRenderer.Submit} that accepts a {@link Mesh}.
|
||||
*/
|
||||
record ExtendedBlockModelSubmit(PoseStack.Pose pose, Function<ChunkSectionLayer, RenderType> renderTypeFunction, boolean translucent, List<BlockStateModelPart> modelParts, @Nullable Mesh mesh, int[] tintLayers, int lightCoords, int overlayCoords, int outlineColor) {
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative to {@link ItemFeatureRenderer.Submit} that accepts a {@link MeshView}.
|
||||
*/
|
||||
record ExtendedItemSubmit(PoseStack.Pose pose, ItemDisplayContext displayContext, int lightCoords, int overlayCoords, int outlineColor, int[] tintLayers, List<BakedQuad> quads, MeshView mesh, ItemStackRenderState.FoilType foilType) {
|
||||
}
|
||||
|
||||
// CHECKSTYLE:ON MatchXpath
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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.api.client.renderer.v1.render.submit;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.feature.BlockModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.FeatureRendererType;
|
||||
import net.minecraft.client.renderer.feature.submit.TranslucentSubmit;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.Mesh;
|
||||
|
||||
/**
|
||||
* An alternative to {@link BlockModelFeatureRenderer.Submit} that optionally accepts a {@link Mesh}.
|
||||
*/
|
||||
//CHECKSTYLE.OFF: MatchXpath
|
||||
public record ExtendedBlockModelSubmit(PoseStack.Pose pose,
|
||||
Function<ChunkSectionLayer, @Nullable RenderType> renderTypeFunction,
|
||||
List<BlockStateModelPart> modelParts, @Nullable Mesh mesh,
|
||||
int[] tintLayers, int lightCoords, int overlayCoords,
|
||||
int tintColor, PoseStack.@Nullable Pose sheetedDecalPose) implements TranslucentSubmit {
|
||||
//CHECKSTYLE.ON: MatchXpath
|
||||
public static final FeatureRendererType<ExtendedBlockModelSubmit> TYPE = FeatureRendererType.create("Extended Block Model");
|
||||
|
||||
@Override
|
||||
public float distanceToCameraSq() {
|
||||
return TranslucentSubmit.computeDistanceToCameraSq(pose.pose(), 0.5F, 0.5F, 0.5F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureRendererType<? extends TranslucentSubmit> featureType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.api.client.renderer.v1.render.submit;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.client.renderer.feature.FeatureRendererType;
|
||||
import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.submit.TranslucentSubmit;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MeshView;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadView;
|
||||
|
||||
/**
|
||||
* An alternative to {@link ItemFeatureRenderer.Submit} that accepts a {@link MeshView}.
|
||||
*/
|
||||
//CHECKSTYLE.OFF: MatchXpath
|
||||
public record ExtendedItemSubmit(PoseStack.Pose pose, ItemDisplayContext displayContext,
|
||||
int lightCoords, int overlayCoords, int outlineColor,
|
||||
int[] tintLayers, List<BakedQuad> quads, MeshView mesh,
|
||||
ItemStackRenderState.FoilType foilType) implements TranslucentSubmit {
|
||||
//CHECKSTYLE.ON: MatchXpath
|
||||
public static final FeatureRendererType<ExtendedItemSubmit> TYPE = FeatureRendererType.create("Extended Item");
|
||||
|
||||
public boolean hasTranslucency() {
|
||||
for (BakedQuad quad : quads()) {
|
||||
if (quad.materialInfo().itemRenderType().hasBlending()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var quadInspector = new Consumer<QuadView>() {
|
||||
private boolean translucent = false;
|
||||
|
||||
@Override
|
||||
public void accept(QuadView quad) {
|
||||
if (quad.itemRenderType().hasBlending()) {
|
||||
translucent = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
mesh.forEach(quadInspector);
|
||||
|
||||
return quadInspector.translucent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float distanceToCameraSq() {
|
||||
return TranslucentSubmit.computeDistanceToCameraSq(pose.pose());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureRendererType<? extends TranslucentSubmit> featureType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +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.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.OutlineBufferSource;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
|
||||
public class BlockModelBufferCache {
|
||||
private final MultiBufferSource.BufferSource bufferSource;
|
||||
private final OutlineBufferSource outlineBufferSource;
|
||||
|
||||
private int outlineColor;
|
||||
|
||||
@Nullable
|
||||
private RenderType lastRenderType;
|
||||
@Nullable
|
||||
private VertexConsumer lastBuffer;
|
||||
@Nullable
|
||||
private VertexConsumer lastOutlineBuffer;
|
||||
|
||||
public BlockModelBufferCache(MultiBufferSource.BufferSource bufferSource, OutlineBufferSource outlineBufferSource) {
|
||||
this.bufferSource = bufferSource;
|
||||
this.outlineBufferSource = outlineBufferSource;
|
||||
}
|
||||
|
||||
public void outlineColor(int outlineColor) {
|
||||
this.outlineColor = outlineColor;
|
||||
lastRenderType = null;
|
||||
}
|
||||
|
||||
public VertexConsumer getBuffer(RenderType renderType) {
|
||||
if (renderType != lastRenderType) {
|
||||
update(renderType);
|
||||
}
|
||||
|
||||
return lastBuffer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VertexConsumer getOutlineBuffer(RenderType renderType) {
|
||||
if (renderType != lastRenderType) {
|
||||
update(renderType);
|
||||
}
|
||||
|
||||
return lastOutlineBuffer;
|
||||
}
|
||||
|
||||
private void update(RenderType renderType) {
|
||||
lastRenderType = renderType;
|
||||
lastBuffer = bufferSource.getBuffer(renderType);
|
||||
|
||||
if (outlineColor != 0) {
|
||||
outlineBufferSource.setColor(outlineColor);
|
||||
lastOutlineBuffer = outlineBufferSource.getBuffer(renderType);
|
||||
} else {
|
||||
lastOutlineBuffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.renderer;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableQuadView;
|
||||
|
||||
public abstract class MovingBlockQuadConsumer implements Consumer<MutableQuadView> {
|
||||
protected int outlineColor;
|
||||
|
||||
public void outlineColor(int outlineColor) {
|
||||
this.outlineColor = outlineColor;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +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.renderer;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.util.LightCoordsUtil;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableQuadView;
|
||||
|
||||
// Workaround for mixin not allowing referencing members of anonymous classes defined within mixins.
|
||||
// Once that is fixed, this class should be inlined.
|
||||
public final class QuadConsumers {
|
||||
private QuadConsumers() {
|
||||
}
|
||||
|
||||
public static class BlockModel implements Consumer<MutableQuadView> {
|
||||
public int[] tintLayers;
|
||||
public int lightCoords;
|
||||
public int overlayCoords;
|
||||
public PoseStack.Pose pose;
|
||||
public Function<ChunkSectionLayer, RenderType> renderTypeFunction;
|
||||
public BlockModelBufferCache bufferCache;
|
||||
|
||||
@Override
|
||||
public void accept(MutableQuadView quad) {
|
||||
if (quad.emissive()) {
|
||||
quad.lightmap(LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT);
|
||||
} else {
|
||||
quad.minLightmap(lightCoords);
|
||||
}
|
||||
|
||||
int tintIndex = quad.tintIndex();
|
||||
|
||||
if (tintIndex != -1 && tintIndex < tintLayers.length) {
|
||||
quad.multiplyColor(tintLayers[tintIndex]);
|
||||
}
|
||||
|
||||
RenderType renderType = renderTypeFunction.apply(quad.chunkLayer());
|
||||
quad.buffer(overlayCoords, pose, bufferCache.getBuffer(renderType));
|
||||
VertexConsumer outlineBuffer = bufferCache.getOutlineBuffer(renderType);
|
||||
|
||||
if (outlineBuffer != null) {
|
||||
quad.buffer(overlayCoords, pose, outlineBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BreakingBlockModel implements Consumer<MutableQuadView> {
|
||||
public PoseStack.Pose pose;
|
||||
public VertexConsumer buffer;
|
||||
|
||||
@Override
|
||||
public void accept(MutableQuadView quad) {
|
||||
quad.lightmap(LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT);
|
||||
quad.buffer(OverlayTexture.NO_OVERLAY, pose, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,18 +20,20 @@ import java.util.function.Predicate;
|
|||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.block.dispatch.ModelState;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.ModelBaker;
|
||||
import net.minecraft.client.resources.model.SimpleModelWrapper;
|
||||
|
|
@ -53,8 +55,23 @@ abstract class SimpleModelWrapperMixin implements BlockStateModelPart {
|
|||
@Final
|
||||
private boolean useAmbientOcclusion;
|
||||
|
||||
@Inject(method = "bake", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/geometry/QuadCollection;getAll()Ljava/util/List;"))
|
||||
private static void analyzeMesh(final ModelBaker modelBakery, final Identifier location, final ModelState state, CallbackInfoReturnable<BlockStateModelPart> cir, @Local(name = "geometry") QuadCollection geometry, @Local(name = "forbiddenSprites") LocalRef<Multimap<Identifier, Identifier>> forbiddenSpritesRef) {
|
||||
@Unique
|
||||
private static final ScopedValue<ModelBaker> MODEL_BAKERY = ScopedValue.newInstance();
|
||||
|
||||
@WrapOperation(method = "bake", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/SimpleModelWrapper;findNonBlockSprites(Lnet/minecraft/client/resources/model/geometry/QuadCollection;)Lcom/google/common/collect/Multimap;"))
|
||||
private static @Nullable Multimap<Identifier, Identifier> storeModelBakery(QuadCollection geometry, Operation<Multimap<Identifier, Identifier>> original, @Local(name = "modelBakery") ModelBaker modelBakery) {
|
||||
return ScopedValue.where(MODEL_BAKERY, modelBakery).call(() -> original.call(geometry));
|
||||
}
|
||||
|
||||
@Inject(method = "findNonBlockSprites", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/resources/model/geometry/QuadCollection;getAll()Ljava/util/List;"))
|
||||
private static void analyzeMesh(QuadCollection geometry, CallbackInfoReturnable<Multimap<Identifier, Identifier>> cir, @Local(name = "forbiddenSprites") LocalRef<Multimap<Identifier, Identifier>> forbiddenSpritesRef) {
|
||||
// This can also be called from ModelBakery.MissingModels, but it's maybe not necessary to hook there?
|
||||
if (!MODEL_BAKERY.isBound()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModelBaker modelBakery = MODEL_BAKERY.get();
|
||||
|
||||
if (geometry instanceof MeshQuadCollection meshQuadCollection) {
|
||||
meshQuadCollection.getMesh().forEach(quad -> {
|
||||
if (quad.atlas() != QuadAtlas.BLOCK) {
|
||||
|
|
|
|||
|
|
@ -1,110 +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.mixin.client.renderer.block.render;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.QuadInstance;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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;
|
||||
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.feature.BlockModelFeatureRenderer;
|
||||
import net.minecraft.client.renderer.feature.FeatureFrameContext;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricSubmitNodeCollection;
|
||||
import net.fabricmc.fabric.impl.client.renderer.BlockModelBufferCache;
|
||||
import net.fabricmc.fabric.impl.client.renderer.QuadConsumers;
|
||||
|
||||
@Mixin(BlockModelFeatureRenderer.class)
|
||||
abstract class BlockModelFeatureRendererMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private static Direction[] DIRECTIONS;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private QuadInstance quadInstance;
|
||||
|
||||
@Shadow
|
||||
private static void putQuad(PoseStack.Pose pose, BakedQuad quad, QuadInstance instance, int[] tintLayers, VertexConsumer buffer, @Nullable VertexConsumer outlineBuffer) {
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void putPartQuads(BlockStateModelPart part, PoseStack.Pose pose, QuadInstance quadInstance, int[] tintLayers, Function<ChunkSectionLayer, RenderType> renderTypeFunction, BlockModelBufferCache bufferCache) {
|
||||
for (Direction direction : DIRECTIONS) {
|
||||
for (BakedQuad quad : part.getQuads(direction)) {
|
||||
RenderType renderType = renderTypeFunction.apply(quad.materialInfo().layer());
|
||||
putQuad(pose, quad, quadInstance, tintLayers, bufferCache.getBuffer(renderType), bufferCache.getOutlineBuffer(renderType));
|
||||
}
|
||||
}
|
||||
|
||||
for (BakedQuad quad : part.getQuads(null)) {
|
||||
RenderType renderType = renderTypeFunction.apply(quad.materialInfo().layer());
|
||||
putQuad(pose, quad, quadInstance, tintLayers, bufferCache.getBuffer(renderType), bufferCache.getOutlineBuffer(renderType));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderModels", at = @At("RETURN"))
|
||||
private void onReturnRenderModels(SubmitNodeCollection nodeCollection, FeatureFrameContext context, boolean translucent, CallbackInfo ci) {
|
||||
BlockModelBufferCache bufferCache = new BlockModelBufferCache((net.minecraft.client.renderer.MultiBufferSource.BufferSource) context.bufferSource(), context.outlineBufferSource());
|
||||
QuadConsumers.BlockModel quadConsumer = new QuadConsumers.BlockModel();
|
||||
QuadEmitter output = Renderer.get().quadEmitter(quadConsumer);
|
||||
|
||||
for (FabricSubmitNodeCollection.ExtendedBlockModelSubmit submit : nodeCollection.getExtendedBlockModelSubmits()) {
|
||||
if (submit.translucent() == translucent) {
|
||||
PoseStack.Pose pose = submit.pose();
|
||||
int[] tintLayers = submit.tintLayers();
|
||||
Function<ChunkSectionLayer, RenderType> renderTypeFunction = submit.renderTypeFunction();
|
||||
|
||||
bufferCache.outlineColor(submit.outlineColor());
|
||||
|
||||
quadInstance.setLightCoords(submit.lightCoords());
|
||||
quadInstance.setOverlayCoords(submit.overlayCoords());
|
||||
|
||||
for (BlockStateModelPart part : submit.modelParts()) {
|
||||
putPartQuads(part, pose, quadInstance, tintLayers, renderTypeFunction, bufferCache);
|
||||
}
|
||||
|
||||
if (submit.mesh() != null) {
|
||||
quadConsumer.tintLayers = tintLayers;
|
||||
quadConsumer.lightCoords = submit.lightCoords();
|
||||
quadConsumer.overlayCoords = submit.overlayCoords();
|
||||
quadConsumer.pose = pose;
|
||||
quadConsumer.renderTypeFunction = renderTypeFunction;
|
||||
quadConsumer.bufferCache = bufferCache;
|
||||
submit.mesh().outputTo(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.mixin.client.renderer.block.render;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.block.BlockAndTintGetter;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.state.level.BlockBreakingRenderState;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableMesh;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
abstract class LevelRendererMixin {
|
||||
@Inject(method = "submitBlockDestroyAnimation(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/LevelRenderState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/RandomSource;createThreadLocalInstance()Lnet/minecraft/util/RandomSource;"))
|
||||
private void beforeCreateRandom(CallbackInfo ci, @Share("mutableMesh") LocalRef<MutableMesh> mutableMesh) {
|
||||
mutableMesh.set(Renderer.get().mutableMesh());
|
||||
}
|
||||
|
||||
@Redirect(method = "submitBlockDestroyAnimation(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/LevelRenderState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/dispatch/BlockStateModel;collectParts(Lnet/minecraft/util/RandomSource;Ljava/util/List;)V"))
|
||||
private void cancelCollectParts(BlockStateModel model, RandomSource random, List<BlockStateModelPart> output) {
|
||||
}
|
||||
|
||||
@Redirect(method = "submitBlockDestroyAnimation(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/LevelRenderState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/SubmitNodeCollector;submitBreakingBlockModel(Lcom/mojang/blaze3d/vertex/PoseStack;Ljava/util/List;I)V"))
|
||||
private void submitBreakingBlockModelProxy(SubmitNodeCollector submitNodeCollector, PoseStack poseStack, List<BlockStateModelPart> parts, int progress, @Local(name = "random") RandomSource random, @Local(name = "state") BlockBreakingRenderState state, @Local(name = "model") BlockStateModel model, @Share("mutableMesh") LocalRef<MutableMesh> mutableMeshRef) {
|
||||
MutableMesh mutableMesh = mutableMeshRef.get();
|
||||
mutableMesh.clear();
|
||||
model.emitQuads(mutableMesh.emitter(), BlockAndTintGetter.EMPTY, state.blockPos(), state.blockState(), random, _ -> false);
|
||||
submitNodeCollector.submitBreakingBlockModel(poseStack, parts, mutableMesh.immutableCopy(), progress);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,55 +16,72 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.client.renderer.block.render;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
import net.minecraft.client.renderer.block.BlockAndTintGetter;
|
||||
import net.minecraft.client.renderer.block.BlockQuadOutput;
|
||||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.client.renderer.block.MovingBlockRenderState;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
|
||||
import net.minecraft.client.renderer.feature.FeatureFrameContext;
|
||||
import net.minecraft.client.renderer.feature.MovingBlockFeatureRenderer;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.client.renderer.feature.RenderTypeFeatureRenderer;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.AltModelBlockRenderer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.ChunkSectionLayerHelper;
|
||||
import net.fabricmc.fabric.impl.client.renderer.MovingBlockQuadConsumer;
|
||||
|
||||
@Mixin(MovingBlockFeatureRenderer.class)
|
||||
abstract class MovingBlockFeatureRendererMixin {
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "net/minecraft/client/renderer/block/ModelBlockRenderer.<init>(ZZLnet/minecraft/client/color/block/BlockColors;)V"))
|
||||
private void beforeInitBlockRenderer(SubmitNodeCollection nodeCollection, FeatureFrameContext context, boolean translucent, CallbackInfo ci, @Local(name = "poseStack") PoseStack poseStack, @Share("altBlockRenderer") LocalRef<AltModelBlockRenderer> altBlockRenderer, @Share("altQuadOutput") LocalRef<QuadEmitter> altQuadOutput) {
|
||||
altBlockRenderer.set(Renderer.get().altModelBlockRenderer(context.options().ambientOcclusion, false, Minecraft.getInstance().getBlockColors()));
|
||||
altQuadOutput.set(Renderer.get().quadEmitter(quad -> {
|
||||
quad.buffer(0, poseStack.last(), context.bufferSource().getBuffer(ChunkSectionLayerHelper.getMovingBlockRenderType(quad.chunkLayer())));
|
||||
}));
|
||||
abstract class MovingBlockFeatureRendererMixin extends RenderTypeFeatureRenderer<MovingBlockFeatureRenderer.Submit> {
|
||||
@Shadow
|
||||
@Final
|
||||
private PoseStack poseStack;
|
||||
|
||||
@Inject(method = "buildGroup", at = @At(value = "INVOKE", target = "net/minecraft/client/renderer/block/ModelBlockRenderer.<init>(ZZLnet/minecraft/client/color/block/BlockColors;)V"))
|
||||
private void beforeInitBlockRenderer(FeatureFrameContext context, List<MovingBlockFeatureRenderer.Submit> submits, CallbackInfo ci, @Share("altBlockRenderer") LocalRef<AltModelBlockRenderer> altBlockRenderer, @Share("altQuadOutput") LocalRef<QuadEmitter> altQuadOutput, @Share("quadConsumer") LocalRef<MovingBlockQuadConsumer> quadConsumerRef) {
|
||||
altBlockRenderer.set(Renderer.get().altModelBlockRenderer(context.options().ambientOcclusion, false, context.blockColors()));
|
||||
MovingBlockQuadConsumer quadConsumer = new MovingBlockQuadConsumer() {
|
||||
@Override
|
||||
public void accept(MutableQuadView quad) {
|
||||
RenderType renderType = ChunkSectionLayerHelper.getMovingBlockRenderType(quad.chunkLayer());
|
||||
VertexConsumer buffer;
|
||||
|
||||
if (outlineColor != 0 && renderType.outline().isPresent()) {
|
||||
quad.color(outlineColor, outlineColor, outlineColor, outlineColor);
|
||||
buffer = getVertexBuilder(renderType.outline().get());
|
||||
} else {
|
||||
buffer = getVertexBuilder(renderType);
|
||||
}
|
||||
|
||||
quad.buffer(OverlayTexture.NO_OVERLAY, poseStack.last(), buffer);
|
||||
}
|
||||
};
|
||||
altQuadOutput.set(Renderer.get().quadEmitter(quadConsumer));
|
||||
quadConsumerRef.set(quadConsumer);
|
||||
}
|
||||
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/dispatch/BlockStateModel;hasMaterialFlag(I)Z"))
|
||||
private boolean hasMaterialFlagProxy(BlockStateModel model, @BakedQuad.MaterialFlags int flag, @Local(name = "movingBlockRenderState") MovingBlockRenderState movingBlockRenderState, @Local(name = "blockState") BlockState blockState) {
|
||||
RandomSource random = RandomSource.createThreadLocalInstance(0L);
|
||||
long blockSeed = blockState.getSeed(movingBlockRenderState.randomSeedPos);
|
||||
random.setSeed(blockSeed);
|
||||
return model.hasMaterialFlag(movingBlockRenderState, movingBlockRenderState.blockPos, blockState, random, flag);
|
||||
}
|
||||
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "net/minecraft/client/renderer/block/ModelBlockRenderer.tesselateBlock(Lnet/minecraft/client/renderer/block/BlockQuadOutput;FFFLnet/minecraft/client/renderer/block/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/client/renderer/block/dispatch/BlockStateModel;J)V"))
|
||||
private void tesselateBlockProxy(ModelBlockRenderer blockRenderer, BlockQuadOutput output, float x, float y, float z, BlockAndTintGetter level, BlockPos pos, BlockState blockState, BlockStateModel model, long seed, @Share("altBlockRenderer") LocalRef<AltModelBlockRenderer> altBlockRenderer, @Share("altQuadOutput") LocalRef<QuadEmitter> altQuadOutput) {
|
||||
@Redirect(method = "buildGroup", at = @At(value = "INVOKE", target = "net/minecraft/client/renderer/block/ModelBlockRenderer.tesselateBlock(Lnet/minecraft/client/renderer/block/BlockQuadOutput;FFFLnet/minecraft/client/renderer/block/BlockAndTintGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/client/renderer/block/dispatch/BlockStateModel;J)V"))
|
||||
private void tesselateBlockProxy(ModelBlockRenderer blockRenderer, BlockQuadOutput output, float x, float y, float z, BlockAndTintGetter level, BlockPos pos, BlockState blockState, BlockStateModel model, long seed, @Local(name = "submit") MovingBlockFeatureRenderer.Submit submit, @Share("altBlockRenderer") LocalRef<AltModelBlockRenderer> altBlockRenderer, @Share("altQuadOutput") LocalRef<QuadEmitter> altQuadOutput, @Share("quadConsumer") LocalRef<MovingBlockQuadConsumer> quadConsumer) {
|
||||
quadConsumer.get().outlineColor(submit.outlineColor());
|
||||
altBlockRenderer.get().tesselateBlock(altQuadOutput.get(), x, y, z, level, pos, blockState, model, seed);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ import net.minecraft.client.resources.model.sprite.MaterialBaker;
|
|||
import net.fabricmc.fabric.api.client.renderer.v1.sprite.FabricMaterialBaker;
|
||||
|
||||
@Mixin(MaterialBaker.class)
|
||||
interface MaterialBakerMixin extends FabricMaterialBaker {
|
||||
abstract class MaterialBakerMixin implements FabricMaterialBaker {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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.mixin.client.renderer.sprite;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import net.minecraft.client.renderer.texture.SpriteLoader;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.data.AtlasIds;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.sprite.FabricMaterialBaker;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.sprite.SpriteFinder;
|
||||
import net.fabricmc.fabric.impl.client.renderer.MissingSpriteFinderImpl;
|
||||
|
||||
@Mixin(ModelManager.BlockOnlyMaterialBaker.class)
|
||||
abstract class ModelManagerBlockOnlyMaterialBakerMixin implements FabricMaterialBaker {
|
||||
@Shadow
|
||||
@Final
|
||||
private SpriteLoader.Preparations blockAtlas;
|
||||
|
||||
@Unique
|
||||
@Nullable
|
||||
private volatile MissingSpriteFinderImpl missingSpriteFinder;
|
||||
|
||||
@Override
|
||||
public SpriteFinder spriteFinder(Identifier atlasId) {
|
||||
if (atlasId.equals(AtlasIds.BLOCKS)) {
|
||||
return blockAtlas.spriteFinder();
|
||||
}
|
||||
|
||||
MissingSpriteFinderImpl result = missingSpriteFinder;
|
||||
|
||||
if (result == null) {
|
||||
synchronized (this) {
|
||||
result = missingSpriteFinder;
|
||||
|
||||
if (result == null) {
|
||||
missingSpriteFinder = result = new MissingSpriteFinderImpl(blockAtlas.missing());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ import org.spongepowered.asm.mixin.Unique;
|
|||
|
||||
import net.minecraft.client.renderer.texture.SpriteLoader;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.sprite.Material;
|
||||
import net.minecraft.data.AtlasIds;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
|
|
@ -32,11 +31,8 @@ import net.fabricmc.fabric.api.client.renderer.v1.sprite.FabricMaterialBaker;
|
|||
import net.fabricmc.fabric.api.client.renderer.v1.sprite.SpriteFinder;
|
||||
import net.fabricmc.fabric.impl.client.renderer.MissingSpriteFinderImpl;
|
||||
|
||||
@Mixin(ModelManager.MaterialBakerImpl.class)
|
||||
abstract class ModelManagerMaterialBakerImplMixin implements FabricMaterialBaker {
|
||||
@Shadow
|
||||
@Final
|
||||
private Material.Baked blockMissing;
|
||||
@Mixin(ModelManager.CombinedBlockItemMaterialBaker.class)
|
||||
abstract class ModelManagerCombinedBlockItemMaterialBakerMixin implements FabricMaterialBaker {
|
||||
@Shadow
|
||||
@Final
|
||||
private SpriteLoader.Preparations blockAtlas;
|
||||
|
|
@ -63,7 +59,7 @@ abstract class ModelManagerMaterialBakerImplMixin implements FabricMaterialBaker
|
|||
result = missingSpriteFinder;
|
||||
|
||||
if (result == null) {
|
||||
missingSpriteFinder = result = new MissingSpriteFinderImpl(blockMissing.sprite());
|
||||
missingSpriteFinder = result = new MissingSpriteFinderImpl(blockAtlas.missing());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,67 +16,112 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.client.renderer.submit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.client.renderer.OrderedSubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
import net.minecraft.client.renderer.block.BlockModelRenderState;
|
||||
import net.minecraft.client.renderer.block.MovingBlockRenderState;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.feature.phase.SimpleFeatureRenderPhase;
|
||||
import net.minecraft.client.renderer.feature.phase.TranslucentFeatureRenderPhase;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.ModelBakery;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.util.LightCoordsUtil;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MeshView;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricSubmitNodeCollection;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedBlockModelSubmit;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedItemSubmit;
|
||||
|
||||
@Mixin(SubmitNodeCollection.class)
|
||||
abstract class SubmitNodeCollectionMixin implements OrderedSubmitNodeCollector, FabricSubmitNodeCollection {
|
||||
abstract class SubmitNodeCollectionMixin implements OrderedSubmitNodeCollector {
|
||||
@Shadow
|
||||
private boolean wasUsed;
|
||||
@Final
|
||||
public SimpleFeatureRenderPhase solid;
|
||||
@Shadow
|
||||
@Final
|
||||
public TranslucentFeatureRenderPhase translucentBlocksAndItems;
|
||||
@Shadow
|
||||
@Final
|
||||
public SimpleFeatureRenderPhase breakingOverlay;
|
||||
@Shadow
|
||||
@Final
|
||||
public SimpleFeatureRenderPhase outline;
|
||||
|
||||
@Unique
|
||||
private final List<ExtendedBlockModelSubmit> extendedBlockModelSubmits = new ArrayList<>();
|
||||
@Unique
|
||||
private final List<ExtendedItemSubmit> extendedItemSubmits = new ArrayList<>();
|
||||
@Shadow
|
||||
@Nullable
|
||||
private static RenderType getOutlineRenderType(RenderType renderType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitBlockModel(PoseStack poseStack, Function<ChunkSectionLayer, RenderType> renderTypeFunction, boolean translucent, List<BlockStateModelPart> parts, @Nullable Mesh mesh, int[] tintLayers, int lightCoords, int overlayCoords, int outlineColor) {
|
||||
wasUsed = true;
|
||||
extendedBlockModelSubmits.add(new ExtendedBlockModelSubmit(poseStack.last().copy(), renderTypeFunction, translucent, parts, mesh, tintLayers, lightCoords, overlayCoords, outlineColor));
|
||||
PoseStack.Pose pose = poseStack.last().copy();
|
||||
Function<ChunkSectionLayer, @Nullable RenderType> filteringRenderTypeFunction = layer -> {
|
||||
RenderType renderType = renderTypeFunction.apply(layer);
|
||||
return renderType.isOutline() ? null : renderType;
|
||||
};
|
||||
ExtendedBlockModelSubmit submit = new ExtendedBlockModelSubmit(pose, filteringRenderTypeFunction, parts, mesh, tintLayers, lightCoords, overlayCoords, -1, null);
|
||||
|
||||
if (translucent) {
|
||||
translucentBlocksAndItems.submit(submit);
|
||||
} else {
|
||||
solid.submit(submit);
|
||||
}
|
||||
|
||||
if (outlineColor != 0) {
|
||||
Function<ChunkSectionLayer, @Nullable RenderType> outlineRenderTypeFunction = layer -> getOutlineRenderType(renderTypeFunction.apply(layer));
|
||||
outline.submit(new ExtendedBlockModelSubmit(pose, outlineRenderTypeFunction, parts, mesh, BlockModelRenderState.EMPTY_TINTS, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, outlineColor, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitBreakingBlockModel(PoseStack poseStack, List<BlockStateModelPart> parts, Mesh mesh, int progress) {
|
||||
PoseStack.Pose pose = poseStack.last().copy();
|
||||
RenderType renderType = ModelBakery.DESTROY_TYPES.get(progress);
|
||||
breakingOverlay.submit(new ExtendedBlockModelSubmit(pose, _ -> renderType, List.copyOf(parts), mesh, BlockModelRenderState.EMPTY_TINTS, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0, pose));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitItem(PoseStack poseStack, ItemDisplayContext displayContext, int lightCoords, int overlayCoords, int outlineColor, int[] tintLayers, List<BakedQuad> quads, MeshView mesh, ItemStackRenderState.FoilType foilType) {
|
||||
this.wasUsed = true;
|
||||
extendedItemSubmits.add(new ExtendedItemSubmit(poseStack.last().copy(), displayContext, lightCoords, overlayCoords, outlineColor, tintLayers, quads, mesh, foilType));
|
||||
PoseStack.Pose pose = poseStack.last().copy();
|
||||
ExtendedItemSubmit submit = new ExtendedItemSubmit(pose, displayContext, lightCoords, overlayCoords, 0, tintLayers, quads, mesh, foilType);
|
||||
|
||||
if (submit.hasTranslucency()) {
|
||||
translucentBlocksAndItems.submit(submit);
|
||||
} else {
|
||||
solid.submit(submit);
|
||||
}
|
||||
|
||||
if (outlineColor != 0) {
|
||||
outline.submit(new ExtendedItemSubmit(pose, displayContext, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, outlineColor, ItemStackRenderState.LayerRenderState.EMPTY_TINTS, quads, mesh, ItemStackRenderState.FoilType.NONE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtendedBlockModelSubmit> getExtendedBlockModelSubmits() {
|
||||
return extendedBlockModelSubmits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtendedItemSubmit> getExtendedItemSubmits() {
|
||||
return extendedItemSubmits;
|
||||
}
|
||||
|
||||
@Inject(method = "clear", at = @At("RETURN"))
|
||||
private void onReturnClear(CallbackInfo ci) {
|
||||
extendedBlockModelSubmits.clear();
|
||||
extendedItemSubmits.clear();
|
||||
@Redirect(method = "submitMovingBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/dispatch/BlockStateModel;hasMaterialFlag(I)Z"))
|
||||
private boolean hasMaterialFlagProxy(BlockStateModel model, @BakedQuad.MaterialFlags int flag, @Local(name = "movingBlockRenderState") MovingBlockRenderState movingBlockRenderState) {
|
||||
BlockState blockState = movingBlockRenderState.blockState;
|
||||
long randomSeed = blockState.getSeed(movingBlockRenderState.randomSeedPos);
|
||||
RandomSource random = RandomSource.createThreadLocalInstance(randomSeed);
|
||||
return model.hasMaterialFlag(movingBlockRenderState, movingBlockRenderState.blockPos, blockState, random, flag);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,11 @@ abstract class SubmitNodeStorageMixin implements SubmitNodeCollector {
|
|||
order(0).submitBlockModel(poseStack, renderTypeFunction, translucent, parts, mesh, tintLayers, lightCoords, overlayCoords, outlineColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitBreakingBlockModel(PoseStack poseStack, List<BlockStateModelPart> parts, Mesh mesh, int progress) {
|
||||
order(0).submitBreakingBlockModel(poseStack, parts, mesh, progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitItem(PoseStack poseStack, ItemDisplayContext displayContext, int lightCoords, int overlayCoords, int outlineColor, int[] tintLayers, List<BakedQuad> quads, MeshView mesh, ItemStackRenderState.FoilType foilType) {
|
||||
order(0).submitItem(poseStack, displayContext, lightCoords, overlayCoords, outlineColor, tintLayers, quads, mesh, foilType);
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
classTweaker v1 official
|
||||
accessible class net/minecraft/client/renderer/block/dispatch/multipart/MultiPartModel$SharedBakedState
|
||||
accessible method net/minecraft/client/resources/model/geometry/QuadCollection <init> (Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V
|
||||
accessible class net/minecraft/client/resources/model/ModelManager$MaterialBakerImpl
|
||||
accessible class net/minecraft/client/resources/model/ModelManager$BlockOnlyMaterialBaker
|
||||
accessible class net/minecraft/client/resources/model/ModelManager$CombinedBlockItemMaterialBaker
|
||||
transitive-inject-interface net/minecraft/client/renderer/block/dispatch/BlockStateModel net/fabricmc/fabric/api/client/renderer/v1/model/FabricBlockStateModel
|
||||
transitive-inject-interface net/minecraft/client/renderer/block/dispatch/BlockStateModelPart net/fabricmc/fabric/api/client/renderer/v1/model/FabricBlockStateModelPart
|
||||
transitive-inject-interface net/minecraft/client/renderer/block/BlockStateModelSet net/fabricmc/fabric/api/client/renderer/v1/model/FabricBlockStateModelSet
|
||||
transitive-inject-interface net/minecraft/client/renderer/block/BlockModelRenderState net/fabricmc/fabric/api/client/renderer/v1/render/FabricBlockModelRenderState
|
||||
transitive-inject-interface net/minecraft/client/renderer/item/ItemStackRenderState$LayerRenderState net/fabricmc/fabric/api/client/renderer/v1/render/FabricLayerRenderState
|
||||
transitive-inject-interface net/minecraft/client/renderer/OrderedSubmitNodeCollector net/fabricmc/fabric/api/client/renderer/v1/render/FabricOrderedSubmitNodeCollector
|
||||
transitive-inject-interface net/minecraft/client/renderer/SubmitNodeCollection net/fabricmc/fabric/api/client/renderer/v1/render/FabricSubmitNodeCollection
|
||||
transitive-inject-interface net/minecraft/client/resources/model/sprite/MaterialBaker net/fabricmc/fabric/api/client/renderer/v1/sprite/FabricMaterialBaker
|
||||
transitive-inject-interface net/minecraft/client/renderer/texture/SpriteLoader$Preparations net/fabricmc/fabric/api/client/renderer/v1/sprite/FabricPreparations
|
||||
transitive-inject-interface net/minecraft/client/renderer/texture/TextureAtlas net/fabricmc/fabric/api/client/renderer/v1/sprite/FabricTextureAtlas
|
||||
|
|
|
|||
|
|
@ -14,17 +14,18 @@
|
|||
"block.particle.BlockStateModelSetMixin",
|
||||
"block.particle.ScreenEffectRendererMixin",
|
||||
"block.particle.TerrainParticleMixin",
|
||||
"block.render.BlockModelFeatureRendererMixin",
|
||||
"block.render.BlockModelRenderStateMixin",
|
||||
"block.render.BlockStateModelWrapperMixin",
|
||||
"block.render.LevelExtractorMixin",
|
||||
"block.render.LevelRendererMixin",
|
||||
"block.render.MovingBlockFeatureRendererMixin",
|
||||
"block.render.SectionCompilerMixin",
|
||||
"item.CuboidItemModelWrapperMixin",
|
||||
"item.ItemStackRenderStateLayerRenderStateMixin",
|
||||
"item.ItemStackRenderStateMixin",
|
||||
"sprite.MaterialBakerMixin",
|
||||
"sprite.ModelManagerMaterialBakerImplMixin",
|
||||
"sprite.ModelManagerBlockOnlyMaterialBakerMixin",
|
||||
"sprite.ModelManagerCombinedBlockItemMaterialBakerMixin",
|
||||
"sprite.SpriteLoaderPreparationsMixin",
|
||||
"sprite.TextureAtlasMixin",
|
||||
"submit.OrderedSubmitNodeCollectorMixin",
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ import org.jspecify.annotations.Nullable;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
|
@ -51,9 +49,6 @@ public class Indigo implements ClientModInitializer {
|
|||
/** If set the default config file will be generated on startup, restoring pre 26.1 behavior. */
|
||||
private static final boolean GENERATE_CONFIG_FILE = System.getProperty("fabric.indigo.generateConfigFile") != null;
|
||||
|
||||
// A hack for Mixins, check usages
|
||||
public static final ScopedValue<MultiBufferSource> LEVEL_RENDERER_BUFFER_SOURCE = ScopedValue.newInstance();
|
||||
|
||||
private static boolean asBoolean(@Nullable String property, boolean defValue) {
|
||||
return asTriState(property).orElse(defValue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,152 +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 java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.OutlineBufferSource;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.util.LightCoordsUtil;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.MeshView;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricLayerRenderState;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricSubmitNodeCollection;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.fabricmc.fabric.mixin.client.indigo.renderer.ItemFeatureRendererAccessor;
|
||||
|
||||
/**
|
||||
* Used during item buffering to support geometry added through {@link FabricLayerRenderState#emitter()}.
|
||||
*/
|
||||
public class AltItemRenderer {
|
||||
private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() {
|
||||
{
|
||||
data = new int[EncodingFormat.TOTAL_STRIDE];
|
||||
clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void emitDirectly() {
|
||||
bufferQuad(this);
|
||||
}
|
||||
};
|
||||
|
||||
private MultiBufferSource bufferSource;
|
||||
private OutlineBufferSource outlineBufferSource;
|
||||
private boolean translucent;
|
||||
|
||||
private FabricSubmitNodeCollection.ExtendedItemSubmit submit;
|
||||
private PoseStack.@Nullable Pose foilDecalPose;
|
||||
|
||||
public void prepare(MultiBufferSource.BufferSource bufferSource, OutlineBufferSource outlineBufferSource, boolean translucent) {
|
||||
this.bufferSource = bufferSource;
|
||||
this.outlineBufferSource = outlineBufferSource;
|
||||
this.translucent = translucent;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
bufferSource = null;
|
||||
outlineBufferSource = null;
|
||||
}
|
||||
|
||||
public void renderItem(FabricSubmitNodeCollection.ExtendedItemSubmit submit) {
|
||||
this.submit = submit;
|
||||
|
||||
if (submit.outlineColor() != 0) {
|
||||
outlineBufferSource.setColor(submit.outlineColor());
|
||||
}
|
||||
|
||||
bufferQuads(submit.quads(), submit.mesh());
|
||||
|
||||
foilDecalPose = null;
|
||||
}
|
||||
|
||||
private void bufferQuads(List<BakedQuad> vanillaQuads, MeshView mesh) {
|
||||
QuadEmitter emitter = this.emitter;
|
||||
emitter.clear();
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < vanillaQuads.size(); i++) {
|
||||
final BakedQuad q = vanillaQuads.get(i);
|
||||
emitter.fromBakedQuad(q);
|
||||
emitter.emit();
|
||||
}
|
||||
|
||||
mesh.outputTo(emitter);
|
||||
}
|
||||
|
||||
private void bufferQuad(MutableQuadViewImpl quad) {
|
||||
final RenderType renderType = quad.itemRenderType();
|
||||
|
||||
if (renderType.hasBlending() != translucent) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadeQuad(quad, quad.emissive());
|
||||
tintQuad(quad);
|
||||
|
||||
final FabricSubmitNodeCollection.ExtendedItemSubmit submit = this.submit;
|
||||
final ItemStackRenderState.FoilType foilType = quad.foilType() == null ? submit.foilType() : quad.foilType();
|
||||
|
||||
if (foilType != ItemStackRenderState.FoilType.NONE) {
|
||||
final PoseStack.Pose foilDecalPose;
|
||||
|
||||
if (foilType == ItemStackRenderState.FoilType.SPECIAL) {
|
||||
if (this.foilDecalPose == null) {
|
||||
this.foilDecalPose = ItemFeatureRendererAccessor.fabric_computeFoilDecalPose(submit.displayContext(), submit.pose());
|
||||
}
|
||||
|
||||
foilDecalPose = this.foilDecalPose;
|
||||
} else {
|
||||
foilDecalPose = null;
|
||||
}
|
||||
|
||||
final VertexConsumer foilBuffer = ItemFeatureRendererAccessor.fabric_getFoilBuffer(bufferSource, renderType, foilDecalPose);
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), foilBuffer);
|
||||
}
|
||||
|
||||
if (submit.outlineColor() != 0) {
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), outlineBufferSource.getBuffer(renderType));
|
||||
}
|
||||
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), bufferSource.getBuffer(renderType));
|
||||
}
|
||||
|
||||
private void shadeQuad(MutableQuadViewImpl quad, boolean emissive) {
|
||||
if (emissive) {
|
||||
quad.lightmap(LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT);
|
||||
} else {
|
||||
quad.minLightmap(submit.lightCoords());
|
||||
}
|
||||
}
|
||||
|
||||
private void tintQuad(MutableQuadViewImpl quad) {
|
||||
final int tintIndex = quad.tintIndex();
|
||||
|
||||
if (tintIndex >= 0 && tintIndex < submit.tintLayers().length) {
|
||||
quad.multiplyColor(submit.tintLayers()[tintIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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 java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.QuadInstance;
|
||||
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||
import net.minecraft.client.renderer.feature.FeatureFrameContext;
|
||||
import net.minecraft.client.renderer.feature.RenderTypeFeatureRenderer;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.ARGB;
|
||||
import net.minecraft.util.LightCoordsUtil;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedBlockModelSubmit;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
|
||||
public class ExtendedBlockModelFeatureRenderer extends RenderTypeFeatureRenderer<ExtendedBlockModelSubmit> {
|
||||
private static final Direction[] DIRECTIONS = Direction.values();
|
||||
private final QuadInstance quadInstance = new QuadInstance();
|
||||
|
||||
private final BufferCache bufferCache = new BufferCache();
|
||||
private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() {
|
||||
{
|
||||
data = new int[EncodingFormat.TOTAL_STRIDE];
|
||||
clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void emitDirectly() {
|
||||
bufferQuad(this);
|
||||
}
|
||||
};
|
||||
|
||||
private ExtendedBlockModelSubmit submit;
|
||||
|
||||
@Override
|
||||
protected void buildGroup(FeatureFrameContext context, List<ExtendedBlockModelSubmit> submits) {
|
||||
BufferCache bufferCache = this.bufferCache;
|
||||
MutableQuadViewImpl emitter = this.emitter;
|
||||
|
||||
for (ExtendedBlockModelSubmit submit : submits) {
|
||||
bufferCache.prepare(submit.renderTypeFunction(), submit.sheetedDecalPose());
|
||||
|
||||
quadInstance.setLightCoords(submit.lightCoords());
|
||||
quadInstance.setOverlayCoords(submit.overlayCoords());
|
||||
|
||||
for (BlockStateModelPart part : submit.modelParts()) {
|
||||
putPartQuads(part, submit.pose(), quadInstance, submit.tintColor(), submit.tintLayers(), bufferCache);
|
||||
}
|
||||
|
||||
if (submit.mesh() != null) {
|
||||
this.submit = submit;
|
||||
submit.mesh().outputTo(emitter);
|
||||
}
|
||||
}
|
||||
|
||||
bufferCache.clear();
|
||||
submit = null;
|
||||
}
|
||||
|
||||
private void putPartQuads(BlockStateModelPart part, PoseStack.Pose pose, QuadInstance quadInstance, int baseTintColor, int[] tintLayers, BufferCache bufferCache) {
|
||||
for (Direction direction : DIRECTIONS) {
|
||||
for (BakedQuad quad : part.getQuads(direction)) {
|
||||
VertexConsumer buffer = bufferCache.getBuffer(quad.materialInfo().layer());
|
||||
|
||||
if (buffer == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
putQuad(pose, quad, quadInstance, baseTintColor, tintLayers, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
for (BakedQuad quad : part.getQuads(null)) {
|
||||
VertexConsumer buffer = bufferCache.getBuffer(quad.materialInfo().layer());
|
||||
|
||||
if (buffer == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
putQuad(pose, quad, quadInstance, baseTintColor, tintLayers, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void putQuad(PoseStack.Pose pose, BakedQuad quad, QuadInstance instance, int baseTintColor, int[] tintLayers, VertexConsumer buffer) {
|
||||
int tintIndex = quad.materialInfo().tintIndex();
|
||||
boolean useTintLayer = tintIndex != -1 && tintIndex < tintLayers.length;
|
||||
instance.setColor(useTintLayer ? ARGB.multiply(baseTintColor, tintLayers[tintIndex]) : baseTintColor);
|
||||
buffer.putBakedQuad(pose, quad, instance);
|
||||
}
|
||||
|
||||
private void bufferQuad(MutableQuadViewImpl quad) {
|
||||
VertexConsumer buffer = bufferCache.getBuffer(quad.chunkLayer());
|
||||
|
||||
if (buffer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (quad.emissive()) {
|
||||
quad.lightmap(LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT);
|
||||
} else {
|
||||
quad.minLightmap(submit.lightCoords());
|
||||
}
|
||||
|
||||
int[] tintLayers = submit.tintLayers();
|
||||
int baseTintColor = submit.tintColor();
|
||||
|
||||
int tintIndex = quad.tintIndex();
|
||||
boolean useTintLayer = tintIndex != -1 && tintIndex < tintLayers.length;
|
||||
quad.multiplyColor(useTintLayer ? ARGB.multiply(baseTintColor, tintLayers[tintIndex]) : baseTintColor);
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), buffer);
|
||||
}
|
||||
|
||||
private class BufferCache {
|
||||
private Function<ChunkSectionLayer, @Nullable RenderType> renderTypeFunction;
|
||||
private PoseStack.@Nullable Pose sheetedDecalPose;
|
||||
|
||||
@Nullable
|
||||
private ChunkSectionLayer lastLayer;
|
||||
@Nullable
|
||||
private VertexConsumer lastBuffer;
|
||||
|
||||
public void prepare(Function<ChunkSectionLayer, @Nullable RenderType> renderTypeFunction, PoseStack.@Nullable Pose sheetedDecalPose) {
|
||||
this.renderTypeFunction = renderTypeFunction;
|
||||
this.sheetedDecalPose = sheetedDecalPose;
|
||||
lastLayer = null;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
renderTypeFunction = null;
|
||||
sheetedDecalPose = null;
|
||||
lastLayer = null;
|
||||
lastBuffer = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VertexConsumer getBuffer(ChunkSectionLayer layer) {
|
||||
if (layer != lastLayer) {
|
||||
lastLayer = layer;
|
||||
RenderType renderType = renderTypeFunction.apply(layer);
|
||||
|
||||
if (renderType == null) {
|
||||
lastBuffer = null;
|
||||
} else {
|
||||
VertexConsumer buffer = getVertexBuilder(renderType);
|
||||
lastBuffer = sheetedDecalPose != null ? new SheetedDecalTextureGenerator(buffer, sheetedDecalPose, 1.0F) : buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return lastBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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 java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.SheetedDecalTextureGenerator;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.renderer.feature.FeatureFrameContext;
|
||||
import net.minecraft.client.renderer.feature.RenderTypeFeatureRenderer;
|
||||
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.client.renderer.rendertype.RenderTypes;
|
||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||
import net.minecraft.util.LightCoordsUtil;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedItemSubmit;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.fabricmc.fabric.mixin.client.indigo.renderer.ItemFeatureRendererAccessor;
|
||||
|
||||
public class ExtendedItemFeatureRenderer extends RenderTypeFeatureRenderer<ExtendedItemSubmit> {
|
||||
private final MutableQuadViewImpl emitter = new MutableQuadViewImpl() {
|
||||
{
|
||||
data = new int[EncodingFormat.TOTAL_STRIDE];
|
||||
clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void emitDirectly() {
|
||||
switch (outputType) {
|
||||
case MAIN -> bufferMain(this);
|
||||
case OUTLINE -> bufferOutline(this);
|
||||
case FOIL -> bufferFoil(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private ExtendedItemSubmit submit;
|
||||
private PoseStack.@Nullable Pose foilDecalPose;
|
||||
private OutputType outputType;
|
||||
|
||||
@Override
|
||||
protected void buildGroup(FeatureFrameContext context, List<ExtendedItemSubmit> submits) {
|
||||
for (ExtendedItemSubmit submit : submits) {
|
||||
prepareSubmit(submit, false);
|
||||
}
|
||||
|
||||
for (ExtendedItemSubmit submit : submits) {
|
||||
prepareSubmit(submit, true);
|
||||
}
|
||||
|
||||
submit = null;
|
||||
foilDecalPose = null;
|
||||
}
|
||||
|
||||
private void prepareSubmit(ExtendedItemSubmit submit, boolean foil) {
|
||||
this.submit = submit;
|
||||
|
||||
if (foil) {
|
||||
foilDecalPose = null;
|
||||
outputType = OutputType.FOIL;
|
||||
} else if (submit.outlineColor() != 0) {
|
||||
outputType = OutputType.OUTLINE;
|
||||
} else {
|
||||
outputType = OutputType.MAIN;
|
||||
}
|
||||
|
||||
QuadEmitter emitter = this.emitter;
|
||||
emitter.clear();
|
||||
|
||||
List<BakedQuad> vanillaQuads = submit.quads();
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < vanillaQuads.size(); i++) {
|
||||
final BakedQuad q = vanillaQuads.get(i);
|
||||
emitter.fromBakedQuad(q);
|
||||
emitter.emit();
|
||||
}
|
||||
|
||||
submit.mesh().outputTo(emitter);
|
||||
}
|
||||
|
||||
private void bufferMain(MutableQuadViewImpl quad) {
|
||||
if (quad.emissive()) {
|
||||
quad.lightmap(LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT, LightCoordsUtil.FULL_BRIGHT);
|
||||
} else {
|
||||
quad.minLightmap(submit.lightCoords());
|
||||
}
|
||||
|
||||
int tintIndex = quad.tintIndex();
|
||||
|
||||
if (tintIndex >= 0 && tintIndex < submit.tintLayers().length) {
|
||||
quad.multiplyColor(submit.tintLayers()[tintIndex]);
|
||||
}
|
||||
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), getVertexBuilder(quad.itemRenderType()));
|
||||
}
|
||||
|
||||
private void bufferOutline(MutableQuadViewImpl quad) {
|
||||
RenderType renderType = quad.itemRenderType().outline().orElse(null);
|
||||
|
||||
if (renderType != null) {
|
||||
int outlineColor = submit.outlineColor();
|
||||
quad.color(outlineColor, outlineColor, outlineColor, outlineColor);
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), getVertexBuilder(renderType));
|
||||
}
|
||||
}
|
||||
|
||||
private void bufferFoil(MutableQuadViewImpl quad) {
|
||||
ItemStackRenderState.FoilType quadFoilType = quad.foilType();
|
||||
ItemStackRenderState.FoilType foilType = quadFoilType == null ? submit.foilType() : quadFoilType;
|
||||
|
||||
if (foilType == ItemStackRenderState.FoilType.NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
PoseStack.Pose foilDecalPose;
|
||||
|
||||
if (foilType == ItemStackRenderState.FoilType.SPECIAL) {
|
||||
if (this.foilDecalPose == null) {
|
||||
this.foilDecalPose = ItemFeatureRendererAccessor.fabric_computeFoilDecalPose(submit.displayContext(), submit.pose());
|
||||
}
|
||||
|
||||
foilDecalPose = this.foilDecalPose;
|
||||
} else {
|
||||
foilDecalPose = null;
|
||||
}
|
||||
|
||||
VertexConsumer foilBuffer = getFoilBuffer(quad.itemRenderType(), foilDecalPose);
|
||||
quad.buffer(submit.overlayCoords(), submit.pose(), foilBuffer);
|
||||
}
|
||||
|
||||
private VertexConsumer getFoilBuffer(RenderType renderType, PoseStack.@Nullable Pose foilDecalPose) {
|
||||
RenderType foilRenderType = ItemFeatureRendererAccessor.fabric_useTransparentGlint(renderType) ? RenderTypes.glintTranslucent() : RenderTypes.glint();
|
||||
VertexConsumer foilBuffer = getVertexBuilder(foilRenderType);
|
||||
|
||||
if (foilDecalPose != null) {
|
||||
foilBuffer = new SheetedDecalTextureGenerator(foilBuffer, foilDecalPose, 0.0078125F);
|
||||
}
|
||||
|
||||
return foilBuffer;
|
||||
}
|
||||
|
||||
private enum OutputType {
|
||||
MAIN,
|
||||
OUTLINE,
|
||||
FOIL
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.mixin.client.indigo.renderer;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.renderer.feature.FeatureRenderDispatcher;
|
||||
import net.minecraft.client.renderer.feature.FeatureRendererMap;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedBlockModelSubmit;
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.submit.ExtendedItemSubmit;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.ExtendedBlockModelFeatureRenderer;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.ExtendedItemFeatureRenderer;
|
||||
|
||||
@Mixin(FeatureRenderDispatcher.class)
|
||||
abstract class FeatureRenderDispatcherMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private FeatureRendererMap featureRenderers;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void registerExtendedFeatureRenderers(CallbackInfo ci) {
|
||||
featureRenderers.put(
|
||||
ExtendedBlockModelSubmit.TYPE,
|
||||
new ExtendedBlockModelFeatureRenderer()
|
||||
);
|
||||
featureRenderers.put(
|
||||
ExtendedItemSubmit.TYPE,
|
||||
new ExtendedItemFeatureRenderer()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,25 +17,22 @@
|
|||
package net.fabricmc.fabric.mixin.client.indigo.renderer;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
|
||||
import net.minecraft.client.renderer.rendertype.RenderType;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
|
||||
@Mixin(ItemFeatureRenderer.class)
|
||||
public interface ItemFeatureRendererAccessor {
|
||||
@Invoker("getFoilBuffer")
|
||||
static VertexConsumer fabric_getFoilBuffer(MultiBufferSource bufferSource, RenderType renderType, PoseStack.@Nullable Pose foilDecalPose) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Invoker("computeFoilDecalPose")
|
||||
static PoseStack.Pose fabric_computeFoilDecalPose(ItemDisplayContext type, PoseStack.Pose pose) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Invoker("useTransparentGlint")
|
||||
static boolean fabric_useTransparentGlint(RenderType renderType) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,59 +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.mixin.client.indigo.renderer;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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;
|
||||
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollection;
|
||||
import net.minecraft.client.renderer.feature.FeatureFrameContext;
|
||||
import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
|
||||
|
||||
import net.fabricmc.fabric.api.client.renderer.v1.render.FabricSubmitNodeCollection;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.AltItemRenderer;
|
||||
|
||||
@Mixin(ItemFeatureRenderer.class)
|
||||
abstract class ItemFeatureRendererMixin {
|
||||
@Unique
|
||||
private final AltItemRenderer altItemRenderer = new AltItemRenderer();
|
||||
|
||||
@Inject(method = "renderSolid", at = @At("RETURN"))
|
||||
private void onReturnRenderSolid(SubmitNodeCollection nodeCollection, FeatureFrameContext context, CallbackInfo ci) {
|
||||
altItemRenderer.prepare((MultiBufferSource.BufferSource) context.bufferSource(), context.outlineBufferSource(), false);
|
||||
|
||||
for (FabricSubmitNodeCollection.ExtendedItemSubmit submit : nodeCollection.getExtendedItemSubmits()) {
|
||||
altItemRenderer.renderItem(submit);
|
||||
}
|
||||
|
||||
altItemRenderer.clear();
|
||||
}
|
||||
|
||||
@Inject(method = "renderTranslucent", at = @At("RETURN"))
|
||||
private void onReturnRenderTranslucent(SubmitNodeCollection nodeCollection, FeatureFrameContext context, CallbackInfo ci) {
|
||||
altItemRenderer.prepare((MultiBufferSource.BufferSource) context.bufferSource(), context.outlineBufferSource(), true);
|
||||
|
||||
for (FabricSubmitNodeCollection.ExtendedItemSubmit submit : nodeCollection.getExtendedItemSubmits()) {
|
||||
altItemRenderer.renderItem(submit);
|
||||
}
|
||||
|
||||
altItemRenderer.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
"plugin": "net.fabricmc.fabric.impl.client.indigo.IndigoMixinConfigPlugin",
|
||||
"client": [
|
||||
"BlockModelLighterAccessor",
|
||||
"ItemFeatureRendererAccessor",
|
||||
"ItemFeatureRendererMixin"
|
||||
"FeatureRenderDispatcherMixin",
|
||||
"ItemFeatureRendererAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
|||
|
|
@ -49,15 +49,15 @@ include 'fabric-lifecycle-events-v1'
|
|||
include 'fabric-loot-api-v3'
|
||||
include 'fabric-menu-api-v1'
|
||||
include 'fabric-message-api-v1'
|
||||
//include 'fabric-model-loading-api-v1'
|
||||
include 'fabric-model-loading-api-v1'
|
||||
include 'fabric-networking-api-v1'
|
||||
include 'fabric-object-builder-api-v1'
|
||||
include 'fabric-particles-v1'
|
||||
include 'fabric-permission-api-v1'
|
||||
include 'fabric-recipe-api-v1'
|
||||
include 'fabric-registry-sync-v0'
|
||||
//include 'fabric-renderer-api-v1'
|
||||
//include 'fabric-renderer-indigo'
|
||||
include 'fabric-renderer-api-v1'
|
||||
include 'fabric-renderer-indigo'
|
||||
include 'fabric-rendering-fluids-v1'
|
||||
include 'fabric-rendering-v1'
|
||||
include 'fabric-resource-conditions-api-v1'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue