    001/*
    002 * The FML Forge Mod Loader suite.
    003 * Copyright (C) 2012 cpw
    004 *
    005 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
    006 * Software Foundation; either version 2.1 of the License, or any later version.
    007 *
    008 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    009 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    010 *
    011 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
    012 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    013 */
    014
    015package net.minecraft.src;
    016
    017import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
    018
    019import java.awt.Graphics2D;
    020import java.awt.image.BufferedImage;
    021import java.awt.image.ImageObserver;
    022
    023import net.minecraft.client.renderer.RenderEngine;
    024
    025import org.lwjgl.opengl.GL11;
    026
    027import cpw.mods.fml.client.FMLClientHandler;
    028import cpw.mods.fml.client.FMLTextureFX;
    029
    030public class ModTextureStatic extends FMLTextureFX
    031{
    032    private boolean oldanaglyph = false;
    033    private int[] pixels = null;
    034    private String targetTex = null;
    035    private int storedSize;
    036    private BufferedImage overrideData = null;
    037    private int needApply = 10;
    038
    039
    040    public ModTextureStatic(int icon, int target, BufferedImage image)
    041    {
    042        this(icon, 1, target, image);
    043    }
    044
    045    public ModTextureStatic(int icon, int size, int target, BufferedImage image)
    046    {
    047        this(icon, size, (target == 0 ? "/terrain.png" : "/gui/items.png"), image);
    048    }
    049
    050    public ModTextureStatic(int icon, int size, String target, BufferedImage image)
    051    {
    052        super(icon);
    053        RenderEngine re = FMLClientHandler.instance().getClient().renderEngine;
    054
    055        targetTex = target;
    056        storedSize = size;
    057        tileSize = size;
    058        tileImage = re.getTexture(target);
    059        overrideData = image;
    060    }
    061
    062    @Override
    063    public void setup()
    064    {
    065        super.setup();
    066        int sWidth  = overrideData.getWidth();
    067        int sHeight = overrideData.getHeight();
    068
    069        pixels = new int[tileSizeSquare];
    070        if (tileSizeBase == sWidth && tileSizeBase == sHeight)
    071        {
    072            overrideData.getRGB(0, 0, sWidth, sHeight, pixels, 0, sWidth);
    073        }
    074        else
    075        {
    076            BufferedImage tmp = new BufferedImage(tileSizeBase, tileSizeBase, 6);
    077            Graphics2D gfx = tmp.createGraphics();
    078            gfx.drawImage(overrideData, 0, 0, tileSizeBase, tileSizeBase, 0, 0, sWidth, sHeight, (ImageObserver)null);
    079            tmp.getRGB(0, 0, tileSizeBase, tileSizeBase, pixels, 0, tileSizeBase);
    080            gfx.dispose();
    081        }
    082
    083        update();
    084    }
    085
    086    @Override
    087    public void onTick()
    088    {
    089        if (oldanaglyph != anaglyphEnabled)
    090        {
    091            update();
    092        }
    093        // This makes it so we only apply the texture to the target texture when we need to,
    094        //due to the fact that update is called when the Effect is first registered, we actually
    095        //need to wait for the next one.
    096        tileSize = (needApply == 0 ? 0 : storedSize);
    097        if (needApply > 0)
    098        {
    099            needApply--;
    100        }
    101    }
    102
    103    @Override
    104    public void bindImage(RenderEngine par1RenderEngine)
    105    {
    106        GL11.glBindTexture(GL_TEXTURE_2D, par1RenderEngine.getTexture(targetTex));
    107    }
    108
    109    public void update()
    110    {
    111        needApply = 10;
    112        for (int idx = 0; idx < pixels.length; idx++)
    113        {
    114            int i = idx * 4;
    115            int a = pixels[idx] >> 24 & 255;
    116            int r = pixels[idx] >> 16 & 255;
    117            int g = pixels[idx] >> 8 & 255;
    118            int b = pixels[idx] >> 0 & 255;
    119
    120            if (anaglyphEnabled)
    121            {
    122                r = g = b = (r + g + b) / 3;
    123            }
    124
    125            imageData[i + 0] = (byte)r;
    126            imageData[i + 1] = (byte)g;
    127            imageData[i + 2] = (byte)b;
    128            imageData[i + 3] = (byte)a;
    129        }
    130
    131        oldanaglyph = anaglyphEnabled;
    132    }
    133
    134    //Implementation of http://scale2x.sourceforge.net/algorithm.html
    135    public static BufferedImage scale2x(BufferedImage image)
    136    {
    137        int w = image.getWidth();
    138        int h = image.getHeight();
    139        BufferedImage tmp = new BufferedImage(w * 2, h * 2, 2);
    140
    141        for (int x = 0; x < h; ++x)
    142        {
    143            int x2 = x * 2;
    144            for (int y = 0; y < w; ++y)
    145            {
    146                int y2 = y * 2;
    147                int E = image.getRGB(y, x);
    148                int D = (x == 0     ? E : image.getRGB(y,     x - 1));
    149                int B = (y == 0     ? E : image.getRGB(y - 1, x    ));
    150                int H = (y >= w - 1 ? E : image.getRGB(y + 1, x    ));
    151                int F = (x >= h - 1 ? E : image.getRGB(y,     x + 1));
    152
    153                int e0, e1, e2, e3;
    154
    155                if (B != H && D != F)
    156                {
    157                    e0 = D == B ? D : E;
    158                    e1 = B == F ? F : E;
    159                    e2 = D == H ? D : E;
    160                    e3 = H == F ? F : E;
    161                }
    162                else
    163                {
    164                    e0 = e1 = e2 = e3 = E;
    165                }
    166
    167                tmp.setRGB(y2,     x2,     e0);
    168                tmp.setRGB(y2 + 1, x2,     e1);
    169                tmp.setRGB(y2,     x2 + 1, e2);
    170                tmp.setRGB(y2 + 1, x2 + 1, e3);
    171            }
    172        }
    173
    174        return tmp;
    175    }
    176
    177
    178    @Override
    179    public String toString()
    180    {
    181        return String.format("ModTextureStatic %s @ %d", targetTex, iconIndex);
    182    }
    183}