Package com.rwtema.denseores

Source Code of com.rwtema.denseores.TextureOre

package com.rwtema.denseores;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.util.ResourceLocation;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;

// Custom texture class to handle the ore generation
@SideOnly(Side.CLIENT)
public class TextureOre extends TextureAtlasSprite {

    private int n;

    private ResourceLocation textureLocation;

    public String name;

    public String base;
    public int type;

    public BufferedImage output_image = null;


    public static String getDerivedName(String s2) {
        String s1 = "minecraft";

        int ind = s2.indexOf(58);

        if (ind >= 0) {
            if (ind > 1) {
                s1 = s2.substring(0, ind);
            }

            s2 = s2.substring(ind + 1, s2.length());
        }

        s1 = s1.toLowerCase();

        return DenseOresMod.MODID + ":" + s1 + "/" + s2;
    }

    private int renderType = 0;

    public TextureOre(DenseOre denseOre) {
        this(denseOre.texture, denseOre.underlyingBlocktexture);
        renderType = denseOre.rendertype;
    }

    public TextureOre(String par1Str, String base) {
        super(getDerivedName(par1Str));
        this.name = par1Str;
        this.base = base;
    }

    // should we use a custom loader to get our texture?
    public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) {

        ResourceLocation location1 = new ResourceLocation(location.getResourceDomain(), String.format("%s/%s%s", new Object[]{"textures/blocks", location.getResourcePath(), ".png"}));
        try {
            // check to see if the resource can be loaded (someone added an
            // override)
            manager.getResource(location1);
            LogHelper.info("Dense Ores: Detected override for " + name);
            return false;
        } catch (IOException e) {
            // file not found: let's generate one
            return true;
        }
    }

    // converts texture name to resource location
    public static ResourceLocation getBlockResource(String s2) {
        String s1 = "minecraft";

        int ind = s2.indexOf(58);

        if (ind >= 0) {
            if (ind > 1) {
                s1 = s2.substring(0, ind);
            }

            s2 = s2.substring(ind + 1, s2.length());
        }

        s1 = s1.toLowerCase();
        s2 = "textures/blocks/" + s2 + ".png";

        return new ResourceLocation(s1, s2);
    }

    // loads the textures
    // note: the documentation

    /**
     * Load the specified resource as this sprite's data. Returning false from
     * this function will prevent this icon from being stitched onto the master
     * texture.
     *
     * @param manager  Main resource manager
     * @param location File resource location
     * @return False to prevent this Icon from being stitched
     */
    // is not correct - return TRUE to prevent this Icon from being stitched
    // (makes no sense but... whatever)

    // this code is based on code from TextureMap.loadTextureAtlas, only with
    // the
    // code for custom mip-mapping textures and animation removed.
    // TODO: add animation support
    public boolean load(IResourceManager manager, ResourceLocation location) {

        // get mipmapping level
        int mp = Minecraft.getMinecraft().gameSettings.mipmapLevels;

        // creates a buffer that will be used for our texture and the
        // various mip-maps
        // (mip-mapping is where you use smaller textures when objects are
        // far-away
        // see: http://en.wikipedia.org/wiki/Mipmap)
        // these will be generated from the base texture by Minecraft
        BufferedImage[] ore_image = new BufferedImage[1 + mp];

        BufferedImage stone_image;
        int w;

        AnimationMetadataSection animation;

        try {
            IResource iresource = manager.getResource(getBlockResource(name));
            IResource iresourceBase = manager.getResource(getBlockResource(base));

            // load the ore texture
            ore_image[0] = ImageIO.read(iresource.getInputStream());

            // load animation
            animation = (AnimationMetadataSection) iresource.getMetadata("animation");

            // load the stone texture
            stone_image = ImageIO.read(iresourceBase.getInputStream());

            w = ore_image[0].getWidth();

            if (stone_image.getWidth() != w) {
                List resourcePacks = manager.getAllResources(getBlockResource(base));
                for (int i = resourcePacks.size() - 1; i >= 0; --i) {
                    IResource resource = (IResource) resourcePacks.get(i);
                    stone_image = ImageIO.read(resource.getInputStream());

                    if (stone_image.getWidth() == w)
                        break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return true;
        }

        if (stone_image.getWidth() != w) {
            LogHelper.error("Error generating texture" + name + ". Unable to find base texture with same size.");
            return true;
        }

        int h = ore_image[0].getHeight();

        // create an ARGB output image that will be used as our texture
        output_image = new BufferedImage(w, h, 2);

        // create some arrays t hold the pixel data
        // pixel data is in the form 0xaarrggbb
        int[] ore_data = new int[w * w];
        int[] stone_data = new int[w * w];

        stone_image.getRGB(0, 0, w, w, stone_data, 0, w);

        for (int y = 0; y < h; y += w) {
            // read the ARGB color data into our arrays
            ore_image[0].getRGB(0, y, w, w, ore_data, 0, w);

            // generate our new texture
            int[] new_data = createDenseTexture(w, ore_data, stone_data, renderType);

            // write the new image data to the output image buffer
            output_image.setRGB(0, y, w, w, new_data, 0, w);
        }

        // replace the old texture
        ore_image[0] = output_image;

        // load the texture
        this.loadSprite(ore_image, animation, (float) Minecraft.getMinecraft().gameSettings.anisotropicFiltering > 1.0F);

        LogHelper.info("Dense Ores: Succesfully generated dense ore texture for '" + name + "' with background '" + base + "'. Place " + name + "_dense.png in the assets folder to override.");
        return false;
    }

    private static int[] createDenseTexture(int w, int[] ore_data, int[] stone_data, int renderType) {
        int[] new_data = new int[w * w];

        // we need to work out which pixels should be considered 'ore pixels' and which should be 'base pixels'
        boolean[] same = new boolean[w * w];
        for (int i = 0; i < ore_data.length; i += 1) {
            if (getAlpha(ore_data[i]) == 0) {   // if the ore texture pixel is transparent, overwrite with the corresponding stone pixel
                same[i] = true;
                ore_data[i] = stone_data[i];
            } else if (ore_data[i] == stone_data[i]) {
                same[i] = true;
            } else {
                int r = Math.abs(getRed(ore_data[i]) - getRed(stone_data[i]));
                int g = Math.abs(getGreen(ore_data[i]) - getGreen(stone_data[i]));
                int b = Math.abs(getBlue(ore_data[i]) - getBlue(stone_data[i]));

                same[i] = (r + g + b) < 20; // check to see if the two pixels are not exactly the same but 'close'
            }

            new_data[i] = ore_data[i];
        }

        int[] dx;
        int[] dy;

        //allows for different convolution filters
        switch (renderType) {
            default:
            case 0:
                dx = new int[]{-1, 2, 3};
                dy = new int[]{-1, 0, 1};
                break;
            case 1:
                dx = new int[]{-1, 1, 0, 0, -1, -1, 1, 1, -2, 2, 0, 0};
                dy = new int[]{0, 0, -1, 1, -1, 1, -1, 1, 0, 0, -2, 2};
                break;
            case 2:
                dx = new int[]{-1, 0, 1};
                dy = new int[]{-1, 0, 1};
                break;
            case 3:
                dx = new int[]{-2, 2, 1, 1};
                dy = new int[]{1, 1, -2, 2};
            case 4:
                dx = new int[]{-6, -3, 3, 6};
                dy = new int[]{0, 0, 0, 0};
                break;
            case 5:
                dx = new int[]{-5, -5, 5, 5};
                dy = new int[]{-5, 5, -5, 5};
                break;
            case 6:
                dx = new int[]{0, 1, 2, 3};
                dy = new int[]{0, -3, 2, -1};
                break;
            case 7:
                dx = new int[]{-1, 1, 0, 0};
                dy = new int[]{0, 0, -1, 1};
                break;
        }


        // where the magic happens
        for (int i = 0; i < ore_data.length; i += 1) {
            int x = (i % w);
            int y = (i - x) / w;

            // if the pixel an ore pixel, we don't need to do anything so continue
            if (!same[i])
                continue;

            // use our convolution filter to see if we can find an ore pixel nearby
            for (int j = 0; j < dx.length; j++) {
                final int new_x = x + dx[j];
                final int new_y = y + dy[j];

                if (new_x >= 0 && new_x < w && new_y >= 0 && new_y < w) // is valid pixel location
                    if (!same[new_x + new_y * w]) { // is it an ore pixel?
                        new_data[i] = ore_data[new_x + new_y * w];
                        break;
                    }
            }
        }
        return new_data;
    }

    public static int getAlpha(int col) {
        return (col & 0xff000000) >> 24;
    }

    public static int getRed(int col) {
        return (col & 0x00ff0000) >> 16;
    }

    public static int getGreen(int col) {
        return (col & 0x0000ff00) >> 8;
    }

    public static int getBlue(int col) {
        return col & 0x000000ff;
    }

    public static int makeCol(int red, int green, int blue, int alpha) {
        return (alpha << 24) | (red << 16) | (green << 8) | blue;
    }
}
TOP

Related Classes of com.rwtema.denseores.TextureOre

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.