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 }