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": {
"north": "true"
"north": "low"
},
"apply": {
"model": "data_gen_test:block/cobblestone_wall_side",
@ -19,7 +19,7 @@
},
{
"when": {
"south": "true"
"south": "low"
},
"apply": {
"model": "data_gen_test:block/cobblestone_wall_side",
@ -29,7 +29,7 @@
},
{
"when": {
"west": "true"
"west": "low"
},
"apply": {
"model": "data_gen_test:block/cobblestone_wall_side",
@ -39,7 +39,7 @@
},
{
"when": {
"east": "true"
"east": "low"
},
"apply": {
"model": "data_gen_test:block/cobblestone_wall_side",

View file

@ -19,64 +19,9 @@
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.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.GameSettings;
import net.minecraft.client.MainWindow;
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.screen.MainMenuScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.FogRenderer.FogType;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.client.renderer.color.ItemColors;
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.NativeImage;
import net.minecraft.client.renderer.texture.OverlayTexture;
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.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.ItemStack;
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.BlockRayTraceResult;
import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.MathHelper;
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.TranslationTextComponent;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.client.event.ColorHandlerEvent;
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.*;
import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.client.model.ModelLoader;
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.model.TransformationHelper;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.VersionChecker;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.loading.progress.StartupMessageManager;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.resource.ReloadRequirements;
import net.minecraftforge.resource.SelectiveReloadStateHandler;
import net.minecraftforge.resource.VanillaResourceType;
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
{
@ -811,15 +775,22 @@ public class ForgeHooksClient
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)) {
modelIn = layerModel.getFirst();
for(com.mojang.datafixers.util.Pair<IBakedModel,RenderType> layerModel : modelIn.getLayerModels(itemStackIn, fabulous))
{
IBakedModel layer = layerModel.getFirst();
RenderType rendertype = layerModel.getSecond();
net.minecraftforge.client.ForgeHooksClient.setRenderLayer(rendertype); // neded for compatibility with MultiLayerModels
IVertexBuilder ivertexbuilder = ItemRenderer.getBuffer(bufferIn, rendertype, true, itemStackIn.hasEffect());
renderer.renderModel(modelIn, itemStackIn, combinedLightIn, combinedOverlayIn, matrixStackIn, ivertexbuilder);
IVertexBuilder ivertexbuilder;
if (fabulous)
{
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);
}

View file

@ -29,16 +29,49 @@ import net.minecraftforge.common.util.NonNullLazy;
import net.minecraftforge.common.util.NonNullSupplier;
import org.lwjgl.opengl.GL11;
@SuppressWarnings("deprecation")
public enum ForgeRenderTypes
{
/**
* A cached copy of {@link ForgeRenderTypes#getUnsortedTranslucent(ResourceLocation)}
* for use in item models and TileEntityRenderers that use the block/item atlas.
*/
ITEM_LAYERED_SOLID(()-> getItemLayeredSolid(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
ITEM_LAYERED_CUTOUT(()-> getItemLayeredCutout(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
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_UNLIT_TRANSLUCENT(()-> getUnlitTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE)),
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.
*/
@ -71,7 +104,7 @@ public enum ForgeRenderTypes
*/
public static RenderType getEntityCutoutMipped(ResourceLocation textureLocation)
{
return Internal.entityCutoutMipped(textureLocation);
return Internal.layeredItemCutoutMipped(textureLocation);
}
// ----------------------------------------
@ -111,7 +144,7 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.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)
@ -124,10 +157,33 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.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()
.texture(new RenderState.TextureState(locationIn, false, true))
.transparency(NO_TRANSPARENCY)
@ -136,7 +192,19 @@ public enum ForgeRenderTypes
.lightmap(LIGHTMAP_ENABLED)
.overlay(OVERLAY_ENABLED)
.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 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.convertRenderTypes = convertRenderTypes;
}
@Override
@ -72,17 +79,18 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
{
Set<RenderMaterial> materials = Sets.newHashSet();
materials.add(owner.resolveTexture("particle"));
for (IUnbakedModel m : models.values())
materials.addAll(m.getTextures(modelGetter, missingTextureErrors));
for (Pair<RenderType, IUnbakedModel> m : models)
materials.addAll(m.getSecond().getTextures(modelGetter, missingTextureErrors));
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();
for(Map.Entry<RenderType, IUnbakedModel> entry : models.entrySet())
ImmutableList.Builder<Pair<RenderType, IBakedModel>> builder = ImmutableList.builder();
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();
}
@ -94,7 +102,7 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
return new MultiLayerBakedModel(
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),
buildModels(models, modelTransform, bakery, spriteGetter, modelLocation),
PerspectiveMapWrapper.getTransforms(new ModelTransformComposition(owner.getCombinedTransform(), modelTransform))
@ -116,11 +124,10 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
public MultiLayerBakedModel(
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)
{
this.isSideLit = isSideLit;
this.models = models;
this.cameraTransforms = cameraTransforms;
this.missing = missing;
this.ambientOcclusion = ambientOcclusion;
@ -128,13 +135,15 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
this.particle = particle;
this.overrides = overrides;
this.convertRenderTypes = convertRenderTypes;
this.itemLayers = models.entrySet().stream().map(kv -> {
RenderType rt = kv.getKey();
this.models = ImmutableMap.copyOf(models.stream().collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)));
this.itemLayers = models.stream().map(kv -> {
RenderType rt = kv.getFirst();
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());
}
@Deprecated
@Override
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();
for (IBakedModel model : models.values())
{
builder.addAll(model.getQuads(state, side, rand));
builder.addAll(model.getQuads(state, side, rand, extraData));
}
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();
static {
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getSolid(), RenderType.getEntitySolid(AtlasTexture.LOCATION_BLOCKS_TEXTURE));
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutout(), RenderType.getEntityCutout(AtlasTexture.LOCATION_BLOCKS_TEXTURE));
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutoutMipped(), ForgeRenderTypes.getEntityCutoutMipped(AtlasTexture.LOCATION_BLOCKS_TEXTURE));
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getTranslucent(), RenderType.getEntityTranslucent(AtlasTexture.LOCATION_BLOCKS_TEXTURE));
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getSolid(), ForgeRenderTypes.ITEM_LAYERED_SOLID.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutout(), ForgeRenderTypes.ITEM_LAYERED_CUTOUT.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getCutoutMipped(), ForgeRenderTypes.ITEM_LAYERED_CUTOUT_MIPPED.get());
ITEM_RENDER_TYPE_MAPPING.put(RenderType.getTranslucent(), ForgeRenderTypes.ITEM_LAYERED_TRANSLUCENT.get());
}
}
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("cutout", RenderType.getCutout())
.put("cutout_mipped", RenderType.getCutoutMipped())
@ -260,18 +269,18 @@ public final class MultiLayerModel implements IModelGeometry<MultiLayerModel>
@Override
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");
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
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();
return new MultiLayerModel(models);
boolean convertRenderTypes = JSONUtils.getBoolean(modelContents, "convert_render_types", true);
return new MultiLayerModel(builder.build(), convertRenderTypes);
}
}
}

View file

@ -28,11 +28,14 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod("stencil_enable_test")
public class StencilEnableTest {
public static boolean ENABLED = false;
public StencilEnableTest() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup);
}
private void clientSetup(FMLClientSetupEvent event) {
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}
}
}