001package net.minecraft.client.renderer;
002
003import cpw.mods.fml.client.TextureFXManager;
004import cpw.mods.fml.common.FMLLog;
005import cpw.mods.fml.relauncher.Side;
006import cpw.mods.fml.relauncher.SideOnly;
007import java.awt.Color;
008import java.awt.Dimension;
009import java.awt.Graphics;
010import java.awt.image.BufferedImage;
011import java.awt.image.ImageObserver;
012import java.io.IOException;
013import java.io.InputStream;
014import java.nio.ByteBuffer;
015import java.nio.IntBuffer;
016import java.util.ArrayList;
017import java.util.HashMap;
018import java.util.Iterator;
019import java.util.List;
020import java.util.Map;
021import java.util.logging.Level;
022import java.util.logging.Logger;
023
024import javax.imageio.ImageIO;
025import net.minecraft.client.renderer.texturefx.TextureFX;
026import net.minecraft.client.settings.GameSettings;
027import net.minecraft.client.texturepacks.ITexturePack;
028import net.minecraft.client.texturepacks.TexturePackList;
029import net.minecraft.util.IntHashMap;
030import org.lwjgl.opengl.GL11;
031
032import net.minecraftforge.client.ForgeHooksClient;
033
034@SideOnly(Side.CLIENT)
035public class RenderEngine
036{
037    private HashMap textureMap = new HashMap();
038
039    /** Texture contents map (key: texture name, value: int[] contents) */
040    private HashMap textureContentsMap = new HashMap();
041
042    /** A mapping from GL texture names (integers) to BufferedImage instances */
043    private IntHashMap textureNameToImageMap = new IntHashMap();
044
045    /** An IntBuffer storing 1 int used as scratch space in RenderEngine */
046    private IntBuffer singleIntBuffer = GLAllocation.createDirectIntBuffer(1);
047
048    /** Stores the image data for the texture. */
049    private ByteBuffer imageData = GLAllocation.createDirectByteBuffer(16777216);
050    public List textureList = new ArrayList();
051
052    /** A mapping from image URLs to ThreadDownloadImageData instances */
053    private Map urlToImageDataMap = new HashMap();
054
055    /** Reference to the GameSettings object */
056    private GameSettings options;
057
058    /** Flag set when a texture should not be repeated */
059    public boolean clampTexture = false;
060
061    /** Flag set when a texture should use blurry resizing */
062    public boolean blurTexture = false;
063
064    /** Texture pack */
065    public TexturePackList texturePack;
066
067    /** Missing texture image */
068    private BufferedImage missingTextureImage = new BufferedImage(64, 64, 2);
069
070    public static Logger log = FMLLog.getLogger();
071
072    public RenderEngine(TexturePackList par1TexturePackList, GameSettings par2GameSettings)
073    {
074        this.texturePack = par1TexturePackList;
075        this.options = par2GameSettings;
076        Graphics var3 = this.missingTextureImage.getGraphics();
077        var3.setColor(Color.WHITE);
078        var3.fillRect(0, 0, 64, 64);
079        var3.setColor(Color.BLACK);
080        var3.drawString("missingtex", 1, 10);
081        var3.dispose();
082    }
083
084    public int[] getTextureContents(String par1Str)
085    {
086        ITexturePack var2 = this.texturePack.getSelectedTexturePack();
087        int[] var3 = (int[])this.textureContentsMap.get(par1Str);
088
089        if (var3 != null)
090        {
091            return var3;
092        }
093        else
094        {
095            try
096            {
097                Object var4 = null;
098                int[] var7;
099
100                if (par1Str.startsWith("##"))
101                {
102                    var7 = this.getImageContentsAndAllocate(this.unwrapImageByColumns(this.readTextureImage(var2.getResourceAsStream(par1Str.substring(2)))));
103                }
104                else if (par1Str.startsWith("%clamp%"))
105                {
106                    this.clampTexture = true;
107                    var7 = this.getImageContentsAndAllocate(this.readTextureImage(var2.getResourceAsStream(par1Str.substring(7))));
108                    this.clampTexture = false;
109                }
110                else if (par1Str.startsWith("%blur%"))
111                {
112                    this.blurTexture = true;
113                    this.clampTexture = true;
114                    var7 = this.getImageContentsAndAllocate(this.readTextureImage(var2.getResourceAsStream(par1Str.substring(6))));
115                    this.clampTexture = false;
116                    this.blurTexture = false;
117                }
118                else
119                {
120                    InputStream var8 = var2.getResourceAsStream(par1Str);
121
122                    if (var8 == null)
123                    {
124                        var7 = this.getImageContentsAndAllocate(this.missingTextureImage);
125                    }
126                    else
127                    {
128                        var7 = this.getImageContentsAndAllocate(this.readTextureImage(var8));
129                    }
130                }
131
132                this.textureContentsMap.put(par1Str, var7);
133                return var7;
134            }
135            catch (Exception var6)
136            {
137                log.log(Level.INFO, String.format("An error occured reading texture file %s (getTexture)", par1Str), var6);
138                var6.printStackTrace();
139                int[] var5 = this.getImageContentsAndAllocate(this.missingTextureImage);
140                this.textureContentsMap.put(par1Str, var5);
141                return var5;
142            }
143        }
144    }
145
146    private int[] getImageContentsAndAllocate(BufferedImage par1BufferedImage)
147    {
148        int var2 = par1BufferedImage.getWidth();
149        int var3 = par1BufferedImage.getHeight();
150        int[] var4 = new int[var2 * var3];
151        par1BufferedImage.getRGB(0, 0, var2, var3, var4, 0, var2);
152        return var4;
153    }
154
155    private int[] getImageContents(BufferedImage par1BufferedImage, int[] par2ArrayOfInteger)
156    {
157        int var3 = par1BufferedImage.getWidth();
158        int var4 = par1BufferedImage.getHeight();
159        par1BufferedImage.getRGB(0, 0, var3, var4, par2ArrayOfInteger, 0, var3);
160        return par2ArrayOfInteger;
161    }
162
163    public int getTexture(String par1Str)
164    {
165        Integer var2 = (Integer)this.textureMap.get(par1Str);
166
167        if (var2 != null)
168        {
169            return var2.intValue();
170        }
171        else
172        {
173            ITexturePack var6 = this.texturePack.getSelectedTexturePack();
174
175            try
176            {
177                ForgeHooksClient.onTextureLoadPre(par1Str);
178                this.singleIntBuffer.clear();
179                GLAllocation.generateTextureNames(this.singleIntBuffer);
180                int var3 = this.singleIntBuffer.get(0);
181
182                if (par1Str.startsWith("##"))
183                {
184                    this.setupTexture(this.unwrapImageByColumns(this.readTextureImage(var6.getResourceAsStream(par1Str.substring(2)))), var3);
185                }
186                else if (par1Str.startsWith("%clamp%"))
187                {
188                    this.clampTexture = true;
189                    this.setupTexture(this.readTextureImage(var6.getResourceAsStream(par1Str.substring(7))), var3);
190                    this.clampTexture = false;
191                }
192                else if (par1Str.startsWith("%blur%"))
193                {
194                    this.blurTexture = true;
195                    this.setupTexture(this.readTextureImage(var6.getResourceAsStream(par1Str.substring(6))), var3);
196                    this.blurTexture = false;
197                }
198                else if (par1Str.startsWith("%blurclamp%"))
199                {
200                    this.blurTexture = true;
201                    this.clampTexture = true;
202                    this.setupTexture(this.readTextureImage(var6.getResourceAsStream(par1Str.substring(11))), var3);
203                    this.blurTexture = false;
204                    this.clampTexture = false;
205                }
206                else
207                {
208                    InputStream var7 = var6.getResourceAsStream(par1Str);
209
210                    if (var7 == null)
211                    {
212                        this.setupTexture(this.missingTextureImage, var3);
213                    }
214                    else
215                    {
216                        this.setupTexture(this.readTextureImage(var7), var3);
217                    }
218                }
219
220                this.textureMap.put(par1Str, Integer.valueOf(var3));
221                ForgeHooksClient.onTextureLoad(par1Str, var6);
222                return var3;
223            }
224            catch (Exception var5)
225            {
226                var5.printStackTrace();
227                GLAllocation.generateTextureNames(this.singleIntBuffer);
228                int var4 = this.singleIntBuffer.get(0);
229                this.setupTexture(this.missingTextureImage, var4);
230                this.textureMap.put(par1Str, Integer.valueOf(var4));
231                return var4;
232            }
233        }
234    }
235
236    /**
237     * Takes an image with multiple 16-pixel-wide columns and creates a new 16-pixel-wide image where the columns are
238     * stacked vertically
239     */
240    private BufferedImage unwrapImageByColumns(BufferedImage par1BufferedImage)
241    {
242        int var2 = par1BufferedImage.getWidth() / 16;
243        BufferedImage var3 = new BufferedImage(16, par1BufferedImage.getHeight() * var2, 2);
244        Graphics var4 = var3.getGraphics();
245
246        for (int var5 = 0; var5 < var2; ++var5)
247        {
248            var4.drawImage(par1BufferedImage, -var5 * 16, var5 * par1BufferedImage.getHeight(), (ImageObserver)null);
249        }
250
251        var4.dispose();
252        return var3;
253    }
254
255    /**
256     * Copy the supplied image onto a newly-allocated OpenGL texture, returning the allocated texture name
257     */
258    public int allocateAndSetupTexture(BufferedImage par1BufferedImage)
259    {
260        this.singleIntBuffer.clear();
261        GLAllocation.generateTextureNames(this.singleIntBuffer);
262        int var2 = this.singleIntBuffer.get(0);
263        this.setupTexture(par1BufferedImage, var2);
264        this.textureNameToImageMap.addKey(var2, par1BufferedImage);
265        return var2;
266    }
267
268    /**
269     * Copy the supplied image onto the specified OpenGL texture
270     */
271    public void setupTexture(BufferedImage par1BufferedImage, int par2)
272    {
273        GL11.glBindTexture(GL11.GL_TEXTURE_2D, par2);
274        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
275        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
276
277        if (this.blurTexture)
278        {
279            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
280            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
281        }
282
283        if (this.clampTexture)
284        {
285            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
286            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
287        }
288        else
289        {
290            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
291            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
292        }
293
294        int var3 = par1BufferedImage.getWidth();
295        int var4 = par1BufferedImage.getHeight();
296        TextureFXManager.instance().setTextureDimensions(par2, var3, var4, (List<TextureFX>)textureList);
297        int[] var5 = new int[var3 * var4];
298        byte[] var6 = new byte[var3 * var4 * 4];
299        par1BufferedImage.getRGB(0, 0, var3, var4, var5, 0, var3);
300
301        for (int var7 = 0; var7 < var5.length; ++var7)
302        {
303            int var8 = var5[var7] >> 24 & 255;
304            int var9 = var5[var7] >> 16 & 255;
305            int var10 = var5[var7] >> 8 & 255;
306            int var11 = var5[var7] & 255;
307
308            if (this.options != null && this.options.anaglyph)
309            {
310                int var12 = (var9 * 30 + var10 * 59 + var11 * 11) / 100;
311                int var13 = (var9 * 30 + var10 * 70) / 100;
312                int var14 = (var9 * 30 + var11 * 70) / 100;
313                var9 = var12;
314                var10 = var13;
315                var11 = var14;
316            }
317
318            var6[var7 * 4 + 0] = (byte)var9;
319            var6[var7 * 4 + 1] = (byte)var10;
320            var6[var7 * 4 + 2] = (byte)var11;
321            var6[var7 * 4 + 3] = (byte)var8;
322        }
323
324        this.imageData.clear();
325        this.imageData.put(var6);
326        this.imageData.position(0).limit(var6.length);
327        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, var3, var4, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, this.imageData);
328    }
329
330    public void createTextureFromBytes(int[] par1ArrayOfInteger, int par2, int par3, int par4)
331    {
332        GL11.glBindTexture(GL11.GL_TEXTURE_2D, par4);
333        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
334        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
335
336        if (this.blurTexture)
337        {
338            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
339            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
340        }
341
342        if (this.clampTexture)
343        {
344            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
345            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
346        }
347        else
348        {
349            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
350            GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
351        }
352
353        byte[] var5 = new byte[par2 * par3 * 4];
354
355        for (int var6 = 0; var6 < par1ArrayOfInteger.length; ++var6)
356        {
357            int var7 = par1ArrayOfInteger[var6] >> 24 & 255;
358            int var8 = par1ArrayOfInteger[var6] >> 16 & 255;
359            int var9 = par1ArrayOfInteger[var6] >> 8 & 255;
360            int var10 = par1ArrayOfInteger[var6] & 255;
361
362            if (this.options != null && this.options.anaglyph)
363            {
364                int var11 = (var8 * 30 + var9 * 59 + var10 * 11) / 100;
365                int var12 = (var8 * 30 + var9 * 70) / 100;
366                int var13 = (var8 * 30 + var10 * 70) / 100;
367                var8 = var11;
368                var9 = var12;
369                var10 = var13;
370            }
371
372            var5[var6 * 4 + 0] = (byte)var8;
373            var5[var6 * 4 + 1] = (byte)var9;
374            var5[var6 * 4 + 2] = (byte)var10;
375            var5[var6 * 4 + 3] = (byte)var7;
376        }
377
378        this.imageData.clear();
379        this.imageData.put(var5);
380        this.imageData.position(0).limit(var5.length);
381        GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, par2, par3, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, this.imageData);
382    }
383
384    /**
385     * Deletes a single GL texture
386     */
387    public void deleteTexture(int par1)
388    {
389        this.textureNameToImageMap.removeObject(par1);
390        this.singleIntBuffer.clear();
391        this.singleIntBuffer.put(par1);
392        this.singleIntBuffer.flip();
393        GL11.glDeleteTextures(this.singleIntBuffer);
394    }
395
396    /**
397     * Takes a URL of a downloadable image and the name of the local image to be used as a fallback.  If the image has
398     * been downloaded, returns the GL texture of the downloaded image, otherwise returns the GL texture of the fallback
399     * image.
400     */
401    public int getTextureForDownloadableImage(String par1Str, String par2Str)
402    {
403        ThreadDownloadImageData var3 = (ThreadDownloadImageData)this.urlToImageDataMap.get(par1Str);
404
405        if (var3 != null && var3.image != null && !var3.textureSetupComplete)
406        {
407            if (var3.textureName < 0)
408            {
409                var3.textureName = this.allocateAndSetupTexture(var3.image);
410            }
411            else
412            {
413                this.setupTexture(var3.image, var3.textureName);
414            }
415
416            var3.textureSetupComplete = true;
417        }
418
419        return var3 != null && var3.textureName >= 0 ? var3.textureName : (par2Str == null ? -1 : this.getTexture(par2Str));
420    }
421
422    /**
423     * Checks if urlToImageDataMap has image data for the given key
424     */
425    public boolean hasImageData(String par1Str)
426    {
427        return this.urlToImageDataMap.containsKey(par1Str);
428    }
429
430    /**
431     * Return a ThreadDownloadImageData instance for the given URL.  If it does not already exist, it is created and
432     * uses the passed ImageBuffer.  If it does, its reference count is incremented.
433     */
434    public ThreadDownloadImageData obtainImageData(String par1Str, IImageBuffer par2IImageBuffer)
435    {
436        ThreadDownloadImageData var3 = (ThreadDownloadImageData)this.urlToImageDataMap.get(par1Str);
437
438        if (var3 == null)
439        {
440            this.urlToImageDataMap.put(par1Str, new ThreadDownloadImageData(par1Str, par2IImageBuffer));
441        }
442        else
443        {
444            ++var3.referenceCount;
445        }
446
447        return var3;
448    }
449
450    /**
451     * Decrements the reference count for a given URL, deleting the image data if the reference count hits 0
452     */
453    public void releaseImageData(String par1Str)
454    {
455        ThreadDownloadImageData var2 = (ThreadDownloadImageData)this.urlToImageDataMap.get(par1Str);
456
457        if (var2 != null)
458        {
459            --var2.referenceCount;
460
461            if (var2.referenceCount == 0)
462            {
463                if (var2.textureName >= 0)
464                {
465                    this.deleteTexture(var2.textureName);
466                }
467
468                this.urlToImageDataMap.remove(par1Str);
469            }
470        }
471    }
472
473    public void registerTextureFX(TextureFX par1TextureFX)
474    {
475        TextureFXManager.instance().onPreRegisterEffect(par1TextureFX);
476        this.textureList.add(par1TextureFX);
477        par1TextureFX.onTick();
478    }
479
480    public void updateDynamicTextures()
481    {
482        int var1 = -1;
483
484        for (int var2 = 0; var2 < this.textureList.size(); ++var2)
485        {
486            TextureFX var3 = (TextureFX)this.textureList.get(var2);
487            var3.anaglyphEnabled = this.options.anaglyph;
488            if (TextureFXManager.instance().onUpdateTextureEffect(var3))
489            {
490                var1 = this.updateDynamicTexture(var3, var1);
491            }
492        }
493    }
494
495    /**
496     * Updates a single dynamic texture
497     */
498    public int updateDynamicTexture(TextureFX par1TextureFX, int par2)
499    {
500        Dimension dim = TextureFXManager.instance().getTextureDimensions(par1TextureFX);
501        int tWidth  = dim.width >> 4;
502        int tHeight = dim.height >> 4;
503        int tLen = tWidth * tHeight << 2;
504
505        if (par1TextureFX.imageData.length == tLen)
506        {
507            this.imageData.clear();
508            this.imageData.put(par1TextureFX.imageData);
509            this.imageData.position(0).limit(par1TextureFX.imageData.length);
510        }
511        else
512        {
513            TextureFXManager.instance().scaleTextureFXData(par1TextureFX.imageData, imageData, tWidth, tLen);
514        }
515
516        if (par1TextureFX.textureId != par2)
517        {
518            par1TextureFX.bindImage(this);
519            par2 = par1TextureFX.textureId;
520        }
521
522        for (int var3 = 0; var3 < par1TextureFX.tileSize; ++var3)
523        {
524            int xOffset = par1TextureFX.iconIndex % 16 * tWidth + var3 * tWidth;
525            for (int var4 = 0; var4 < par1TextureFX.tileSize; ++var4)
526            {
527                int yOffset = par1TextureFX.iconIndex / 16 * tHeight + var4 * tHeight;
528                GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, xOffset, yOffset, tWidth, tHeight, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, this.imageData);
529            }
530        }
531
532        return par2;
533    }
534
535    /**
536     * Call setupTexture on all currently-loaded textures again to account for changes in rendering options
537     */
538    public void refreshTextures()
539    {
540        ITexturePack var1 = this.texturePack.getSelectedTexturePack();
541        Iterator var2 = this.textureNameToImageMap.getKeySet().iterator();
542        BufferedImage var4;
543
544        while (var2.hasNext())
545        {
546            int var3 = ((Integer)var2.next()).intValue();
547            var4 = (BufferedImage)this.textureNameToImageMap.lookup(var3);
548            this.setupTexture(var4, var3);
549        }
550
551        ThreadDownloadImageData var8;
552
553        for (var2 = this.urlToImageDataMap.values().iterator(); var2.hasNext(); var8.textureSetupComplete = false)
554        {
555            var8 = (ThreadDownloadImageData)var2.next();
556        }
557
558        var2 = this.textureMap.keySet().iterator();
559        String var9;
560
561        while (var2.hasNext())
562        {
563            var9 = (String)var2.next();
564
565            try
566            {
567                if (var9.startsWith("##"))
568                {
569                    var4 = this.unwrapImageByColumns(this.readTextureImage(var1.getResourceAsStream(var9.substring(2))));
570                }
571                else if (var9.startsWith("%clamp%"))
572                {
573                    this.clampTexture = true;
574                    var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(7)));
575                }
576                else if (var9.startsWith("%blur%"))
577                {
578                    this.blurTexture = true;
579                    var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(6)));
580                }
581                else if (var9.startsWith("%blurclamp%"))
582                {
583                    this.blurTexture = true;
584                    this.clampTexture = true;
585                    var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(11)));
586                }
587                else
588                {
589                    var4 = this.readTextureImage(var1.getResourceAsStream(var9));
590                }
591
592                int var5 = ((Integer)this.textureMap.get(var9)).intValue();
593                this.setupTexture(var4, var5);
594                this.blurTexture = false;
595                this.clampTexture = false;
596            }
597            catch (Exception var7)
598            {
599                log.log(Level.INFO,String.format("An error occured reading texture file %s (refreshTexture)", var9), var7);
600                var7.printStackTrace();
601            }
602        }
603
604        var2 = this.textureContentsMap.keySet().iterator();
605
606        while (var2.hasNext())
607        {
608            var9 = (String)var2.next();
609
610            try
611            {
612                if (var9.startsWith("##"))
613                {
614                    var4 = this.unwrapImageByColumns(this.readTextureImage(var1.getResourceAsStream(var9.substring(2))));
615                }
616                else if (var9.startsWith("%clamp%"))
617                {
618                    this.clampTexture = true;
619                    var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(7)));
620                }
621                else if (var9.startsWith("%blur%"))
622                {
623                    this.blurTexture = true;
624                    var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(6)));
625                }
626                else
627                {
628                    var4 = this.readTextureImage(var1.getResourceAsStream(var9));
629                }
630
631                this.getImageContents(var4, (int[])this.textureContentsMap.get(var9));
632                this.blurTexture = false;
633                this.clampTexture = false;
634            }
635            catch (Exception var6)
636            {
637                log.log(Level.INFO,String.format("An error occured reading texture file data %s (refreshTexture)", var9), var6);
638                var6.printStackTrace();
639            }
640        }
641    }
642
643    /**
644     * Returns a BufferedImage read off the provided input stream.  Args: inputStream
645     */
646    private BufferedImage readTextureImage(InputStream par1InputStream) throws IOException
647    {
648        BufferedImage var2 = ImageIO.read(par1InputStream);
649        par1InputStream.close();
650        return var2;
651    }
652
653    public void bindTexture(int par1)
654    {
655        if (par1 >= 0)
656        {
657            GL11.glBindTexture(GL11.GL_TEXTURE_2D, par1);
658        }
659    }
660}