001 package net.minecraft.client.renderer;
002
003 import cpw.mods.fml.client.TextureFXManager;
004 import cpw.mods.fml.common.FMLLog;
005 import cpw.mods.fml.common.Side;
006 import cpw.mods.fml.common.asm.SideOnly;
007 import java.awt.Color;
008 import java.awt.Dimension;
009 import java.awt.Graphics;
010 import java.awt.image.BufferedImage;
011 import java.awt.image.ImageObserver;
012 import java.io.IOException;
013 import java.io.InputStream;
014 import java.nio.ByteBuffer;
015 import java.nio.IntBuffer;
016 import java.util.ArrayList;
017 import java.util.HashMap;
018 import java.util.Iterator;
019 import java.util.List;
020 import java.util.Map;
021 import java.util.logging.Level;
022 import java.util.logging.Logger;
023
024 import javax.imageio.ImageIO;
025 import net.minecraft.client.renderer.texturefx.TextureFX;
026 import net.minecraft.client.settings.GameSettings;
027 import net.minecraft.client.texturepacks.ITexturePack;
028 import net.minecraft.client.texturepacks.TexturePackList;
029 import net.minecraft.util.IntHashMap;
030 import org.lwjgl.opengl.GL11;
031
032 import net.minecraftforge.client.ForgeHooksClient;
033
034 @SideOnly(Side.CLIENT)
035 public 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 public boolean func_82773_c(String par1Str)
423 {
424 return this.urlToImageDataMap.containsKey(par1Str);
425 }
426
427 /**
428 * Return a ThreadDownloadImageData instance for the given URL. If it does not already exist, it is created and
429 * uses the passed ImageBuffer. If it does, its reference count is incremented.
430 */
431 public ThreadDownloadImageData obtainImageData(String par1Str, IImageBuffer par2IImageBuffer)
432 {
433 ThreadDownloadImageData var3 = (ThreadDownloadImageData)this.urlToImageDataMap.get(par1Str);
434
435 if (var3 == null)
436 {
437 this.urlToImageDataMap.put(par1Str, new ThreadDownloadImageData(par1Str, par2IImageBuffer));
438 }
439 else
440 {
441 ++var3.referenceCount;
442 }
443
444 return var3;
445 }
446
447 /**
448 * Decrements the reference count for a given URL, deleting the image data if the reference count hits 0
449 */
450 public void releaseImageData(String par1Str)
451 {
452 ThreadDownloadImageData var2 = (ThreadDownloadImageData)this.urlToImageDataMap.get(par1Str);
453
454 if (var2 != null)
455 {
456 --var2.referenceCount;
457
458 if (var2.referenceCount == 0)
459 {
460 if (var2.textureName >= 0)
461 {
462 this.deleteTexture(var2.textureName);
463 }
464
465 this.urlToImageDataMap.remove(par1Str);
466 }
467 }
468 }
469
470 public void registerTextureFX(TextureFX par1TextureFX)
471 {
472 TextureFXManager.instance().onPreRegisterEffect(par1TextureFX);
473 this.textureList.add(par1TextureFX);
474 par1TextureFX.onTick();
475 }
476
477 public void updateDynamicTextures()
478 {
479 int var1 = -1;
480
481 for (int var2 = 0; var2 < this.textureList.size(); ++var2)
482 {
483 TextureFX var3 = (TextureFX)this.textureList.get(var2);
484 var3.anaglyphEnabled = this.options.anaglyph;
485 if (TextureFXManager.instance().onUpdateTextureEffect(var3))
486 {
487 var1 = this.func_82772_a(var3, var1);
488 }
489 }
490 }
491
492 public int func_82772_a(TextureFX par1TextureFX, int par2)
493 {
494 Dimension dim = TextureFXManager.instance().getTextureDimensions(par1TextureFX);
495 int tWidth = dim.width >> 4;
496 int tHeight = dim.height >> 4;
497 int tLen = tWidth * tHeight << 2;
498
499 if (par1TextureFX.imageData.length == tLen)
500 {
501 this.imageData.clear();
502 this.imageData.put(par1TextureFX.imageData);
503 this.imageData.position(0).limit(par1TextureFX.imageData.length);
504 }
505 else
506 {
507 TextureFXManager.instance().scaleTextureFXData(par1TextureFX.imageData, imageData, tWidth, tLen);
508 }
509
510 if (par1TextureFX.textureId != par2)
511 {
512 par1TextureFX.bindImage(this);
513 par2 = par1TextureFX.textureId;
514 }
515
516 for (int var3 = 0; var3 < par1TextureFX.tileSize; ++var3)
517 {
518 int xOffset = par1TextureFX.iconIndex % 16 * tWidth + var3 * tWidth;
519 for (int var4 = 0; var4 < par1TextureFX.tileSize; ++var4)
520 {
521 int yOffset = par1TextureFX.iconIndex / 16 * tHeight + var4 * tHeight;
522 GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, xOffset, yOffset, tWidth, tHeight, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, this.imageData);
523 }
524 }
525
526 return par2;
527 }
528
529 /**
530 * Call setupTexture on all currently-loaded textures again to account for changes in rendering options
531 */
532 public void refreshTextures()
533 {
534 ITexturePack var1 = this.texturePack.getSelectedTexturePack();
535 Iterator var2 = this.textureNameToImageMap.getKeySet().iterator();
536 BufferedImage var4;
537
538 while (var2.hasNext())
539 {
540 int var3 = ((Integer)var2.next()).intValue();
541 var4 = (BufferedImage)this.textureNameToImageMap.lookup(var3);
542 this.setupTexture(var4, var3);
543 }
544
545 ThreadDownloadImageData var8;
546
547 for (var2 = this.urlToImageDataMap.values().iterator(); var2.hasNext(); var8.textureSetupComplete = false)
548 {
549 var8 = (ThreadDownloadImageData)var2.next();
550 }
551
552 var2 = this.textureMap.keySet().iterator();
553 String var9;
554
555 while (var2.hasNext())
556 {
557 var9 = (String)var2.next();
558
559 try
560 {
561 if (var9.startsWith("##"))
562 {
563 var4 = this.unwrapImageByColumns(this.readTextureImage(var1.getResourceAsStream(var9.substring(2))));
564 }
565 else if (var9.startsWith("%clamp%"))
566 {
567 this.clampTexture = true;
568 var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(7)));
569 }
570 else if (var9.startsWith("%blur%"))
571 {
572 this.blurTexture = true;
573 var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(6)));
574 }
575 else if (var9.startsWith("%blurclamp%"))
576 {
577 this.blurTexture = true;
578 this.clampTexture = true;
579 var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(11)));
580 }
581 else
582 {
583 var4 = this.readTextureImage(var1.getResourceAsStream(var9));
584 }
585
586 int var5 = ((Integer)this.textureMap.get(var9)).intValue();
587 this.setupTexture(var4, var5);
588 this.blurTexture = false;
589 this.clampTexture = false;
590 }
591 catch (Exception var7)
592 {
593 log.log(Level.INFO,String.format("An error occured reading texture file %s (refreshTexture)", var9), var7);
594 var7.printStackTrace();
595 }
596 }
597
598 var2 = this.textureContentsMap.keySet().iterator();
599
600 while (var2.hasNext())
601 {
602 var9 = (String)var2.next();
603
604 try
605 {
606 if (var9.startsWith("##"))
607 {
608 var4 = this.unwrapImageByColumns(this.readTextureImage(var1.getResourceAsStream(var9.substring(2))));
609 }
610 else if (var9.startsWith("%clamp%"))
611 {
612 this.clampTexture = true;
613 var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(7)));
614 }
615 else if (var9.startsWith("%blur%"))
616 {
617 this.blurTexture = true;
618 var4 = this.readTextureImage(var1.getResourceAsStream(var9.substring(6)));
619 }
620 else
621 {
622 var4 = this.readTextureImage(var1.getResourceAsStream(var9));
623 }
624
625 this.getImageContents(var4, (int[])this.textureContentsMap.get(var9));
626 this.blurTexture = false;
627 this.clampTexture = false;
628 }
629 catch (Exception var6)
630 {
631 log.log(Level.INFO,String.format("An error occured reading texture file data %s (refreshTexture)", var9), var6);
632 var6.printStackTrace();
633 }
634 }
635 }
636
637 /**
638 * Returns a BufferedImage read off the provided input stream. Args: inputStream
639 */
640 private BufferedImage readTextureImage(InputStream par1InputStream) throws IOException
641 {
642 BufferedImage var2 = ImageIO.read(par1InputStream);
643 par1InputStream.close();
644 return var2;
645 }
646
647 public void bindTexture(int par1)
648 {
649 if (par1 >= 0)
650 {
651 GL11.glBindTexture(GL11.GL_TEXTURE_2D, par1);
652 }
653 }
654 }