From 1361c39a2ba62230619b4efbfa2b0ab0b65d0373 Mon Sep 17 00:00:00 2001 From: quat Date: Mon, 27 May 2019 20:14:56 -0400 Subject: [PATCH] killswitches for various rendering-related things for performance reasons (see: #5) --- build.gradle | 2 +- .../client/ClientGameEvents.java | 33 +++- .../tesr/RenderItemStackSimpleTrophy.java | 170 +++++++++--------- .../client/tesr/RenderTileSimpleTrophy.java | 6 +- .../common/config/SimpleTrophiesConfig.java | 16 ++ 5 files changed, 140 insertions(+), 87 deletions(-) diff --git a/build.gradle b/build.gradle index bf3f67f..0f3bc36 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -version = "1.2.0" +version = "1.2.1" group = "quaternary.simpletrophies" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "simpletrophies" diff --git a/src/main/java/quaternary/simpletrophies/client/ClientGameEvents.java b/src/main/java/quaternary/simpletrophies/client/ClientGameEvents.java index 0d3c949..4e63dc2 100644 --- a/src/main/java/quaternary/simpletrophies/client/ClientGameEvents.java +++ b/src/main/java/quaternary/simpletrophies/client/ClientGameEvents.java @@ -6,8 +6,11 @@ import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.color.BlockColors; +import net.minecraft.client.renderer.color.ItemColors; +import net.minecraft.client.resources.SimpleReloadableResourceManager; import net.minecraft.item.Item; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; @@ -20,6 +23,7 @@ import quaternary.simpletrophies.client.tesr.RenderItemStackSimpleTrophy; import quaternary.simpletrophies.client.tesr.RenderTileSimpleTrophy; import quaternary.simpletrophies.common.block.SimpleTrophiesBlocks; +import quaternary.simpletrophies.common.config.SimpleTrophiesConfig; import quaternary.simpletrophies.common.etc.TrophyHelpers; import quaternary.simpletrophies.common.item.SimpleTrophiesItems; import quaternary.simpletrophies.common.tile.TileSimpleTrophy; @@ -30,8 +34,23 @@ public class ClientGameEvents { public static void models(ModelRegistryEvent e) { setSimpleItemModel(SimpleTrophiesItems.TROPHY); - ClientRegistry.bindTileEntitySpecialRenderer(TileSimpleTrophy.class, new RenderTileSimpleTrophy()); - SimpleTrophiesItems.TROPHY.setTileEntityItemStackRenderer(new RenderItemStackSimpleTrophy()); + if(SimpleTrophiesConfig.NO_TEISR) { + if(!SimpleTrophiesConfig.SKIP_ITEM_BASES) { + ModelLoader.setCustomMeshDefinition(SimpleTrophiesItems.TROPHY, stack -> + RenderItemStackSimpleTrophy.baseLocations.get(TrophyHelpers.getDisplayedVariant(stack)) + ); + + //this used to work...fuck it, doesnt seem to now though + ModelLoader.registerItemVariants(SimpleTrophiesItems.TROPHY, new ResourceLocation(SimpleTrophies.MODID, "trophy")); + } + } else { + SimpleTrophiesItems.TROPHY.setTileEntityItemStackRenderer(new RenderItemStackSimpleTrophy()); + ((SimpleReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(resourceManager -> RenderItemStackSimpleTrophy.dumpCache()); + } + + if(!SimpleTrophiesConfig.NO_TESR) { + ClientRegistry.bindTileEntitySpecialRenderer(TileSimpleTrophy.class, new RenderTileSimpleTrophy()); + } } private static void setSimpleItemModel(Item e) { @@ -51,6 +70,16 @@ public static void blockColors(ColorHandlerEvent.Block e) { }, SimpleTrophiesBlocks.TROPHY); } + @SubscribeEvent + public static void itemColors(ColorHandlerEvent.Item e) { + //Has no effect unless skipTeisr is on, btw + ItemColors ic = e.getItemColors(); + ic.registerItemColorHandler((stack, tintIndex) -> { + if(tintIndex != 0) return 0xFFFFFF; + else return TrophyHelpers.getCombinedColor(stack); + }, SimpleTrophiesItems.TROPHY); + } + private static long ticksInGame = 0; private static boolean paused = false; private static float lastNonPausedPartialTicks = 0; diff --git a/src/main/java/quaternary/simpletrophies/client/tesr/RenderItemStackSimpleTrophy.java b/src/main/java/quaternary/simpletrophies/client/tesr/RenderItemStackSimpleTrophy.java index 2a95410..72688fc 100644 --- a/src/main/java/quaternary/simpletrophies/client/tesr/RenderItemStackSimpleTrophy.java +++ b/src/main/java/quaternary/simpletrophies/client/tesr/RenderItemStackSimpleTrophy.java @@ -2,124 +2,132 @@ import net.minecraft.block.properties.PropertyEnum; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BlockModelRenderer; -import net.minecraft.client.renderer.BlockModelShapes; import net.minecraft.client.renderer.BlockRendererDispatcher; -import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.block.model.ModelManager; import net.minecraft.client.renderer.block.model.ModelResourceLocation; -import net.minecraft.client.renderer.texture.AbstractTexture; -import net.minecraft.client.renderer.texture.ITextureObject; -import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.ReflectionHelper; -import org.lwjgl.opengl.GL11; import quaternary.simpletrophies.SimpleTrophies; import quaternary.simpletrophies.client.ClientGameEvents; import quaternary.simpletrophies.common.block.BlockSimpleTrophy; +import quaternary.simpletrophies.common.config.SimpleTrophiesConfig; import quaternary.simpletrophies.common.etc.EnumTrophyVariant; import quaternary.simpletrophies.common.etc.TrophyHelpers; import quaternary.simpletrophies.common.item.ItemSimpleTrophy; +import java.util.EnumMap; + public class RenderItemStackSimpleTrophy extends TileEntityItemStackRenderer { - static final ModelResourceLocation[] baseModels; + public static final EnumMap baseLocations; + static final EnumMap baseModels; static { - baseModels = new ModelResourceLocation[EnumTrophyVariant.VALUES.length]; + baseLocations = new EnumMap<>(EnumTrophyVariant.class); PropertyEnum propVariant = BlockSimpleTrophy.PROP_VARIANT; String variantName = propVariant.getName(); - for(int i = 0; i < EnumTrophyVariant.VALUES.length; i++) { - EnumTrophyVariant var = EnumTrophyVariant.VALUES[i]; - baseModels[i] = new ModelResourceLocation(new ResourceLocation(SimpleTrophies.MODID, "trophy"), variantName + '=' + propVariant.getName(var)); + + for(EnumTrophyVariant var : EnumTrophyVariant.VALUES) { + baseLocations.put(var, new ModelResourceLocation(new ResourceLocation(SimpleTrophies.MODID, "trophy"), variantName + '=' + propVariant.getName(var))); } + + baseModels = new EnumMap<>(EnumTrophyVariant.class); + } + + public static void dumpCache() { + baseModels.clear(); } int recursionDepth = 0; @Override public void renderByItem(ItemStack stack) { - if(!(stack.getItem() instanceof ItemSimpleTrophy)) return; + if(SimpleTrophiesConfig.NO_TEISR || !(stack.getItem() instanceof ItemSimpleTrophy)) return; //Render the base - int variantID = TrophyHelpers.getDisplayedVariant(stack).ordinal(); BlockRendererDispatcher brd = Minecraft.getMinecraft().getBlockRendererDispatcher(); - ModelManager mm = brd.getBlockModelShapes().getModelManager(); - int color = TrophyHelpers.getCombinedColor(stack); - float red = ((color & 0xFF0000) >> 16) / 255f; - float green = ((color & 0x00FF00) >> 8) / 255f; - float blue = (color & 0x0000FF) / 255f; - brd.getBlockModelRenderer().renderModelBrightnessColor(mm.getModel(baseModels[variantID]), 1f, red, green, blue); - //Render the item - ItemStack displayedStack = TrophyHelpers.getDisplayedStack(stack); - - if(!displayedStack.isEmpty()) { - float ticks = ClientGameEvents.getPauseAdjustedTicksAndPartialTicks(); - - GlStateManager.pushMatrix(); - GlStateManager.translate(.5, .55, .5); - if(!Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(displayedStack, Minecraft.getMinecraft().world, null).isGui3d()) { - GlStateManager.translate(0, 0.1, 0); - } + if(!SimpleTrophiesConfig.SKIP_ITEM_BASES) { + EnumTrophyVariant baseVariant = TrophyHelpers.getDisplayedVariant(stack); + IBakedModel baseModel = baseModels.computeIfAbsent(baseVariant, (var) -> + brd.getBlockModelShapes().getModelManager().getModel(baseLocations.get(var)) + ); - GlStateManager.rotate(ticks * 2.5f, 0, 1, 0); - GlStateManager.scale(2, 2, 2); - - //Fix flickering leaves issue on old Forges - //Without this line: - //RenderItem#renderItem is called on this item - // -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (A) - // -> finds and calls this TEISR - // -> -> I call renderItem#renderItem - // -> -> -> calls setBlurMipmap(false, false) which destroys old values (!!!) (B) - // -> -> -> item rendering happens - // -> -> -> calls restoreLastBlurMipmap() which restores the (false, false) saved in A - // -> calls restoreLastBlurMipmap() which restores (false, false) from B - //values saved in A have now been overwritten with (false, false) - stateleak! - // - //With this line: - //RenderItem#renderItem is called on this item - // -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (A) - // -> finds and calls this TEISR - // -> -> I call restoreLastBlurMipmap() which restores old values saved in A - // -> -> I call renderItem#renderItem - // -> -> -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (B) - // -> -> -> item rendering happens - // -> -> -> calls restoreLastBlurMipmap() which restores the old values saved in A (saved again in B) - // -> calls restoreLastBlurMipmap() (but the saved values match the real values so nothing happens) - //values saved in A are now preserved - no stateleak - // - //Flickering leaves were fixed in https://github.com/MinecraftForge/MinecraftForge/pull/4997 - //But it still stateleaks technically, you just can't see it on leaves. - Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); - - //Too many nested pushmatrixes can cause severe render glitching on my pc. - //Nobody's going to actually hand out trophies of trophies of trophies of trophies of trophies of trophies anyways. - //No, that's not a challenge, stop it. - //And you can't even see it anyways it's so small. - recursionDepth++; + int color = TrophyHelpers.getCombinedColor(stack); + float red = ((color & 0xFF0000) >> 16) / 255f; + float green = ((color & 0x00FF00) >> 8) / 255f; + float blue = (color & 0x0000FF) / 255f; + brd.getBlockModelRenderer().renderModelBrightnessColor(baseModel, 1f, red, green, blue); + } + + //Render the item + if(!SimpleTrophiesConfig.SKIP_ITEM_ITEMS) { + ItemStack displayedStack = TrophyHelpers.getDisplayedStack(stack); - if(recursionDepth < 5) { - try { - Minecraft.getMinecraft().getRenderItem().renderItem(displayedStack, ItemCameraTransforms.TransformType.GROUND); - } catch(Exception oof) { - SimpleTrophies.LOG.error("Problem rendering item on a trophy TEISR", oof); + if(!displayedStack.isEmpty()) { + float ticks = ClientGameEvents.getPauseAdjustedTicksAndPartialTicks(); + + GlStateManager.pushMatrix(); + GlStateManager.translate(.5, .55, .5); + if(!Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(displayedStack).isGui3d()) { + GlStateManager.translate(0, 0.1, 0); } + + GlStateManager.rotate(ticks * 2.5f, 0, 1, 0); + GlStateManager.scale(2, 2, 2); + + //Fix flickering leaves issue on old Forges + //Without this line: + //RenderItem#renderItem is called on this item + // -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (A) + // -> finds and calls this TEISR + // -> -> I call renderItem#renderItem + // -> -> -> calls setBlurMipmap(false, false) which destroys old values (!!!) (B) + // -> -> -> item rendering happens + // -> -> -> calls restoreLastBlurMipmap() which restores the (false, false) saved in A + // -> calls restoreLastBlurMipmap() which restores (false, false) from B + //values saved in A have now been overwritten with (false, false) - stateleak! + // + //With this line: + //RenderItem#renderItem is called on this item + // -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (A) + // -> finds and calls this TEISR + // -> -> I call restoreLastBlurMipmap() which restores old values saved in A + // -> -> I call renderItem#renderItem + // -> -> -> calls setBlurMipmap(false, false) which saves old blur/mipmap values (B) + // -> -> -> item rendering happens + // -> -> -> calls restoreLastBlurMipmap() which restores the old values saved in A (saved again in B) + // -> calls restoreLastBlurMipmap() (but the saved values match the real values so nothing happens) + //values saved in A are now preserved - no stateleak + // + //Flickering leaves were fixed in https://github.com/MinecraftForge/MinecraftForge/pull/4997 + //But it still stateleaks technically, you just can't see it on leaves. + Minecraft.getMinecraft().getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).restoreLastBlurMipmap(); + + //Too many nested pushmatrixes can cause severe render glitching on my pc. + //Nobody's going to actually hand out trophies of trophies of trophies of trophies of trophies of trophies anyways. + //No, that's not a challenge, stop it. + //And you can't even see it anyways it's so small. + recursionDepth++; + + if(recursionDepth < 5) { + try { + Minecraft.getMinecraft().getRenderItem().renderItem(displayedStack, ItemCameraTransforms.TransformType.GROUND); + } catch(Exception oof) { + SimpleTrophies.LOG.error("Problem rendering item on a trophy TEISR", oof); + } + } + + recursionDepth--; + + GlStateManager.enableBlend(); //fix a stateleak + + GlStateManager.popMatrix(); } - - recursionDepth--; - - GlStateManager.enableBlend(); //fix a stateleak - - GlStateManager.popMatrix(); } } } \ No newline at end of file diff --git a/src/main/java/quaternary/simpletrophies/client/tesr/RenderTileSimpleTrophy.java b/src/main/java/quaternary/simpletrophies/client/tesr/RenderTileSimpleTrophy.java index 5d34e69..4a11efe 100644 --- a/src/main/java/quaternary/simpletrophies/client/tesr/RenderTileSimpleTrophy.java +++ b/src/main/java/quaternary/simpletrophies/client/tesr/RenderTileSimpleTrophy.java @@ -20,11 +20,11 @@ public class RenderTileSimpleTrophy extends TileEntitySpecialRenderer { @Override public void render(TileSimpleTrophy te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { - if(te == null) return; + if(te == null || SimpleTrophiesConfig.NO_TESR) return; ItemStack displayedStack = te.displayedStack; - if(!displayedStack.isEmpty()) { + if(!SimpleTrophiesConfig.SKIP_BLOCK_ITEMS && !displayedStack.isEmpty()) { float ticks = ClientGameEvents.getPauseAdjustedTicksAndPartialTicks(); //spread out animations a little bit. @@ -36,7 +36,7 @@ public void render(TileSimpleTrophy te, double x, double y, double z, float part GlStateManager.translate(x + .5, y + .6 + Math.sin(ticks / 25f) / 7f, z + .5); - if(!Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(displayedStack, getWorld(), null).isGui3d()) { + if(!Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getItemModel(displayedStack).isGui3d()) { GlStateManager.translate(0, 0.2, 0); } diff --git a/src/main/java/quaternary/simpletrophies/common/config/SimpleTrophiesConfig.java b/src/main/java/quaternary/simpletrophies/common/config/SimpleTrophiesConfig.java index c4c5e75..c6fcbc5 100644 --- a/src/main/java/quaternary/simpletrophies/common/config/SimpleTrophiesConfig.java +++ b/src/main/java/quaternary/simpletrophies/common/config/SimpleTrophiesConfig.java @@ -24,6 +24,12 @@ public class SimpleTrophiesConfig { public static List CREATIVETAB_TAGS; + public static boolean SKIP_ITEM_BASES; + public static boolean SKIP_ITEM_ITEMS; + public static boolean SKIP_BLOCK_ITEMS; + public static boolean NO_TEISR; + public static boolean NO_TESR; + public static String DEFAULT_CREATIVETAB_STR = "{TrophyName:\"Add your own trophies here in the config!\",TrophyVariant:\"classic\",TrophyItem:{id:\"minecraft:diamond_axe\",Count:1b,Damage:0s},TrophyColorRed:65,TrophyColorGreen:205,TrophyColorBlue:52}"; public static NBTTagCompound DEFAULT_CREATIVETAB_TAG = SimpleTrophiesUtil.swallowError(() -> JsonToNBT.getTagFromJson(DEFAULT_CREATIVETAB_STR)); @@ -49,6 +55,16 @@ private static void load() { } } + SKIP_BLOCK_ITEMS = config.getBoolean("skipBlockItems", "client.perf", false, "Don't show the items on top of trophies placed in the world. Saves on performance."); + + SKIP_ITEM_ITEMS = config.getBoolean("skipItemItems", "client.perf", false, "Don't show the items on top of trophies in your inventory and on other GUIs. Saves on performance."); + + SKIP_ITEM_BASES = config.getBoolean("skipItemBases", "client.perf", false, "Don't show trophy bases on trophies in your inventory and on other GUIs. Saves on performance."); + + NO_TESR = config.getBoolean("noTileEntitySpecialRenderer", "client.perf", false, "Emergency killswitch for the tile entity renderer. Enable in cases of extreme performance issues or client rendering-related crashes.\n(Requires a game restart in some cases.)"); + + NO_TEISR = config.getBoolean("noTileEntityItemStackRenderer", "client.perf", false, "Emergency killswitch for the in-inventory trophy renderer. Enable in cases of extreme performance issues or client rendering-related crashes.\n(Requires a game restart in some cases.)\nIf this option is enabled, and skipItemBases is not, trophy item bases will render using a 'fast path' that is about as expensive as rendering a grass block item. This fast path is not compatible with the fancy trophy TEISR, to my knowledge."); + if(config.hasChanged()) config.save(); }