diff --git a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java index 751338a..1a4f776 100644 --- a/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java +++ b/src/main/java/mods/betterfoliage/client/BetterFoliageClient.java @@ -1,7 +1,6 @@ package mods.betterfoliage.client; import java.io.File; -import java.io.IOException; import java.util.Map; import mods.betterfoliage.BetterFoliage; @@ -13,13 +12,12 @@ import mods.betterfoliage.client.render.impl.RenderBlockBetterGrass; import mods.betterfoliage.client.render.impl.RenderBlockBetterLeaves; import mods.betterfoliage.client.render.impl.RenderBlockBetterLilypad; import mods.betterfoliage.client.render.impl.RenderBlockBetterReed; -import mods.betterfoliage.client.resource.BlockTextureGenerator; -import mods.betterfoliage.client.resource.HalfTextureResource; -import mods.betterfoliage.client.resource.LeafTextureGenerator; -import mods.betterfoliage.client.resource.ShortGrassTextureResource; +import mods.betterfoliage.client.resource.LeafGenerator; +import mods.betterfoliage.client.resource.LeafTextureEnumerator; +import mods.betterfoliage.client.resource.ReedGenerator; +import mods.betterfoliage.client.resource.ShortGrassGenerator; import net.minecraft.block.Block; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.IResource; import net.minecraft.util.ResourceLocation; import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.MinecraftForge; @@ -32,11 +30,13 @@ import cpw.mods.fml.common.FMLCommonHandler; public class BetterFoliageClient { public static Map decorators = Maps.newHashMap(); - public static LeafTextureGenerator leafGenerator; + public static LeafGenerator leafGenerator; public static BlockMatcher leaves = new BlockMatcher(); public static BlockMatcher crops = new BlockMatcher(); + public static ResourceLocation missingTexture = new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png"); + public static void preInit() { FMLCommonHandler.instance().bus().register(new KeyHandler()); @@ -55,36 +55,15 @@ public class BetterFoliageClient { crops.load(new File(BetterFoliage.configDir, "classesCrops.cfg"), new ResourceLocation("betterfoliage:classesCropsDefault.cfg")); MinecraftForge.EVENT_BUS.register(crops); - BetterFoliage.log.info("Registering leaf texture generator"); - leafGenerator = new LeafTextureGenerator(); + MinecraftForge.EVENT_BUS.register(new LeafTextureEnumerator("bf_leaves")); + + BetterFoliage.log.info("Registering texture generators"); + leafGenerator = new LeafGenerator("bf_leaves", missingTexture); MinecraftForge.EVENT_BUS.register(leafGenerator); - - MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_bottom", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) { - @Override - public IResource getResource(ResourceLocation var1) throws IOException { - return new HalfTextureResource(unwrapResource(var1), true, getMissingResource()); - } - }); - MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_reed_top", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) { - @Override - public IResource getResource(ResourceLocation var1) throws IOException { - return new HalfTextureResource(unwrapResource(var1), false, getMissingResource()); - } - }); - MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_shortgrass", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) { - @Override - public IResource getResource(ResourceLocation var1) throws IOException { - return new ShortGrassTextureResource(unwrapResource(var1), false, getMissingResource()); - } - }); - MinecraftForge.EVENT_BUS.register(new BlockTextureGenerator("bf_shortgrass_snow", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")) { - @Override - public IResource getResource(ResourceLocation var1) throws IOException { - return new ShortGrassTextureResource(unwrapResource(var1), true, getMissingResource()); - } - }); - - MinecraftForge.EVENT_BUS.register(new BetterFoliageClient()); + MinecraftForge.EVENT_BUS.register(new ReedGenerator("bf_reed_bottom", missingTexture, true)); + MinecraftForge.EVENT_BUS.register(new ReedGenerator("bf_reed_top", missingTexture, false)); + MinecraftForge.EVENT_BUS.register(new ShortGrassGenerator("bf_shortgrass", missingTexture, false)); + MinecraftForge.EVENT_BUS.register(new ShortGrassGenerator("bf_shortgrass_snow", missingTexture, true)); ShadersModIntegration.init(); } diff --git a/src/main/java/mods/betterfoliage/client/ShadersModIntegration.java b/src/main/java/mods/betterfoliage/client/ShadersModIntegration.java index 8a394c1..f10b630 100644 --- a/src/main/java/mods/betterfoliage/client/ShadersModIntegration.java +++ b/src/main/java/mods/betterfoliage/client/ShadersModIntegration.java @@ -4,6 +4,7 @@ import java.lang.reflect.Field; import net.minecraft.block.Block; import net.minecraft.init.Blocks; +import net.minecraft.util.ResourceLocation; public class ShadersModIntegration { @@ -52,4 +53,8 @@ public class ShadersModIntegration { if (BetterFoliageClient.crops.matchesID(original & 0xFFFF)) return tallGrassEntityData; return original; } + + public static boolean isSpecialTexture(ResourceLocation resource) { + return resource.getResourcePath().toLowerCase().endsWith("_n.png") || resource.getResourcePath().toLowerCase().endsWith("_s.png"); + } } diff --git a/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java b/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java index 5f730f0..dad2aab 100644 --- a/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java +++ b/src/main/java/mods/betterfoliage/client/resource/BlockTextureGenerator.java @@ -33,32 +33,22 @@ public abstract class BlockTextureGenerator implements IResourceManager { /** 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 = Utils.getDomainResourceManagers(); if (domainManagers == null) { BetterFoliage.log.warn("Failed to inject texture generator"); return; } domainManagers.put(domainName, this); - - onStitchStart(event); } @SubscribeEvent @@ -69,8 +59,6 @@ public abstract class BlockTextureGenerator implements IResourceManager { // don't leave a mess Map domainManagers = Utils.getDomainResourceManagers(); if (domainManagers != null) domainManagers.remove(domainName); - - onStitchEnd(event); } public Set getResourceDomains() { @@ -88,4 +76,13 @@ public abstract class BlockTextureGenerator implements IResourceManager { public ResourceLocation unwrapResource(ResourceLocation wrapped) { return new ResourceLocation(wrapped.getResourcePath().substring(16)); } + + protected static int blendRGB(int rgbOrig, int rgbBlend, int weightOrig, int weightBlend) { + int r = ((rgbOrig & 0xFF) * weightOrig + (rgbBlend & 0xFF) * weightBlend) / (weightOrig + weightBlend); + int g = (((rgbOrig >> 8) & 0xFF) * weightOrig + ((rgbBlend >> 8) & 0xFF) * weightBlend) / (weightOrig + weightBlend); + int b = (((rgbOrig >> 16) & 0xFF) * weightOrig + ((rgbBlend >> 16) & 0xFF) * weightBlend) / (weightOrig + weightBlend); + int a = (rgbOrig >> 24) & 0xFF; + int result = (int) (a << 24 | b << 16 | g << 8 | r); + return result; + } } diff --git a/src/main/java/mods/betterfoliage/client/resource/BufferedImageResource.java b/src/main/java/mods/betterfoliage/client/resource/BufferedImageResource.java new file mode 100644 index 0000000..5a92662 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/resource/BufferedImageResource.java @@ -0,0 +1,44 @@ +package mods.betterfoliage.client.resource; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.imageio.ImageIO; + +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.data.IMetadataSection; + +public class BufferedImageResource implements IResource { + + /** Raw PNG data*/ + protected byte[] data = null; + + public BufferedImageResource(BufferedImage image) { + // create PNG image + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(image, "PNG", baos); + data = baos.toByteArray(); + } catch (IOException e) { + } + } + + @Override + public InputStream getInputStream() { + return data == null ? null : new ByteArrayInputStream(data); + } + + @Override + public boolean hasMetadata() { + return false; + } + + @Override + public IMetadataSection getMetadata(String var1) { + return null; + } + +} diff --git a/src/main/java/mods/betterfoliage/client/resource/HalfTextureResource.java b/src/main/java/mods/betterfoliage/client/resource/HalfTextureResource.java deleted file mode 100644 index fc3fcd4..0000000 --- a/src/main/java/mods/betterfoliage/client/resource/HalfTextureResource.java +++ /dev/null @@ -1,74 +0,0 @@ -package mods.betterfoliage.client.resource; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -import mods.betterfoliage.BetterFoliage; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.data.IMetadataSection; -import net.minecraft.util.ResourceLocation; - -/** {@link IResource} of PNG containing one half (top or bottom) of a given texture resource - * @author octarine-noise - */ -@SideOnly(Side.CLIENT) -public class HalfTextureResource implements IResource { - - /** Raw PNG data*/ - public byte[] data = null; - - /** Resource to return if generation fails */ - public IResource fallbackResource; - - public HalfTextureResource(ResourceLocation resource, boolean bottom, IResource fallbackResource) { - this.fallbackResource = fallbackResource; - - IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); - try { - // load full texture - ResourceLocation origResource = new ResourceLocation(resource.getResourceDomain(), "textures/blocks/" + resource.getResourcePath()); - BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).getInputStream()); - - // draw half texture - BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight() / 2, BufferedImage.TYPE_4BYTE_ABGR); - Graphics2D graphics = result.createGraphics(); - graphics.drawImage(origImage, 0, bottom ? -origImage.getHeight() / 2 : 0, null); - - // create PNG image - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageIO.write(result, "PNG", baos); - data = baos.toByteArray(); - } catch (Exception e) { - // stop log spam with GLSL installed - if (e instanceof FileNotFoundException) return; - BetterFoliage.log.info(String.format("Could not load texture: %s, exception: %s", resource.toString(), e.getClass().getSimpleName())); - } - } - - @Override - public InputStream getInputStream() { - return data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream(); - } - - @Override - public boolean hasMetadata() { - return false; - } - - @Override - public IMetadataSection getMetadata(String var1) { - return null; - } - -} diff --git a/src/main/java/mods/betterfoliage/client/resource/LeafGenerator.java b/src/main/java/mods/betterfoliage/client/resource/LeafGenerator.java new file mode 100644 index 0000000..00528fa --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/resource/LeafGenerator.java @@ -0,0 +1,130 @@ +package mods.betterfoliage.client.resource; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +import mods.betterfoliage.BetterFoliage; +import mods.betterfoliage.client.ShadersModIntegration; +import mods.betterfoliage.common.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.TextureStitchEvent.Post; +import net.minecraftforge.client.event.TextureStitchEvent.Pre; + +public class LeafGenerator extends BlockTextureGenerator { + + /** Resource domain name of pre-drawn textures */ + public String nonGeneratedDomain = "betterfoliage"; + + /** Number of textures generated in the current run */ + public int generatedCounter = 0; + + /** Number of pre-drawn textures found in the current run */ + public int drawnCounter = 0; + + /** Name of the default alpha mask to use */ + public static String defaultMask = "rough"; + + public LeafGenerator(String domainName, ResourceLocation missingResource) { + super(domainName, missingResource); + } + + @Override + public IResource getResource(ResourceLocation resourceLocation) throws IOException { + IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); + ResourceLocation originalNoDirs = unwrapResource(resourceLocation); + ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath()); + + // check for provided texture + ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", originalNoDirs.getResourceDomain(), originalNoDirs.getResourcePath())); + if (Utils.resourceExists(handDrawnLocation)) { + drawnCounter++; + return resourceManager.getResource(handDrawnLocation); + } + + // generate our own + if (!Utils.resourceExists(originalWithDirs)) return getMissingResource(); + + // load normal leaf texture + BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).getInputStream()); + if (origImage.getWidth() != origImage.getHeight()) return getMissingResource(); + int size = origImage.getWidth(); + + // tile leaf texture 2x2 + BufferedImage overlayIcon = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D graphics = overlayIcon.createGraphics(); + graphics.drawImage(origImage, 0, 0, null); + graphics.drawImage(origImage, 0, size, null); + graphics.drawImage(origImage, size, 0, null); + graphics.drawImage(origImage, size, size, null); + + // overlay mask alpha on texture + if (!ShadersModIntegration.isSpecialTexture(originalWithDirs)) { + // load alpha mask of appropriate size + BufferedImage maskImage = loadLeafMaskImage(defaultMask, size * 2); + int scale = size * 2 / maskImage.getWidth(); + + for (int x = 0; x < overlayIcon.getWidth(); x++) { + for (int y = 0; y < overlayIcon.getHeight(); y++) { + long origPixel = overlayIcon.getRGB(x, y) & 0xFFFFFFFFl; + long maskPixel = maskImage.getRGB(x / scale, y / scale) & 0xFF000000l | 0x00FFFFFF; + overlayIcon.setRGB(x, y, (int) (origPixel & maskPixel)); + } + } + } + + generatedCounter++; + return new BufferedImageResource(overlayIcon); + } + + /** Loads the alpha mask of the given type and size. If a mask of the exact size can not be found, + * will try to load progressively smaller masks down to 16x16 + * @param type mask type + * @param size texture size + * @return alpha mask + */ + protected BufferedImage loadLeafMaskImage(String type, int size) { + IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); + IResource maskResource = null; + + while (maskResource == null && size >= 16) { + try { + maskResource = resourceManager.getResource(new ResourceLocation(String.format("betterfoliage:textures/blocks/leafmask_%d_%s.png", size, type))); + } catch (Exception e) {} + size /= 2; + } + + try { + return maskResource == null ? null : ImageIO.read(maskResource.getInputStream()); + } catch (IOException e) { + return null; + } + } + + @Override + @SubscribeEvent + public void handleTextureReload(Pre event) { + super.handleTextureReload(event); + if (event.map.getTextureType() != 0) return; + generatedCounter = 0; + drawnCounter = 0; + } + + @Override + @SubscribeEvent + public void endTextureReload(Post event) { + super.endTextureReload(event); + if (event.map.getTextureType() != 0) return; + BetterFoliage.log.info(String.format("Found %d pre-drawn leaf textures", drawnCounter)); + BetterFoliage.log.info(String.format("Found %d leaf textures", generatedCounter)); + } + + +} diff --git a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java b/src/main/java/mods/betterfoliage/client/resource/LeafTextureEnumerator.java similarity index 52% rename from src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java rename to src/main/java/mods/betterfoliage/client/resource/LeafTextureEnumerator.java index 376f94e..4a16f29 100644 --- a/src/main/java/mods/betterfoliage/client/resource/LeafTextureGenerator.java +++ b/src/main/java/mods/betterfoliage/client/resource/LeafTextureEnumerator.java @@ -1,6 +1,5 @@ package mods.betterfoliage.client.resource; -import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -10,63 +9,29 @@ import mods.betterfoliage.client.BetterFoliageClient; import mods.betterfoliage.common.util.Utils; import mods.betterfoliage.loader.DeobfHelper; 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.resources.IResource; -import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.event.TextureStitchEvent.Post; -import net.minecraftforge.client.event.TextureStitchEvent.Pre; +import net.minecraftforge.client.event.TextureStitchEvent; import com.google.common.collect.Sets; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; -/** Generates rounded crossleaf textures for all registered normal leaf textures at stitch time. - * @author octarine-noise - */ -@SideOnly(Side.CLIENT) -public class LeafTextureGenerator extends BlockTextureGenerator implements IIconRegister { +public class LeafTextureEnumerator implements IIconRegister { - public String nonGeneratedDomain = "betterfoliage"; + /** Resource domain name of generated textures */ + public String domainName; - public int nonGeneratedCounter = 0; + /** Texture atlas for block textures used in the current run */ + public TextureMap blockTextures; - public LeafTextureGenerator() { - super("bf_leaves_autogen", new ResourceLocation("betterfoliage", "textures/blocks/missing_leaf.png")); + public LeafTextureEnumerator(String domainName) { + this.domainName = domainName; } - - public IResource getResource(ResourceLocation resourceLocation) throws IOException { - IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); - ResourceLocation originalNoDirs = unwrapResource(resourceLocation); - ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath()); - - // check for provided texture - ResourceLocation handDrawnLocation = new ResourceLocation(nonGeneratedDomain, String.format("textures/blocks/%s/%s", originalNoDirs.getResourceDomain(), originalNoDirs.getResourcePath())); - if (Utils.resourceExists(handDrawnLocation)) { - nonGeneratedCounter++; - return resourceManager.getResource(handDrawnLocation); - } - - // Don't alter ShaderMod normal and specular maps - if (originalWithDirs.getResourcePath().toLowerCase().endsWith("_n.png") || originalWithDirs.getResourcePath().toLowerCase().endsWith("_s.png")) { - resourceManager.getResource(originalWithDirs); - } - - // generate our own - if (!Utils.resourceExists(originalWithDirs)) return getMissingResource(); - LeafTextureResource result = new LeafTextureResource(resourceManager.getResource(originalWithDirs)); - if (result.data != null) { - counter++; - return result; - } else { - return getMissingResource(); - } - } - + /** Leaf blocks register their textures here. An extra texture will be registered in the atlas * for each, with the resource domain of this generator. * @return the originally registered {@link IIcon} already in the atlas @@ -82,10 +47,12 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon * their textures to "sniff out" all leaf textures. * @param event */ + @SubscribeEvent @SuppressWarnings("unchecked") - @Override - public void onStitchStart(Pre event) { - nonGeneratedCounter = 0; + public void handleTextureReload(TextureStitchEvent.Pre event) { + if (event.map.getTextureType() != 0) return; + blockTextures = event.map; + BetterFoliage.log.info("Reloading leaf textures"); // register simple block textures @@ -115,11 +82,11 @@ public class LeafTextureGenerator extends BlockTextureGenerator implements IIcon } } } - - @Override - public void onStitchEnd(Post event) { - BetterFoliage.log.info(String.format("Found %d pre-drawn leaf textures", nonGeneratedCounter)); - BetterFoliage.log.info(String.format("Generated %d leaf textures", counter)); + + @SubscribeEvent + public void endTextureReload(TextureStitchEvent.Post event) { + if (event.map.getTextureType() != 0) return; + blockTextures = null; } - + } diff --git a/src/main/java/mods/betterfoliage/client/resource/LeafTextureResource.java b/src/main/java/mods/betterfoliage/client/resource/LeafTextureResource.java deleted file mode 100644 index 564b77f..0000000 --- a/src/main/java/mods/betterfoliage/client/resource/LeafTextureResource.java +++ /dev/null @@ -1,107 +0,0 @@ -package mods.betterfoliage.client.resource; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import mods.betterfoliage.BetterFoliage; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.data.IMetadataSection; -import net.minecraft.util.ResourceLocation; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; - -/** {@link IResource} containing an autogenerated round crossleaf texture - * @author octarine-noise - */ -@SideOnly(Side.CLIENT) -public class LeafTextureResource implements IResource { - - /** Raw PNG data*/ - protected byte[] data = null; - - /** Name of the default alpha mask to use */ - public static String defaultMask = "rough"; - - public LeafTextureResource(IResource resLeaf) { - try { - // load normal leaf texture - BufferedImage origImage = ImageIO.read(resLeaf.getInputStream()); - if (origImage.getWidth() != origImage.getHeight()) return; - int size = origImage.getWidth(); - - // load alpha mask of appropriate size - BufferedImage maskImage = loadLeafMaskImage(defaultMask, size * 2); - int scale = size * 2 / maskImage.getWidth(); - - // tile leaf texture 2x2 - BufferedImage overlayIcon = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_4BYTE_ABGR); - Graphics2D graphics = overlayIcon.createGraphics(); - graphics.drawImage(origImage, 0, 0, null); - graphics.drawImage(origImage, 0, size, null); - graphics.drawImage(origImage, size, 0, null); - graphics.drawImage(origImage, size, size, null); - - // overlay mask alpha on texture - for (int x = 0; x < overlayIcon.getWidth(); x++) { - for (int y = 0; y < overlayIcon.getHeight(); y++) { - long origPixel = overlayIcon.getRGB(x, y) & 0xFFFFFFFFl; - long maskPixel = maskImage.getRGB(x / scale, y / scale) & 0xFF000000l | 0x00FFFFFF; - overlayIcon.setRGB(x, y, (int) (origPixel & maskPixel)); - } - } - - // create PNG image - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageIO.write(overlayIcon, "PNG", baos); - data = baos.toByteArray(); - } catch (Exception e) { - // stop log spam with GLSL installed - BetterFoliage.log.info(String.format("Could not create leaf texture: %s, exception: %s", resLeaf.toString(), e.getClass().getSimpleName())); - } - } - - /** Loads the alpha mask of the given type and size. If a mask of the exact size can not be found, - * will try to load progressively smaller masks down to 16x16 - * @param type mask type - * @param size texture size - * @return alpha mask - */ - protected BufferedImage loadLeafMaskImage(String type, int size) { - IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); - IResource maskResource = null; - - while (maskResource == null && size >= 16) { - try { - maskResource = resourceManager.getResource(new ResourceLocation(String.format("betterfoliage:textures/blocks/leafmask_%d_%s.png", size, type))); - } catch (Exception e) {} - size /= 2; - } - - try { - return maskResource == null ? null : ImageIO.read(maskResource.getInputStream()); - } catch (IOException e) { - return null; - } - } - - public InputStream getInputStream() { - return new ByteArrayInputStream(data); - } - - public boolean hasMetadata() { - return false; - } - - public IMetadataSection getMetadata(String var1) { - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/mods/betterfoliage/client/resource/ReedGenerator.java b/src/main/java/mods/betterfoliage/client/resource/ReedGenerator.java new file mode 100644 index 0000000..af85ec7 --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/resource/ReedGenerator.java @@ -0,0 +1,40 @@ +package mods.betterfoliage.client.resource; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; + +public class ReedGenerator extends BlockTextureGenerator { + + public boolean isBottom; + + public ReedGenerator(String domainName, ResourceLocation missingResource, boolean isBottom) { + super(domainName, missingResource); + this.isBottom = isBottom; + } + + @Override + public IResource getResource(ResourceLocation resourceLocation) throws IOException { + IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); + ResourceLocation originalNoDirs = unwrapResource(resourceLocation); + ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath()); + + // load full texture + BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).getInputStream()); + + // draw half texture + BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight() / 2, BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D graphics = result.createGraphics(); + graphics.drawImage(origImage, 0, isBottom ? -origImage.getHeight() / 2 : 0, null); + + return new BufferedImageResource(result); + } + +} diff --git a/src/main/java/mods/betterfoliage/client/resource/ShortGrassGenerator.java b/src/main/java/mods/betterfoliage/client/resource/ShortGrassGenerator.java new file mode 100644 index 0000000..5131fca --- /dev/null +++ b/src/main/java/mods/betterfoliage/client/resource/ShortGrassGenerator.java @@ -0,0 +1,52 @@ +package mods.betterfoliage.client.resource; + +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import mods.betterfoliage.client.ShadersModIntegration; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.util.ResourceLocation; + +public class ShortGrassGenerator extends BlockTextureGenerator { + + protected boolean isSnowed = false; + + protected int snowOriginalWeight = 2; + + protected int snowWhiteWeight = 3; + + public ShortGrassGenerator(String domainName, ResourceLocation missingResource, boolean isSnowed) { + super(domainName, missingResource); + this.isSnowed = isSnowed; + } + + @Override + public IResource getResource(ResourceLocation resourceLocation) throws IOException { + IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); + ResourceLocation originalNoDirs = unwrapResource(resourceLocation); + ResourceLocation originalWithDirs = new ResourceLocation(originalNoDirs.getResourceDomain(), "textures/blocks/" + originalNoDirs.getResourcePath()); + + // load full texture + BufferedImage origImage = ImageIO.read(resourceManager.getResource(originalWithDirs).getInputStream()); + + // draw bottom half of texture + BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D graphics = result.createGraphics(); + graphics.drawImage(origImage, 0, 3 * origImage.getHeight() / 8, null); + + // blend with white if snowed + if (isSnowed && !ShadersModIntegration.isSpecialTexture(originalWithDirs)) { + for (int x = 0; x < result.getWidth(); x++) for (int y = 0; y < result.getHeight(); y++) { + result.setRGB(x, y, blendRGB(result.getRGB(x, y), 0xFFFFFF, 2, 3)); + } + } + + return new BufferedImageResource(result); + } + +} diff --git a/src/main/java/mods/betterfoliage/client/resource/ShortGrassTextureResource.java b/src/main/java/mods/betterfoliage/client/resource/ShortGrassTextureResource.java deleted file mode 100644 index 6f59f7f..0000000 --- a/src/main/java/mods/betterfoliage/client/resource/ShortGrassTextureResource.java +++ /dev/null @@ -1,82 +0,0 @@ -package mods.betterfoliage.client.resource; - -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import mods.betterfoliage.BetterFoliage; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IResource; -import net.minecraft.client.resources.IResourceManager; -import net.minecraft.client.resources.data.IMetadataSection; -import net.minecraft.util.ResourceLocation; - -public class ShortGrassTextureResource implements IResource { - - /** Raw PNG data*/ - public byte[] data = null; - - /** Resource to return if generation fails */ - public IResource fallbackResource; - - public ShortGrassTextureResource(ResourceLocation resource, boolean isSnowed, IResource fallbackResource) { - this.fallbackResource = fallbackResource; - boolean isSpecialTexture = resource.getResourcePath().toLowerCase().endsWith("_n.png") || resource.getResourcePath().toLowerCase().endsWith("_s.png"); - - IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); - try { - // load full texture - ResourceLocation origResource = new ResourceLocation(resource.getResourceDomain(), "textures/blocks/" + resource.getResourcePath()); - BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).getInputStream()); - - // draw bottom half of texture - BufferedImage result = new BufferedImage(origImage.getWidth(), origImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); - Graphics2D graphics = result.createGraphics(); - graphics.drawImage(origImage, 0, 3 * origImage.getHeight() / 8, null); - - // blend with white if snowed - if (isSnowed && !isSpecialTexture) { - for (int x = 0; x < result.getWidth(); x++) for (int y = 0; y < result.getHeight(); y++) { - result.setRGB(x, y, blend(result.getRGB(x, y), 0xFFFFFF, 2, 3)); - } - } - - // create PNG image - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageIO.write(result, "PNG", baos); - data = baos.toByteArray(); - } catch (Exception e) { - // stop log spam with GLSL installed - BetterFoliage.log.info(String.format("Could not load texture: %s, exception: %s", resource.toString(), e.getClass().getSimpleName())); - } - } - - protected int blend(int rgbOrig, int rgbBlend, int weightOrig, int weightBlend) { - int r = ((rgbOrig & 0xFF) * weightOrig + (rgbBlend & 0xFF) * weightBlend) / (weightOrig + weightBlend); - int g = (((rgbOrig >> 8) & 0xFF) * weightOrig + ((rgbBlend >> 8) & 0xFF) * weightBlend) / (weightOrig + weightBlend); - int b = (((rgbOrig >> 16) & 0xFF) * weightOrig + ((rgbBlend >> 16) & 0xFF) * weightBlend) / (weightOrig + weightBlend); - int a = (rgbOrig >> 24) & 0xFF; - int result = (int) (a << 24 | b << 16 | g << 8 | r); - return result; - } - - @Override - public InputStream getInputStream() { - return data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream(); - } - - @Override - public boolean hasMetadata() { - return false; - } - - @Override - public IMetadataSection getMetadata(String var1) { - return null; - } - -}