Fix multi-layer item rendering.

This commit is contained in:
David Quintana 2020-07-03 05:54:46 +02:00
parent 517bbc8b5b
commit a690a7526a
6 changed files with 168 additions and 150 deletions

View File

@ -10,7 +10,7 @@
}, },
{ {
"when": { "when": {
"north": "true" "north": "low"
}, },
"apply": { "apply": {
"model": "data_gen_test:block/cobblestone_wall_side", "model": "data_gen_test:block/cobblestone_wall_side",
@ -19,7 +19,7 @@
}, },
{ {
"when": { "when": {
"south": "true" "south": "low"
}, },
"apply": { "apply": {
"model": "data_gen_test:block/cobblestone_wall_side", "model": "data_gen_test:block/cobblestone_wall_side",
@ -29,7 +29,7 @@
}, },
{ {
"when": { "when": {
"west": "true" "west": "low"
}, },
"apply": { "apply": {
"model": "data_gen_test:block/cobblestone_wall_side", "model": "data_gen_test:block/cobblestone_wall_side",
@ -39,7 +39,7 @@
}, },
{ {
"when": { "when": {
"east": "true" "east": "low"
}, },
"apply": { "apply": {
"model": "data_gen_test:block/cobblestone_wall_side", "model": "data_gen_test:block/cobblestone_wall_side",

View File

@ -19,64 +19,9 @@
package net.minecraftforge.client; package net.minecraftforge.client;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.BOSSINFO;
import static net.minecraftforge.fml.VersionChecker.Status.BETA;
import static net.minecraftforge.fml.VersionChecker.Status.BETA_OUTDATED;
import static org.lwjgl.opengl.GL11.GL_COLOR_ARRAY;
import static org.lwjgl.opengl.GL11.GL_NORMAL_ARRAY;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_COORD_ARRAY;
import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY;
import static org.lwjgl.opengl.GL11.glColorPointer;
import static org.lwjgl.opengl.GL11.glDisableClientState;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL11.glMultMatrixf;
import static org.lwjgl.opengl.GL11.glNormalPointer;
import static org.lwjgl.opengl.GL11.glTexCoordPointer;
import static org.lwjgl.opengl.GL11.glVertexPointer;
import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.math.vector.Matrix3f;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.client.model.pipeline.LightUtil;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy;
import org.apache.logging.log4j.core.impl.ReusableLogEventFactory;
import org.lwjgl.opengl.GL13;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.GameSettings; import net.minecraft.client.GameSettings;
import net.minecraft.client.MainWindow; import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -87,23 +32,28 @@ import net.minecraft.client.gui.ClientBossInfo;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.screen.MainMenuScreen; import net.minecraft.client.gui.screen.MainMenuScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.FogRenderer.FogType; import net.minecraft.client.renderer.FogRenderer.FogType;
import net.minecraft.client.renderer.color.BlockColors; import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.client.renderer.color.ItemColors;
import net.minecraft.client.renderer.entity.model.BipedModel; import net.minecraft.client.renderer.entity.model.BipedModel;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ModelManager;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage; import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.RecipeManager; import net.minecraft.item.crafting.RecipeManager;
@ -114,40 +64,54 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.EntityRayTraceResult; import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.vector.Matrix3f;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.*;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.client.event.EntityViewRenderEvent;
import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.InputUpdateEvent;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.RecipesUpdatedEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.ScreenshotEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.event.sound.PlaySoundEvent; import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.animation.Animation; import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.pipeline.QuadGatheringTransformer;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.model.TransformationHelper; import net.minecraftforge.common.model.TransformationHelper;
import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.ModLoader; import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.VersionChecker;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.resource.ReloadRequirements; import net.minecraftforge.resource.ReloadRequirements;
import net.minecraftforge.resource.SelectiveReloadStateHandler; import net.minecraftforge.resource.SelectiveReloadStateHandler;
import net.minecraftforge.resource.VanillaResourceType; import net.minecraftforge.resource.VanillaResourceType;
import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.forge.ForgeVersion;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy;
import org.apache.logging.log4j.core.impl.ReusableLogEventFactory;
import org.lwjgl.opengl.GL13;
import javax.annotation.Nonnull;
import java.io.File;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.BOSSINFO;
import static net.minecraftforge.fml.VersionChecker.Status.BETA;
import static net.minecraftforge.fml.VersionChecker.Status.BETA_OUTDATED;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
public class ForgeHooksClient public class ForgeHooksClient
{ {
@ -811,15 +775,22 @@ public class ForgeHooksClient
return event; return event;
} }
public static void drawItemLayered(ItemRenderer renderer, IBakedModel modelIn, ItemStack itemStackIn, MatrixStack matrixStackIn, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn, boolean fabulous) public static void drawItemLayered(ItemRenderer renderer, IBakedModel modelIn, ItemStack itemStackIn, MatrixStack matrixStackIn,
IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn, boolean fabulous)
{ {
for(com.mojang.datafixers.util.Pair<IBakedModel,RenderType> layerModel : modelIn.getLayerModels(itemStackIn, fabulous)) { for(com.mojang.datafixers.util.Pair<IBakedModel,RenderType> layerModel : modelIn.getLayerModels(itemStackIn, fabulous))
modelIn = layerModel.getFirst(); {
IBakedModel layer = layerModel.getFirst();
RenderType rendertype = layerModel.getSecond(); RenderType rendertype = layerModel.getSecond();
net.minecraftforge.client.ForgeHooksClient.setRenderLayer(rendertype); // neded for compatibility with MultiLayerModels net.minecraftforge.client.ForgeHooksClient.setRenderLayer(rendertype); // neded for compatibility with MultiLayerModels
IVertexBuilder ivertexbuilder;
IVertexBuilder ivertexbuilder = ItemRenderer.getBuffer(bufferIn, rendertype, true, itemStackIn.hasEffect()); if (fabulous)
renderer.renderModel(modelIn, itemStackIn, combinedLightIn, combinedOverlayIn, matrixStackIn, ivertexbuilder); {
ivertexbuilder = ItemRenderer.func_239391_c_(bufferIn, rendertype, true, itemStackIn.hasEffect());
} else {
ivertexbuilder = ItemRenderer.getBuffer(bufferIn, rendertype, true, itemStackIn.hasEffect());
}
renderer.renderModel(layer, itemStackIn, combinedLightIn, combinedOverlayIn, matrixStackIn, ivertexbuilder);
} }
net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null); net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null);
} }

View File

@ -29,16 +29,49 @@ import net.minecraftforge.common.util.NonNullLazy;
import net.minecraftforge.common.util.NonNullSupplier; import net.minecraftforge.common.util.NonNullSupplier;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@SuppressWarnings("deprecation")
public enum ForgeRenderTypes public enum ForgeRenderTypes
{ {
/** ITEM_LAYERED_SOLID(()-> getItemLayeredSolid(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
* A cached copy of {@link ForgeRenderTypes#getUnsortedTranslucent(ResourceLocation)} ITEM_LAYERED_CUTOUT(()-> getItemLayeredCutout(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
* for use in item models and TileEntityRenderers that use the block/item atlas. ITEM_LAYERED_CUTOUT_MIPPED(()-> getItemLayeredCutoutMipped(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
*/ ITEM_LAYERED_TRANSLUCENT(()-> getItemLayeredTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
ITEM_UNSORTED_TRANSLUCENT(()-> getUnsortedTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)), ITEM_UNSORTED_TRANSLUCENT(()-> getUnsortedTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
ITEM_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)), ITEM_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
ITEM_UNSORTED_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE, false)); ITEM_UNSORTED_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE, false));
/**
* @return A RenderType fit for multi-layer solid item rendering.
*/
public static RenderType getItemLayeredSolid(ResourceLocation textureLocation)
{
return Internal.layeredItemSolid(textureLocation);
}
/**
* @return A RenderType fit for multi-layer cutout item item rendering.
*/
public static RenderType getItemLayeredCutout(ResourceLocation textureLocation)
{
return Internal.layeredItemCutout(textureLocation);
}
/**
* @return A RenderType fit for multi-layer cutout-mipped item rendering.
*/
public static RenderType getItemLayeredCutoutMipped(ResourceLocation textureLocation)
{
return Internal.layeredItemCutoutMipped(textureLocation);
}
/**
* @return A RenderType fit for multi-layer translucent item rendering.
*/
public static RenderType getItemLayeredTranslucent(ResourceLocation textureLocation)
{
return Internal.layeredItemTranslucent(textureLocation);
}
/** /**
* @return A RenderType fit for translucent item/entity rendering, but with depth sorting disabled. * @return A RenderType fit for translucent item/entity rendering, but with depth sorting disabled.
*/ */
@ -71,7 +104,7 @@ public enum ForgeRenderTypes
*/ */
public static RenderType getEntityCutoutMipped(ResourceLocation textureLocation) public static RenderType getEntityCutoutMipped(ResourceLocation textureLocation)
{ {
return Internal.entityCutoutMipped(textureLocation); return Internal.layeredItemCutoutMipped(textureLocation);
} }
// ---------------------------------------- // ----------------------------------------
@ -111,7 +144,7 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED) .lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED) .overlay(OVERLAY_ENABLED)
.build(true); .build(true);
return makeType("entity_unsorted_translucent", DefaultVertexFormats.ENTITY, GL11.GL_QUADS, 256, true, sortingEnabled, renderState); return makeType("forge_entity_unsorted_translucent", DefaultVertexFormats.ENTITY, GL11.GL_QUADS, 256, true, sortingEnabled, renderState);
} }
public static RenderType unlitTranslucent(ResourceLocation textureLocation, boolean sortingEnabled) public static RenderType unlitTranslucent(ResourceLocation textureLocation, boolean sortingEnabled)
@ -124,10 +157,33 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED) .lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED) .overlay(OVERLAY_ENABLED)
.build(true); .build(true);
return makeType("entity_unlit_translucent", DefaultVertexFormats.ENTITY, GL11.GL_QUADS, 256, true, sortingEnabled, renderState); return makeType("forge_entity_unlit_translucent", DefaultVertexFormats.ENTITY, GL11.GL_QUADS, 256, true, sortingEnabled, renderState);
} }
public static RenderType entityCutoutMipped(ResourceLocation locationIn) { public static RenderType layeredItemSolid(ResourceLocation locationIn) {
RenderType.State rendertype$state = RenderType.State.getBuilder()
.texture(new RenderState.TextureState(locationIn, false, false))
.transparency(NO_TRANSPARENCY)
.diffuseLighting(DIFFUSE_LIGHTING_ENABLED)
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.build(true);
return makeType("forge_item_entity_solid", DefaultVertexFormats.ENTITY, 7, 256, true, false, rendertype$state);
}
public static RenderType layeredItemCutout(ResourceLocation locationIn) {
RenderType.State rendertype$state = RenderType.State.getBuilder()
.texture(new RenderState.TextureState(locationIn, false, false))
.transparency(NO_TRANSPARENCY)
.diffuseLighting(DIFFUSE_LIGHTING_ENABLED)
.alpha(DEFAULT_ALPHA)
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.build(true);
return makeType("forge_item_entity_cutout", DefaultVertexFormats.ENTITY, 7, 256, true, false, rendertype$state);
}
public static RenderType layeredItemCutoutMipped(ResourceLocation locationIn) {
RenderType.State rendertype$state = RenderType.State.getBuilder() RenderType.State rendertype$state = RenderType.State.getBuilder()
.texture(new RenderState.TextureState(locationIn, false, true)) .texture(new RenderState.TextureState(locationIn, false, true))
.transparency(NO_TRANSPARENCY) .transparency(NO_TRANSPARENCY)
@ -136,7 +192,19 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED) .lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED) .overlay(OVERLAY_ENABLED)
.build(true); .build(true);
return makeType("entity_cutout_mipped", DefaultVertexFormats.ENTITY, 7, 256, true, false, rendertype$state); return makeType("forge_item_entity_cutout_mipped", DefaultVertexFormats.ENTITY, 7, 256, true, false, rendertype$state);
}
public static RenderType layeredItemTranslucent(ResourceLocation p_239268_0_) {
RenderType.State rendertype$state = RenderType.State.getBuilder()
.texture(new RenderState.TextureState(p_239268_0_, false, false))
.transparency(TRANSLUCENT_TRANSPARENCY)
.diffuseLighting(DIFFUSE_LIGHTING_ENABLED)
.alpha(DEFAULT_ALPHA)
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.build(true);
return makeType("forge_item_entity_translucent_cull", DefaultVertexFormats.ENTITY, 7, 256, true, true, rendertype$state);
} }
} }
} }

View File

@ -60,11 +60,18 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
{ {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
private final ImmutableMap<RenderType, IUnbakedModel> models; private final ImmutableList<Pair<RenderType, IUnbakedModel>> models;
private final boolean convertRenderTypes;
public MultiLayerModel(ImmutableMap<RenderType, IUnbakedModel> models) public MultiLayerModel(Map<RenderType, IUnbakedModel> models)
{
this(models.entrySet().stream().map(kv -> Pair.of(kv.getKey(), kv.getValue())).collect(ImmutableList.toImmutableList()), true);
}
public MultiLayerModel(ImmutableList<Pair<RenderType, IUnbakedModel>> models, boolean convertRenderTypes)
{ {
this.models = models; this.models = models;
this.convertRenderTypes = convertRenderTypes;
} }
@Override @Override
@ -72,17 +79,18 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
{ {
Set<RenderMaterial> materials = Sets.newHashSet(); Set<RenderMaterial> materials = Sets.newHashSet();
materials.add(owner.resolveTexture("particle")); materials.add(owner.resolveTexture("particle"));
for (IUnbakedModel m : models.values()) for (Pair<RenderType, IUnbakedModel> m : models)
materials.addAll(m.getTextures(modelGetter, missingTextureErrors)); materials.addAll(m.getSecond().getTextures(modelGetter, missingTextureErrors));
return materials; return materials;
} }
private static ImmutableMap<RenderType, IBakedModel> buildModels(ImmutableMap<RenderType, IUnbakedModel> models, IModelTransform modelTransform, ModelBakery bakery, Function<RenderMaterial, TextureAtlasSprite> spriteGetter, ResourceLocation modelLocation) private static ImmutableList<Pair<RenderType, IBakedModel>> buildModels(List<Pair<RenderType, IUnbakedModel>> models, IModelTransform modelTransform,
ModelBakery bakery, Function<RenderMaterial, TextureAtlasSprite> spriteGetter, ResourceLocation modelLocation)
{ {
ImmutableMap.Builder<RenderType, IBakedModel> builder = ImmutableMap.builder(); ImmutableList.Builder<Pair<RenderType, IBakedModel>> builder = ImmutableList.builder();
for(Map.Entry<RenderType, IUnbakedModel> entry : models.entrySet()) for(Pair<RenderType, IUnbakedModel> entry : models)
{ {
builder.put(entry.getKey(), entry.getValue().bakeModel(bakery, spriteGetter, modelTransform, modelLocation)); builder.add(Pair.of(entry.getFirst(), entry.getSecond().bakeModel(bakery, spriteGetter, modelTransform, modelLocation)));
} }
return builder.build(); return builder.build();
} }
@ -94,7 +102,7 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
return new MultiLayerBakedModel( return new MultiLayerBakedModel(
owner.useSmoothLighting(), owner.isShadedInGui(), owner.isSideLit(), owner.useSmoothLighting(), owner.isShadedInGui(), owner.isSideLit(),
spriteGetter.apply(owner.resolveTexture("particle")), overrides, true, spriteGetter.apply(owner.resolveTexture("particle")), overrides, convertRenderTypes,
missing.bakeModel(bakery, spriteGetter, modelTransform, modelLocation), missing.bakeModel(bakery, spriteGetter, modelTransform, modelLocation),
buildModels(models, modelTransform, bakery, spriteGetter, modelLocation), buildModels(models, modelTransform, bakery, spriteGetter, modelLocation),
PerspectiveMapWrapper.getTransforms(new ModelTransformComposition(owner.getCombinedTransform(), modelTransform)) PerspectiveMapWrapper.getTransforms(new ModelTransformComposition(owner.getCombinedTransform(), modelTransform))
@ -116,11 +124,10 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
public MultiLayerBakedModel( public MultiLayerBakedModel(
boolean ambientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrideList overrides, boolean ambientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrideList overrides,
boolean convertRenderTypes, IBakedModel missing, ImmutableMap<RenderType, IBakedModel> models, boolean convertRenderTypes, IBakedModel missing, List<Pair<RenderType, IBakedModel>> models,
ImmutableMap<TransformType, TransformationMatrix> cameraTransforms) ImmutableMap<TransformType, TransformationMatrix> cameraTransforms)
{ {
this.isSideLit = isSideLit; this.isSideLit = isSideLit;
this.models = models;
this.cameraTransforms = cameraTransforms; this.cameraTransforms = cameraTransforms;
this.missing = missing; this.missing = missing;
this.ambientOcclusion = ambientOcclusion; this.ambientOcclusion = ambientOcclusion;
@ -128,13 +135,15 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
this.particle = particle; this.particle = particle;
this.overrides = overrides; this.overrides = overrides;
this.convertRenderTypes = convertRenderTypes; this.convertRenderTypes = convertRenderTypes;
this.itemLayers = models.entrySet().stream().map(kv -> { this.models = ImmutableMap.copyOf(models.stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)));
RenderType rt = kv.getKey(); this.itemLayers = models.stream().map(kv -> {
RenderType rt = kv.getFirst();
if (convertRenderTypes) rt = ITEM_RENDER_TYPE_MAPPING.getOrDefault(rt, rt); if (convertRenderTypes) rt = ITEM_RENDER_TYPE_MAPPING.getOrDefault(rt, rt);
return Pair.of(kv.getValue(), rt); return Pair.of(kv.getSecond(), rt);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
@Deprecated
@Override @Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand)
{ {
@ -151,7 +160,7 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder(); ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
for (IBakedModel model : models.values()) for (IBakedModel model : models.values())
{ {
builder.addAll(model.getQuads(state, side, rand)); builder.addAll(model.getQuads(state, side, rand, extraData));
} }
return builder.build(); return builder.build();
} }
@ -230,16 +239,16 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
public static BiMap<RenderType, RenderType> ITEM_RENDER_TYPE_MAPPING = HashBiMap.create(); public static BiMap<RenderType, RenderType> ITEM_RENDER_TYPE_MAPPING = HashBiMap.create();
static { static {
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getSolid(), RenderType.getEntitySolid(AtlasTexture.LOCATION_BLOCKS_TEXTURE)); ITEM_RENDER_TYPE_MAPPING.put(RenderType.getSolid(), ForgeRenderTypes.ITEM_LAYERED_SOLID.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutout(), RenderType.getEntityCutout(AtlasTexture.LOCATION_BLOCKS_TEXTURE)); ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutout(), ForgeRenderTypes.ITEM_LAYERED_CUTOUT.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutoutMipped(), ForgeRenderTypes.getEntityCutoutMipped(AtlasTexture.LOCATION_BLOCKS_TEXTURE)); ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutoutMipped(), ForgeRenderTypes.ITEM_LAYERED_CUTOUT_MIPPED.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getTranslucent(), RenderType.getEntityTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)); ITEM_RENDER_TYPE_MAPPING.put(RenderType.getTranslucent(), ForgeRenderTypes.ITEM_LAYERED_TRANSLUCENT.get());
} }
} }
public static final class Loader implements IModelLoader<MultiLayerModel> public static final class Loader implements IModelLoader<MultiLayerModel>
{ {
public static final Map<String, RenderType> BLOCK_LAYERS = ImmutableMap.<String,RenderType>builder() public static final ImmutableBiMap<String, RenderType> BLOCK_LAYERS = ImmutableBiMap.<String, RenderType>builder()
.put("solid", RenderType.getSolid()) .put("solid", RenderType.getSolid())
.put("cutout", RenderType.getCutout()) .put("cutout", RenderType.getCutout())
.put("cutout_mipped", RenderType.getCutoutMipped()) .put("cutout_mipped", RenderType.getCutoutMipped())
@ -260,18 +269,18 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
@Override @Override
public MultiLayerModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) public MultiLayerModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
{ {
ImmutableMap.Builder<RenderType, IUnbakedModel> builder = ImmutableMap.builder(); ImmutableList.Builder<Pair<RenderType, IUnbakedModel>> builder = ImmutableList.builder();
JsonObject layersObject = JSONUtils.getJsonObject(modelContents, "layers"); JsonObject layersObject = JSONUtils.getJsonObject(modelContents, "layers");
for(Map.Entry<String, RenderType> layer : BLOCK_LAYERS.entrySet()) // block layers for(Map.Entry<String, RenderType> layer : BLOCK_LAYERS.entrySet()) // block layers
{ {
String layerName = layer.getKey(); // mc overrides toString to return the ID for the layer String layerName = layer.getKey(); // mc overrides toString to return the ID for the layer
if(layersObject.has(layerName)) if(layersObject.has(layerName))
{ {
builder.put(layer.getValue(), deserializationContext.deserialize(JSONUtils.getJsonObject(layersObject, layerName), BlockModel.class)); builder.add(Pair.of(layer.getValue(), deserializationContext.deserialize(JSONUtils.getJsonObject(layersObject, layerName), BlockModel.class)));
} }
} }
ImmutableMap<RenderType, IUnbakedModel> models = builder.build(); boolean convertRenderTypes = JSONUtils.getBoolean(modelContents, "convert_render_types", true);
return new MultiLayerModel(models); return new MultiLayerModel(builder.build(), convertRenderTypes);
} }
} }
} }

View File

@ -28,11 +28,14 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod("stencil_enable_test") @Mod("stencil_enable_test")
public class StencilEnableTest { public class StencilEnableTest {
public static boolean ENABLED = false;
public StencilEnableTest() { public StencilEnableTest() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup);
} }
private void clientSetup(FMLClientSetupEvent event) { private void clientSetup(FMLClientSetupEvent event) {
DeferredWorkQueue.runLater(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); if (ENABLED)
DeferredWorkQueue.runLater(() -> Minecraft.getInstance().getFramebuffer().enableStencil());
} }
} }

View File

@ -1,33 +0,0 @@
{
"forge_marker": 1,
"defaults": {
"textures": {"wall": "block/obsidian"},
"model": "block/cobblestone_wall_post",
"uvlock": true, // This and all other properties of "defaults" will be inherited by simple submodels. They will NOT be inherited by named submodels.
"transform": "forge:default-block"
},
"variants": {
"north": {
"true": {"submodel": "forgeblockstatesloader:block/wall_connect"}, // Simple submodel declaration. You can also specify multiple submodels for a variant.
"false": {}
},
"south": {
"true": {"submodel": "forgeblockstatesloader:block/wall_connect", "y": 180},
"false": {}
},
"east": {
"true": {"submodel": "forgeblockstatesloader:block/wall_connect", "y": 90}, // Submodel will be rotated.
"false": {}
},
"west": {
"true": {"submodel": "forgeblockstatesloader:block/wall_connect", "y": 270},
"false": {}
},
"up": {"true": {}, "false": {}}, // Must have this in here or the blockstates loader will not know of all the properties and values, and it will create the wrong vanilla state strings.
"waterlogged": {"true": {}, "false": {}},
"east=false,north=true,south=true,up=false,waterlogged=false,west=false": {"model": null}, // Fully specified variant, will inherit from variants above, but remove the model set in "defaults", removing the wall post.
"east=true,north=false,south=false,up=false,waterlogged=false,west=true": {"model": null},
"east=false,north=true,south=true,up=false,waterlogged=true,west=false": {"model": null},
"east=true,north=false,south=false,up=false,waterlogged=true,west=true": {"model": null}
}
}