From 44a20ceab3de71eddede4e92e4721e9e818f2d1d Mon Sep 17 00:00:00 2001 From: octarine-noise Date: Sat, 5 Jul 2014 13:08:10 +0200 Subject: [PATCH] Support up to 16 icons for every feature --- .../betterfoliage/client/render/IconSet.java | 58 ++++++++++++ .../render/impl/RenderBlockBetterCactus.java | 10 ++- .../render/impl/RenderBlockBetterGrass.java | 22 +++-- .../render/impl/RenderBlockBetterLilypad.java | 28 +++--- .../resource/BlockTextureGenerator.java | 88 +++++++++++++++++++ .../client/resource/LeafTextureGenerator.java | 79 ++++------------- 6 files changed, 200 insertions(+), 85 deletions(-) create mode 100644 src/main/java/mods/betterfoliage/client/render/IconSet.java create mode 100644 src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java diff --git a/src/main/java/mods/betterfoliage/client/render/IconSet.java b/src/main/java/mods/betterfoliage/client/render/IconSet.java new file mode 100644 index 0000000..5fe36ae --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/render/IconSet.java @@ -0,0 +1,58 @@ +package mods.betterfoliage.client.render; + +import java.io.IOException; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +/** Loads an indexed set of textures + * @author octarine-noise + */ +public class IconSet { + + /** Icon array */ + public IIcon[] icons = new IIcon[16]; + + /** Number of successfully loaded icons*/ + public int numLoaded = 0; + + /** Resource domain of icons */ + String domain; + + /** Format string of icon paths */ + String path; + + public IconSet(String domain, String path) { + this.domain = domain; + this.path = path; + } + + public void registerIcons(IIconRegister register) { + numLoaded = 0; + IResourceManager manager = Minecraft.getMinecraft().getResourceManager(); + + for (int idx = 0; idx < 16; idx++) { + icons[idx] = null; + // if the path contains a domain, use that to check if the resource exists + String resolvedDomain = path.contains(":") ? new ResourceLocation(path).getResourceDomain() : domain; + String resolvedPath = String.format("textures/blocks/" + (path.contains(":") ? new ResourceLocation(path).getResourcePath() : path) + ".png", idx); + try { + IResource resource = manager.getResource(new ResourceLocation(resolvedDomain, resolvedPath)); + if (resource != null) icons[numLoaded++] = register.registerIcon(domain + ":" + String.format(path, idx)); + } catch (IOException e) { + } + } + } + + public IIcon get(int variation) { + return numLoaded == 0 ? null : icons[variation % numLoaded]; + } + + public boolean hasIcons() { + return numLoaded > 0; + } +} diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java index 745adfa..4d20282 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterCactus.java @@ -1,7 +1,9 @@ package mods.betterfoliage.client.render.impl; +import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.client.render.FakeRenderBlockAOBase; import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.common.config.Config; import mods.betterfoliage.common.util.Double3; import net.minecraft.block.Block; @@ -21,7 +23,7 @@ import cpw.mods.fml.relauncher.SideOnly; public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IRenderBlockDecorator { public IIcon cactusRoundIcon; - public IIcon cactusSideIcons[] = new IIcon[2]; + public IconSet cactusSideIcons = new IconSet("bettergrassandleaves", "better_cactus_arm_%d"); public static ForgeDirection[] cactusDirections = new ForgeDirection[] { ForgeDirection.NORTH, ForgeDirection.SOUTH, ForgeDirection.EAST, ForgeDirection.WEST}; public static double cactusRadius = 0.4375; @@ -51,7 +53,7 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR Double3 drawBase = blockCenter.add(new Double3(drawDirection).scale(cactusRadius)); Tessellator.instance.setBrightness(getBrightness(block, x, y, z)); - renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons[iconVariation % 2], 0, false); + if (cactusSideIcons.hasIcons()) renderCrossedSideQuads(drawBase, drawDirection, 0.5, 0.5, pRot[iconVariation], 0.2, cactusSideIcons.get(iconVariation), 0, false); renderCrossedBlockQuadsSkew(blockCenter, 0.65, pRot[iconVariation].scaleAxes(0.1, 0.0, 0.1), pRot[(iconVariation + 1) & 63].scaleAxes(0.1, 0.0, 0.1), @@ -78,7 +80,9 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR @SubscribeEvent public void handleTextureReload(TextureStitchEvent.Pre event) { if (event.map.getTextureType() != 0) return; + cactusRoundIcon = event.map.registerIcon("bettergrassandleaves:better_cactus"); - for (int idx = 0; idx < 2; idx++) cactusSideIcons[idx] = event.map.registerIcon("bettergrassandleaves:better_cactus_arm_" + Integer.toString(idx)); + cactusSideIcons.registerIcons(event.map); + BetterFoliage.log.info(String.format("Found %d cactus arm textures", cactusSideIcons.numLoaded)); } } diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java index e4023db..b6f9010 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterGrass.java @@ -1,6 +1,8 @@ package mods.betterfoliage.client.render.impl; +import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.client.render.RenderBlockAOBase; import mods.betterfoliage.common.config.Config; import mods.betterfoliage.common.util.Double3; @@ -20,8 +22,9 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRenderBlockDecorator { - public IIcon grassIcons[] = new IIcon[5]; - public IIcon myceliumIcons[] = new IIcon[4]; + public IconSet grassIcons = new IconSet("bettergrassandleaves", "better_grass_long_%d"); + public IconSet myceliumIcons = new IconSet("bettergrassandleaves", "better_mycel_%d"); + public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { if (!Config.grassEnabled) return false; @@ -42,7 +45,8 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender int variation = getSemiRandomFromPos(x, y, z, 0); int heightVariation = getSemiRandomFromPos(x, y, z, 1); - IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons[variation % 4] : grassIcons[variation % 5]; + IIcon renderIcon = (block == Blocks.mycelium) ? myceliumIcons.get(variation) : grassIcons.get(variation); + if (renderIcon == null) return true; double scale = Config.grassSize.value * 0.5; double halfHeight = 0.5 * (Config.grassHeightMin.value + pRand[heightVariation] * (Config.grassHeightMax.value - Config.grassHeightMin.value)); @@ -55,11 +59,11 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender @SubscribeEvent public void handleTextureReload(TextureStitchEvent.Pre event) { if (event.map.getTextureType() != 0) return; - for (int idx = 0; idx < 5; idx++) { - grassIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_grass_long_%d", idx)); - } - for (int idx = 0; idx < 4; idx++) { - myceliumIcons[idx] = event.map.registerIcon(String.format("bettergrassandleaves:better_mycel_%d", idx)); - } + + grassIcons.registerIcons(event.map); + myceliumIcons.registerIcons(event.map); + BetterFoliage.log.info(String.format("Found %d short grass textures", grassIcons.numLoaded)); + BetterFoliage.log.info(String.format("Found %d mycelium textures", myceliumIcons.numLoaded)); } + } diff --git a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java index 3142950..5734157 100644 --- a/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java +++ b/src/main/java/mods/betterfoliage/client/render/impl/RenderBlockBetterLilypad.java @@ -1,14 +1,15 @@ package mods.betterfoliage.client.render.impl; +import mods.betterfoliage.BetterFoliage; import mods.betterfoliage.client.render.FakeRenderBlockAOBase; import mods.betterfoliage.client.render.IRenderBlockDecorator; +import mods.betterfoliage.client.render.IconSet; import mods.betterfoliage.common.config.Config; import mods.betterfoliage.common.util.Double3; import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.init.Blocks; -import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.common.util.ForgeDirection; @@ -19,8 +20,8 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements IRenderBlockDecorator { - public IIcon lilypadFlowers[] = new IIcon[2]; - public IIcon lilypadRoots[] = new IIcon[3]; + public IconSet lilypadFlowers = new IconSet("bettergrassandleaves", "better_lilypad_flower_%d"); + public IconSet lilypadRoots = new IconSet("bettergrassandleaves", "better_lilypad_roots_%d"); public boolean isBlockAccepted(IBlockAccess blockAccess, int x, int y, int z, Block block, int original) { return Config.lilypadEnabled && block == Blocks.waterlily; @@ -39,16 +40,16 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I Tessellator.instance.setBrightness(getBrightness(block, x, y, z)); Tessellator.instance.setColorOpaque(255, 255, 255); - renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN, - 0.2, 0.3, - null, 0.0, - lilypadRoots[iconVariation % 3], 2, - true); - if (chanceVariation < Config.lilypadChance.value) + if (lilypadRoots.hasIcons()) renderCrossedSideQuads(new Double3(x + 0.5, y + 0.015, z + 0.5), ForgeDirection.DOWN, + 0.2, 0.3, + null, 0.0, + lilypadRoots.get(iconVariation), 2, + true); + if (chanceVariation < Config.lilypadChance.value && lilypadFlowers.hasIcons()) renderCrossedSideQuads(new Double3(x + 0.5, y + 0.02, z + 0.5), ForgeDirection.UP, 0.2, 0.3, pRot[offsetVariation], Config.lilypadHOffset.value, - lilypadFlowers[iconVariation % 2], 0, + lilypadFlowers.get(iconVariation), 0, true); return true; @@ -57,8 +58,11 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I @SubscribeEvent public void handleTextureReload(TextureStitchEvent.Pre event) { if (event.map.getTextureType() != 0) return; - for (int idx = 0; idx < 2; idx++) lilypadFlowers[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_flower_" + Integer.toString(idx)); - for (int idx = 0; idx < 3; idx++) lilypadRoots[idx] = event.map.registerIcon("bettergrassandleaves:better_lilypad_roots_" + Integer.toString(idx)); + + lilypadFlowers.registerIcons(event.map); + lilypadRoots.registerIcons(event.map); + BetterFoliage.log.info(String.format("Found %d lilypad flower textures", lilypadFlowers.numLoaded)); + BetterFoliage.log.info(String.format("Found %d lilypad root textures", lilypadRoots.numLoaded)); } } diff --git a/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java b/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java new file mode 100644 index 0000000..c937e3c --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java @@ -0,0 +1,88 @@ +package mods.betterfoliage.client.resource; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import mods.betterfoliage.BetterFoliage; +import mods.betterfoliage.common.util.ReflectionUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.TextureStitchEvent; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +public abstract class BlockTextureGenerator implements IResourceManager { + + /** Resource domain name of generated textures */ + public String domainName; + + /** Resource location for fallback texture (if the generation process fails) */ + public ResourceLocation missingResource; + + /** Texture atlas for block textures used in the current run */ + public TextureMap blockTextures; + + /** Number of textures generated in the current run */ + int counter = 0; + + public BlockTextureGenerator(String domainName, ResourceLocation missingResource) { + this.domainName = domainName; + this.missingResource = missingResource; + } + + public void onStitchStart(TextureStitchEvent.Pre event) {} + + public void onStitchEnd(TextureStitchEvent.Post event) {} + + @SubscribeEvent + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + + blockTextures = event.map; + counter = 0; + Map domainManagers = ReflectionUtil.getDomainResourceManagers(); + if (domainManagers == null) { + BetterFoliage.log.warn("Failed to inject texture generator"); + return; + } + domainManagers.put(domainName, this); + + onStitchStart(event); + } + + @SubscribeEvent + public void endTextureReload(TextureStitchEvent.Post event) { + blockTextures = null; + if (event.map.getTextureType() != 0) return; + + // don't leave a mess + Map domainManagers = ReflectionUtil.getDomainResourceManagers(); + if (domainManagers != null) domainManagers.remove(domainName); + + onStitchEnd(event); + } + + public Set getResourceDomains() { + return ImmutableSet.of(domainName); + } + + public List getAllResources(ResourceLocation resource) throws IOException { + return ImmutableList.of(getResource(resource)); + } + + public IResource getMissingResource() throws IOException { + return Minecraft.getMinecraft().getResourceManager().getResource(missingResource); + } + + public ResourceLocation unwrapResource(ResourceLocation wrapped) { + return new ResourceLocation(wrapped.getResourcePath().substring(16)); + } +} diff --git a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java b/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java index 8888014..026f556 100644 --- a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java +++ b/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java @@ -11,22 +11,17 @@ import mods.betterfoliage.client.BetterFoliageClient; import mods.betterfoliage.common.util.DeobfNames; import mods.betterfoliage.common.util.ReflectionUtil; import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourceManager; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.client.event.TextureStitchEvent.Post; +import net.minecraftforge.client.event.TextureStitchEvent.Pre; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -34,41 +29,22 @@ import cpw.mods.fml.relauncher.SideOnly; * @author octarine-noise */ @SideOnly(Side.CLIENT) -public class LeafTextureGenerator implements IIconRegister, IResourceManager { +public class LeafTextureGenerator extends BlockTextureGenerator implements IIconRegister { - /** Resource domain name of autogenerated crossleaf textures */ - public String domainName = "bf_leaves_autogen"; - - /** Resource location for fallback texture (if the generation process fails) */ - public ResourceLocation missing_resource = new ResourceLocation("betterfoliage", "textures/blocks/missingleaf.png"); - - /** Texture atlas for block textures used in the current run */ - public TextureMap blockTextures; - - /** List of helpers which can identify leaf textures loaded by alternate means */ - public List recognizers = Lists.newLinkedList(); - - /** Number of textures generated in the current run */ - int counter = 0; - - public Set getResourceDomains() { - return ImmutableSet.of(domainName); + public LeafTextureGenerator() { + super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missingleaf.png")); } + /** List of helpers which can identify leaf textures loaded by alternate means */ + public List recognizers = Lists.newLinkedList(); + public IResource getResource(ResourceLocation resourceLocation) throws IOException { - // remove "/blocks/textures/" from beginning - String origResPath = resourceLocation.getResourcePath().substring(16); - LeafTextureResource result = new LeafTextureResource(new ResourceLocation(origResPath)); - if (result.data == null) { - return Minecraft.getMinecraft().getResourceManager().getResource(missing_resource); - } else { + LeafTextureResource result = new LeafTextureResource(unwrapResource(resourceLocation)); + if (result.data != null) { counter++; return result; } - } - - public List getAllResources(ResourceLocation resource) throws IOException { - return ImmutableList.of(); + return getMissingResource(); } /** Leaf blocks register their textures here. An extra texture will be registered in the atlas @@ -87,21 +63,10 @@ public class LeafTextureGenerator implements IIconRegister, IResourceManager { * @param event */ @SuppressWarnings("unchecked") - @SubscribeEvent - public void handleTextureReload(TextureStitchEvent.Pre event) { - if (event.map.getTextureType() != 0) return; - - blockTextures = event.map; - counter = 0; + @Override + public void onStitchStart(Pre event) { BetterFoliage.log.info("Reloading leaf textures"); - Map domainManagers = ReflectionUtil.getDomainResourceManagers(); - if (domainManagers == null) { - BetterFoliage.log.warn("Failed to inject leaf texture generator"); - return; - } - domainManagers.put(domainName, this); - // register simple block textures Iterator iter = Block.blockRegistry.iterator(); while(iter.hasNext()) { @@ -130,18 +95,10 @@ public class LeafTextureGenerator implements IIconRegister, IResourceManager { } } } - - @SubscribeEvent - public void endTextureReload(TextureStitchEvent.Post event) { - blockTextures = null; - if (event.map.getTextureType() == 0) { - BetterFoliage.log.info(String.format("Generated %d leaf textures", counter)); - - // don't leave a mess - Map domainManagers = ReflectionUtil.getDomainResourceManagers(); - if (domainManagers == null) return; - domainManagers.remove(domainName); - } + + @Override + public void onStitchEnd(Post event) { + BetterFoliage.log.info(String.format("Generated %d leaf textures", counter)); } - + }