Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d9d32b32a | ||
|
|
6623bee39f | ||
|
|
ffa8dd724e |
@@ -22,7 +22,7 @@ minecraft {
|
||||
|
||||
jar.baseName = 'BetterFoliage'
|
||||
group = 'com.github.octarine-noise'
|
||||
version='0.9.8b'
|
||||
version='0.9.9b'
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
@@ -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<Integer, IRenderBlockDecorator> 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();
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,13 @@ public class RenderBlockBetterAlgae extends RenderBlockAOBase implements IRender
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render dirt block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -35,9 +35,14 @@ public class RenderBlockBetterCactus extends FakeRenderBlockAOBase implements IR
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.renderBlockCactus(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render cactus center
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
Double3 blockCenter = new Double3(x + 0.5, y + 0.5, z + 0.5);
|
||||
renderStandardBlock(block, x, y, z);
|
||||
|
||||
@@ -39,6 +39,13 @@ public class RenderBlockBetterCoral extends RenderBlockAOBase implements IRender
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render sand block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -39,6 +39,13 @@ public class RenderBlockBetterGrass extends RenderBlockAOBase implements IRender
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render grass block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -31,6 +31,13 @@ public class RenderBlockBetterLeaves extends RenderBlockAOBase implements IRende
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render leaves center
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -30,6 +30,12 @@ public class RenderBlockBetterLilypad extends FakeRenderBlockAOBase implements I
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.renderBlockLilyPad(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render lilypad block
|
||||
renderBlockLilyPad(block, x, y, z);
|
||||
|
||||
|
||||
@@ -45,6 +45,13 @@ public class RenderBlockBetterReed extends RenderBlockAOBase implements IRenderB
|
||||
// store world for later use
|
||||
blockAccess = world;
|
||||
|
||||
// use original renderer for block breaking overlay
|
||||
if (renderer.hasOverrideBlockTexture()) {
|
||||
renderer.setRenderBoundsFromBlock(block);
|
||||
renderer.renderStandardBlock(block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
// render dirt block
|
||||
setPassCounters(1);
|
||||
setRenderBoundsFromBlock(block);
|
||||
|
||||
@@ -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<String, IResourceManager> 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<String, IResourceManager> domainManagers = Utils.getDomainResourceManagers();
|
||||
if (domainManagers != null) domainManagers.remove(domainName);
|
||||
|
||||
onStitchEnd(event);
|
||||
}
|
||||
|
||||
public Set<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user