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.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"; /** Resource to return if generation fails */ public IResource fallbackResource; public LeafTextureResource(ResourceLocation resLeaf, IResource fallbackResource) { this.fallbackResource = fallbackResource; IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager(); try { // load normal leaf texture ResourceLocation origResource = new ResourceLocation(resLeaf.getResourceDomain(), "textures/blocks/" + resLeaf.getResourcePath()); BufferedImage origImage = ImageIO.read(resourceManager.getResource(origResource).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 if (e instanceof FileNotFoundException) return; 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 data != null ? new ByteArrayInputStream(data) : fallbackResource.getInputStream(); } public boolean hasMetadata() { return false; } public IMetadataSection getMetadata(String var1) { return null; } }