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    
015    package net.minecraft.src;
016    
017    import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
018    
019    import java.awt.Graphics2D;
020    import java.awt.image.BufferedImage;
021    import java.awt.image.ImageObserver;
022    
023    import net.minecraft.client.renderer.RenderEngine;
024    
025    import org.lwjgl.opengl.GL11;
026    
027    import cpw.mods.fml.client.FMLClientHandler;
028    import cpw.mods.fml.client.FMLTextureFX;
029    
030    public 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    }