Normand Briere
2019-07-22 c570e1e38f2ff8622a71f81436654bad01cfdd5b
CameraPane.java
....@@ -45,6 +45,39 @@
4545
4646 static int STEP = 1;
4747
48
+ private static BufferedImage CreateBim(byte[] bytes, int width, int height)
49
+ {
50
+ int[] pixels = new int[bytes.length/3];
51
+ for (int i=pixels.length; --i>=0;)
52
+ {
53
+ int i3 = i*3;
54
+ pixels[i] = 0xFF;
55
+ pixels[i] <<= 8;
56
+ pixels[i] |= bytes[i3+2] & 0xFF;
57
+ pixels[i] <<= 8;
58
+ pixels[i] |= bytes[i3+1] & 0xFF;
59
+ pixels[i] <<= 8;
60
+ pixels[i] |= bytes[i3] & 0xFF;
61
+ }
62
+ /*
63
+ int r=0,g=0,b=0,a=0;
64
+ for (int i=0; i<width; i++)
65
+ for (int j=0; j<height; j++)
66
+ {
67
+ int index = j*width+i;
68
+ int p = pixels[index];
69
+ a = ((p>>24) & 0xFF);
70
+ r = ((p>>16) & 0xFF);
71
+ g = ((p>>8) & 0xFF);
72
+ b = (p & 0xFF);
73
+ pixels[index] = (a<<24) | (b<<16) | (g<<8) | r;
74
+ }
75
+ /**/
76
+ BufferedImage rendImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
77
+ rendImage.setRGB(0,0,width,height,pixels,width*(height-1),-width);
78
+ return rendImage;
79
+ }
80
+
4881 /*static*/ private boolean CULLFACE = false; // true;
4982 /*static*/ boolean NEAREST = false; // true;
5083 /*static*/ boolean WIREFRAME = false; // true;
....@@ -2405,6 +2438,21 @@
24052438 return currentGL;
24062439 }
24072440
2441
+ static private BufferedImage CreateBim(TextureData texturedata)
2442
+ {
2443
+ Grafreed.Assert(texturedata != null);
2444
+
2445
+ int width = texturedata.getWidth();
2446
+ int height = texturedata.getHeight();
2447
+
2448
+ Buffer buffer = texturedata.getBuffer();
2449
+ ByteBuffer bytebuf = (ByteBuffer)buffer;
2450
+
2451
+ byte[] bytes = bytebuf.array();
2452
+
2453
+ return CreateBim(bytes, width, height);
2454
+ }
2455
+
24082456 /**/
24092457 class CacheTexture
24102458 {
....@@ -2413,18 +2461,20 @@
24132461
24142462 int resolution;
24152463
2416
- CacheTexture(com.sun.opengl.util.texture.Texture tex, int res)
2464
+ CacheTexture(com.sun.opengl.util.texture.TextureData texdata, int res)
24172465 {
2418
- texture = tex;
2466
+ texture = com.sun.opengl.util.texture.TextureIO.newTexture(texdata);
2467
+ texturedata = texdata;
24192468 resolution = res;
24202469 }
24212470 }
24222471 /**/
24232472
24242473 // TEXTURE static Texture texture;
2425
- static public java.util.Hashtable<String, CacheTexture> textures = new java.util.Hashtable<String, CacheTexture>();
2426
- static public java.util.Hashtable<BufferedImage, CacheTexture> bimtextures = new java.util.Hashtable<BufferedImage, CacheTexture>();
2427
- static public java.util.HashSet<String> usedtextures = new java.util.HashSet<String>();
2474
+ static public Hashtable<cTexture, CacheTexture> texturepigment = new Hashtable<cTexture, CacheTexture>();
2475
+ static public Hashtable<cTexture, CacheTexture> texturebump = new Hashtable<cTexture, CacheTexture>();
2476
+ static public Hashtable<byte[], CacheTexture> bimtextures = new Hashtable<byte[], CacheTexture>();
2477
+ static public java.util.HashSet<cTexture> usedtextures = new java.util.HashSet<cTexture>();
24282478
24292479 int pigmentdepth = 0;
24302480 public com.sun.opengl.util.texture.Texture[] pigmentstack = new com.sun.opengl.util.texture.Texture[65536];
....@@ -2432,10 +2482,10 @@
24322482 public com.sun.opengl.util.texture.Texture[] bumpstack = new com.sun.opengl.util.texture.Texture[65536];
24332483 //public static String DEFAULT_TEXTURE = "DEFAULT_TEXTURE";
24342484 public static cTexture DEFAULT_TEXTURES = new cTexture("DEFAULT_TEXTURE" + ":" + "DEFAULT_TEXTURE_BUMP");
2435
- public static String NOISE_TEXTURE = "WHITE_NOISE";
2485
+ public static cTexture NOISE_TEXTURE = new cTexture("WHITE_NOISE:");
24362486 // public static cTexture IMMORTAL_TEXTURE = new cTexture("IMMORTAL");
24372487
2438
- com.sun.opengl.util.texture.Texture GetResourceTexture(String name, boolean bump)
2488
+ com.sun.opengl.util.texture.TextureData GetResourceTexture(String name, boolean bump)
24392489 {
24402490 TextureData texturedata = null;
24412491
....@@ -2454,16 +2504,16 @@
24542504 if (bump)
24552505 texturedata = ConvertBump(texturedata, false);
24562506
2457
- com.sun.opengl.util.texture.Texture texture =
2458
- com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
2507
+// com.sun.opengl.util.texture.Texture texture =
2508
+// com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
24592509
2460
- texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
2461
- texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
2510
+ //texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
2511
+ //texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
24622512
2463
- return texture;
2513
+ return texturedata;
24642514 }
24652515
2466
- com.sun.opengl.util.texture.Texture GetBimTexture(BufferedImage name, boolean bump)
2516
+ com.sun.opengl.util.texture.TextureData GetBimTexture(BufferedImage bim, boolean bump)
24672517 {
24682518 TextureData texturedata = null;
24692519
....@@ -2471,7 +2521,7 @@
24712521 {
24722522 texturedata =
24732523 com.sun.opengl.util.texture.TextureIO.newTextureData(
2474
- name,
2524
+ bim,
24752525 true);
24762526 } catch (Exception e)
24772527 {
....@@ -2480,14 +2530,8 @@
24802530
24812531 if (bump)
24822532 texturedata = ConvertBump(texturedata, false);
2483
-
2484
- com.sun.opengl.util.texture.Texture texture =
2485
- com.sun.opengl.util.texture.TextureIO.newTexture(texturedata);
2486
-
2487
- texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_S, javax.media.opengl.GL.GL_REPEAT);
2488
- texture.setTexParameteri(javax.media.opengl.GL.GL_TEXTURE_WRAP_T, javax.media.opengl.GL.GL_REPEAT);
2489
-
2490
- return texture;
2533
+
2534
+ return texturedata;
24912535 }
24922536
24932537 boolean HUESMOOTH = true; // wrap around bug... true;
....@@ -7975,8 +8019,8 @@
79758019 pigment = null;
79768020 }
79778021
7978
- ReleaseTexture(bump, true);
7979
- ReleaseTexture(pigment, false);
8022
+ ReleaseTexture(tex, true);
8023
+ ReleaseTexture(tex, false);
79808024 }
79818025
79828026 public void ReleasePigmentTexture(cTexture tex) // INTERFACE
....@@ -8005,7 +8049,7 @@
80058049 pigment = null;
80068050 }
80078051
8008
- ReleaseTexture(pigment, false);
8052
+ ReleaseTexture(tex, false);
80098053 }
80108054
80118055 public void ReleaseBumpTexture(cTexture tex) // INTERFACE
....@@ -8034,10 +8078,10 @@
80348078 bump = null;
80358079 }
80368080
8037
- ReleaseTexture(bump, true);
8081
+ ReleaseTexture(tex, true);
80388082 }
80398083
8040
- void ReleaseTexture(String tex, boolean bump)
8084
+ void ReleaseTexture(cTexture tex, boolean bump)
80418085 {
80428086 if (// DrawMode() != 0 || /*tex == null ||*/
80438087 ambientOcclusion ) // || !textureon)
....@@ -8048,7 +8092,7 @@
80488092 CacheTexture/*com.sun.opengl.util.texture.Texture*/ texture = null;
80498093
80508094 if (tex != null)
8051
- texture = textures.get(tex);
8095
+ texture = bump ? texturebump.get(tex) : texturepigment.get(tex);
80528096
80538097 // //assert( texture != null );
80548098 // if (texture == null)
....@@ -8198,13 +8242,13 @@
81988242
81998243 if (tex == null)
82008244 {
8201
- BindTexture(null, null,false,resolution);
8245
+ BindTexture(null,false,resolution);
82028246 return;
82038247 }
82048248
82058249 String pigment = Object3D.GetPigment(tex);
82068250
8207
- usedtextures.add(pigment);
8251
+ usedtextures.add(tex);
82088252
82098253 //if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
82108254 {
....@@ -8218,7 +8262,7 @@
82188262 }
82198263
82208264 GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
8221
- BindTexture(tex.pigmenttexture, pigment, false, resolution);
8265
+ BindTexture(tex, false, resolution);
82228266 }
82238267
82248268 /*boolean*/ public void BindBumpTexture(cTexture tex, int resolution) throws Exception // INTERFACE
....@@ -8231,13 +8275,13 @@
82318275
82328276 if (tex == null)
82338277 {
8234
- BindTexture(null, null,true,resolution);
8278
+ BindTexture(null,true,resolution);
82358279 return;
82368280 }
82378281
82388282 String bump = Object3D.GetBump(tex);
82398283
8240
- usedtextures.add(bump);
8284
+ usedtextures.add(tex);
82418285
82428286 //if (!tex.equals(":") && !tex.equals(DEFAULT_TEXTURES))
82438287 {
....@@ -8251,7 +8295,7 @@
82518295 }
82528296
82538297 GetGL().glActiveTexture(GetGL().GL_TEXTURE2);
8254
- BindTexture(tex.bumptexture, bump, true, resolution);
8298
+ BindTexture(tex, true, resolution);
82558299 GetGL().glActiveTexture(GetGL().GL_TEXTURE0);
82568300 }
82578301
....@@ -8275,13 +8319,19 @@
82758319 return fileExists;
82768320 }
82778321
8278
- CacheTexture GetCacheTexture(java.awt.image.BufferedImage bim, String tex, boolean bump, int resolution) throws Exception
8322
+ CacheTexture GetCacheTexture(cTexture tex, boolean bump, int resolution) throws Exception
82798323 {
82808324 CacheTexture texturecache = null;
82818325
82828326 if (tex != null)
82838327 {
8284
- String texname = tex;
8328
+ String texname = bump ? Object3D.GetBump(tex) : Object3D.GetPigment(tex);
8329
+ byte[] texdata = bump ? tex.bumpdata : tex.pigmentdata;
8330
+
8331
+ if (texname.equals("") && texdata == null)
8332
+ {
8333
+ return null;
8334
+ }
82858335
82868336 String fallbackTextureName = defaultDirectory + "/Textures/" + texname;
82878337
....@@ -8291,29 +8341,34 @@
82918341 // else
82928342 // if (!texname.startsWith("/"))
82938343 // texname = "/Users/nbriere/Textures/" + texname;
8294
- if (!FileExists(tex))
8344
+ if (!FileExists(texname))
82958345 {
82968346 texname = fallbackTextureName;
82978347 }
82988348
82998349 if (CACHETEXTURE)
83008350 {
8301
- if (bim == null)
8302
- texturecache = textures.get(texname); // TEXTURE CACHE
8351
+ if (texdata == null)
8352
+ texturecache = bump ? texturebump.get(tex) : texturepigment.get(tex);
83038353 else
8304
- texturecache = bimtextures.get(bim); // TEXTURE CACHE
8354
+ texturecache = bimtextures.get(texdata);
83058355 }
83068356
8307
- if (texturecache == null || texturecache.resolution < resolution)
8357
+ if (texturecache == null || texturecache.resolution != -1 && texturecache.resolution < resolution)
83088358 {
83098359 TextureData texturedata = null;
83108360
8311
- if (bim == null)
8361
+ if (texdata != null)
83128362 {
8363
+ BufferedImage bim = //new BufferedImage(bump?tex.bw:tex.pw, bump?tex.bh:tex.ph, BufferedImage.TYPE_INT_RGB);
83138364
8365
+ CreateBim(texdata, bump?tex.bw:tex.pw, bump?tex.bh:tex.ph);
8366
+
8367
+ texturecache = new CacheTexture(GetBimTexture(bim, bump), -1);
8368
+ bimtextures.put(texdata, texturecache);
83148369 }
83158370 else
8316
- if (tex.equals("DEFAULT_TEXTURE")) // ||*/ tex.equals(""))
8371
+ if (texname.endsWith("DEFAULT_TEXTURE")) // ||*/ tex.equals(""))
83178372 {
83188373 assert(!bump);
83198374 // if (bump)
....@@ -8324,19 +8379,23 @@
83248379 // }
83258380 // else
83268381 // {
8327
- texturecache = textures.get(tex);
8382
+ // texturecache = textures.get(texname); // suspicious
83288383 if (texturecache == null)
83298384 {
83308385 texturecache = new CacheTexture(GetResourceTexture("default.png", bump),resolution);
83318386 }
8387
+ else
8388
+ new Exception().printStackTrace();
83328389 // }
83338390 } else
8334
- if (tex.equals("DEFAULT_TEXTURE_BUMP")) // ||*/ tex.equals(""))
8391
+ if (texname.endsWith("DEFAULT_TEXTURE_BUMP")) // ||*/ tex.equals(""))
83358392 {
83368393 assert(bump);
8337
- texturecache = textures.get(tex);
8394
+ // texturecache = textures.get(texname); // suspicious
83388395 if (texturecache == null)
83398396 texturecache = new CacheTexture(GetResourceTexture("default.png", bump),resolution);
8397
+ else
8398
+ new Exception().printStackTrace();
83408399 } else
83418400 {
83428401 //if (tex.equals("IMMORTAL"))
....@@ -8344,11 +8403,13 @@
83448403 // texture = GetResourceTexture("default.png");
83458404 //} else
83468405 //{
8347
- if (tex.equals("WHITE_NOISE"))
8406
+ if (texname.endsWith("WHITE_NOISE"))
83488407 {
8349
- texturecache = textures.get(tex);
8408
+ // texturecache = textures.get(texname); // suspicious
83508409 if (texturecache == null)
83518410 texturecache = new CacheTexture(GetResourceTexture("whitenoise.png", bump),resolution);
8411
+ else
8412
+ new Exception().printStackTrace();
83528413 } else
83538414 {
83548415 if (textureon)
....@@ -8407,14 +8468,14 @@
84078468 if (texturedata == null)
84088469 throw new Exception();
84098470
8410
- texturecache = new CacheTexture(com.sun.opengl.util.texture.TextureIO.newTexture(texturedata),resolution);
8471
+ texturecache = new CacheTexture(texturedata,resolution);
84118472 //texture = GetTexture(tex, bump);
84128473 }
84138474 }
84148475 //}
84158476 }
84168477
8417
- if (/*CACHETEXTURE &&*/ texturecache != null && textureon)
8478
+ if (texdata == null && /*CACHETEXTURE &&*/ texturecache != null && textureon)
84188479 {
84198480 //return false;
84208481
....@@ -8436,52 +8497,17 @@
84368497 File cachefile = new File(texname.substring(0, texname.length()-4)+ext+".jpg");
84378498 if (!cachefile.exists())
84388499 {
8439
- // cache to disk
8440
- Buffer buffer = texturedata.getBuffer(); // getMipmapData();
8441
- //buffers[0].
8442
-
8443
- ByteBuffer bytebuf = (ByteBuffer)buffer; // ).asIntBuffer();
8444
- int[] pixels = new int[bytebuf.capacity()/3];
8445
-
8446
- // squared size heuristic...
8447
- if ((int)Math.sqrt(pixels.length) == Math.sqrt(pixels.length))
8500
+ //if (texturedata.getWidth() == texturedata.getHeight())
84488501 {
8449
- for (int i=pixels.length; --i>=0;)
8450
- {
8451
- int i3 = i*3;
8452
- pixels[i] = 0xFF;
8453
- pixels[i] <<= 8;
8454
- pixels[i] |= bytebuf.get(i3+2) & 0xFF;
8455
- pixels[i] <<= 8;
8456
- pixels[i] |= bytebuf.get(i3+1) & 0xFF;
8457
- pixels[i] <<= 8;
8458
- pixels[i] |= bytebuf.get(i3) & 0xFF;
8459
- }
8460
-
8461
- /*
8462
- int r=0,g=0,b=0,a=0;
8463
- for (int i=0; i<width; i++)
8464
- for (int j=0; j<height; j++)
8465
- {
8466
- int index = j*width+i;
8467
- int p = pixels[index];
8468
- a = ((p>>24) & 0xFF);
8469
- r = ((p>>16) & 0xFF);
8470
- g = ((p>>8) & 0xFF);
8471
- b = (p & 0xFF);
8472
- pixels[index] = (a<<24) | (b<<16) | (g<<8) | r;
8473
- }
8474
- /**/
8475
- int width = (int)Math.sqrt(pixels.length); // squared
8476
- int height = width;
8477
- BufferedImage rendImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // ImageIO.read(infile);
8478
- rendImage.setRGB(0,0,width,height,pixels,width*(height-1),-width);
8502
+ BufferedImage rendImage = CreateBim(texturedata);
8503
+
84798504 ImageWriter writer = null;
84808505 Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
84818506 if (iter.hasNext()) {
84828507 writer = (ImageWriter)iter.next();
84838508 }
8484
- float compressionQuality = 0.9f;
8509
+
8510
+ float compressionQuality = 0.85f;
84858511 try
84868512 {
84878513 ImageOutputStream ios = ImageIO.createImageOutputStream(cachefile);
....@@ -8498,18 +8524,20 @@
84988524 }
84998525 }
85008526 }
8501
-
8527
+
8528
+ Hashtable<cTexture, CacheTexture> textures = bump ? texturebump : texturepigment;
8529
+
85028530 //System.out.println("Texture = " + tex);
8503
- if (textures.containsKey(texname))
8531
+ if (textures.containsKey(tex))
85048532 {
8505
- CacheTexture thetex = textures.get(texname);
8533
+ CacheTexture thetex = textures.get(tex);
85068534 thetex.texture.disable();
85078535 thetex.texture.dispose();
8508
- textures.remove(texname);
8536
+ textures.remove(tex);
85098537 }
85108538
85118539 //texture.texturedata = texturedata;
8512
- textures.put(texname, texturecache);
8540
+ textures.put(tex, texturecache);
85138541
85148542 // newtex = true;
85158543 }
....@@ -8528,9 +8556,40 @@
85288556 return texturecache;
85298557 }
85308558
8531
- com.sun.opengl.util.texture.Texture GetTexture(java.awt.image.BufferedImage stream, String tex, boolean bump, int resolution) throws Exception
8559
+ static void EmbedTextures(cTexture tex)
85328560 {
8533
- CacheTexture texture = GetCacheTexture(stream, tex, bump, resolution);
8561
+ if (tex.pigmentdata == null)
8562
+ {
8563
+ String texname = Object3D.GetPigment(tex);
8564
+
8565
+ CacheTexture texturecache = texturepigment.get(tex);
8566
+
8567
+ if (texturecache != null)
8568
+ {
8569
+ tex.pigmentdata = ((ByteBuffer)texturecache.texturedata.getBuffer()).array();
8570
+ tex.pw = texturecache.texturedata.getWidth();
8571
+ tex.ph = texturecache.texturedata.getHeight();
8572
+ }
8573
+ }
8574
+
8575
+ if (tex.bumpdata == null)
8576
+ {
8577
+ String texname = Object3D.GetBump(tex);
8578
+
8579
+ CacheTexture texturecache = texturebump.get(tex);
8580
+
8581
+ if (texturecache != null)
8582
+ {
8583
+ tex.bumpdata = ((ByteBuffer)texturecache.texturedata.getBuffer()).array();
8584
+ tex.bw = texturecache.texturedata.getWidth();
8585
+ tex.bh = texturecache.texturedata.getHeight();
8586
+ }
8587
+ }
8588
+ }
8589
+
8590
+ com.sun.opengl.util.texture.Texture GetTexture(cTexture tex, boolean bump, int resolution) throws Exception
8591
+ {
8592
+ CacheTexture texture = GetCacheTexture(tex, bump, resolution);
85348593
85358594 if (bump)
85368595 {
....@@ -8546,14 +8605,14 @@
85468605 return texture!=null?texture.texture:null;
85478606 }
85488607
8549
- public com.sun.opengl.util.texture.TextureData GetTextureData(java.awt.image.BufferedImage stream, String tex, boolean bump, int resolution) throws Exception
8608
+ public com.sun.opengl.util.texture.TextureData GetTextureData(cTexture tex, boolean bump, int resolution) throws Exception
85508609 {
8551
- CacheTexture texture = GetCacheTexture(stream, tex, bump, resolution);
8610
+ CacheTexture texture = GetCacheTexture(tex, bump, resolution);
85528611
85538612 return texture!=null?texture.texturedata:null;
85548613 }
85558614
8556
- boolean BindTexture(java.awt.image.BufferedImage stream, String tex, boolean bump, int resolution) throws Exception
8615
+ boolean BindTexture(cTexture tex, boolean bump, int resolution) throws Exception
85578616 {
85588617 if (/*tex == null ||*/ ambientOcclusion ) // || !textureon)
85598618 {
....@@ -8562,7 +8621,7 @@
85628621
85638622 //boolean newtex = false;
85648623
8565
- com.sun.opengl.util.texture.Texture texture = GetTexture(stream, tex, bump, resolution);
8624
+ com.sun.opengl.util.texture.Texture texture = GetTexture(tex, bump, resolution);
85668625
85678626 if (texture == null)
85688627 return false;
....@@ -11049,7 +11108,7 @@
1104911108
1105011109 try
1105111110 {
11052
- BindTexture(null, NOISE_TEXTURE, false, 2);
11111
+ BindTexture(NOISE_TEXTURE, false, 2);
1105311112 }
1105411113 catch (Exception e)
1105511114 {
....@@ -11705,20 +11764,32 @@
1170511764 ReleaseTextures(DEFAULT_TEXTURES);
1170611765
1170711766 if (CLEANCACHE)
11708
- for (java.util.Enumeration<String> e = textures.keys() ; e.hasMoreElements();)
11767
+ for (java.util.Enumeration<cTexture> e = texturepigment.keys() ; e.hasMoreElements();)
1170911768 {
11710
- String tex = e.nextElement();
11769
+ cTexture tex = e.nextElement();
1171111770
1171211771 // System.out.println("Texture --------- " + tex);
1171311772
11714
- if (tex.equals("WHITE_NOISE"))
11773
+ if (tex.equals("WHITE_NOISE:"))
1171511774 continue;
1171611775
1171711776 if (!usedtextures.contains(tex))
1171811777 {
11778
+ CacheTexture gettex = texturepigment.get(tex);
1171911779 // System.out.println("DISPOSE +++++++++++++++ " + tex);
11720
- textures.get(tex).texture.dispose();
11721
- textures.remove(tex);
11780
+ if (gettex != null)
11781
+ {
11782
+ gettex.texture.dispose();
11783
+ texturepigment.remove(tex);
11784
+ }
11785
+
11786
+ gettex = texturebump.get(tex);
11787
+ // System.out.println("DISPOSE +++++++++++++++ " + tex);
11788
+ if (gettex != null)
11789
+ {
11790
+ gettex.texture.dispose();
11791
+ texturebump.remove(tex);
11792
+ }
1172211793 }
1172311794 }
1172411795 }
....@@ -14911,7 +14982,8 @@
1491114982 // break;
1491214983 case 'T':
1491314984 CACHETEXTURE ^= true;
14914
- textures.clear();
14985
+ texturepigment.clear();
14986
+ texturebump.clear();
1491514987 // repaint();
1491614988 break;
1491714989 case 'Y':