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}