commit 7602a82767eb61ee52cbd00822843742c498eaf8
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu May 2 23:41:10 2019 +0100

    Rename all the classes that are not exported to application to 'Internal'

diff --git a/src/main/java/org/distorted/library/effect/Effect.java b/src/main/java/org/distorted/library/effect/Effect.java
index 3fb87ce..3258549 100644
--- a/src/main/java/org/distorted/library/effect/Effect.java
+++ b/src/main/java/org/distorted/library/effect/Effect.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/EffectName.java b/src/main/java/org/distorted/library/effect/EffectName.java
index cea4786..4f635ed 100644
--- a/src/main/java/org/distorted/library/effect/EffectName.java
+++ b/src/main/java/org/distorted/library/effect/EffectName.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/EffectQuality.java b/src/main/java/org/distorted/library/effect/EffectQuality.java
index 2017549..ad5665e 100644
--- a/src/main/java/org/distorted/library/effect/EffectQuality.java
+++ b/src/main/java/org/distorted/library/effect/EffectQuality.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/EffectType.java b/src/main/java/org/distorted/library/effect/EffectType.java
index ed4bc88..983228a 100644
--- a/src/main/java/org/distorted/library/effect/EffectType.java
+++ b/src/main/java/org/distorted/library/effect/EffectType.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffect.java b/src/main/java/org/distorted/library/effect/FragmentEffect.java
index ae50218..f6643a9 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffect.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffect.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java b/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
index a397fdd..3786851 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -83,7 +83,7 @@ public class FragmentEffectAlpha extends FragmentEffect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java b/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
index 3612b16..cc5fb2a 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -81,7 +81,7 @@ public class FragmentEffectBrightness extends FragmentEffect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java b/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
index c74d8ec..0660b9c 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -91,7 +91,7 @@ public class FragmentEffectChroma extends FragmentEffect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java b/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
index 690d022..e90150b 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -81,7 +81,7 @@ public class FragmentEffectContrast extends FragmentEffect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java b/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
index e947896..3cbd38d 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -83,7 +83,7 @@ public class FragmentEffectSaturation extends FragmentEffect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffect.java b/src/main/java/org/distorted/library/effect/MatrixEffect.java
index 125f532..65c0663 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffect.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffect.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectMove.java b/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
index 6be6a7f..1f98f50 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
index 3c59bb5..bd6c33e 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
index 14c33b0..8306e73 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectScale.java b/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
index 4d36383..095fda4 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
index 6ec7c27..b8e5fe9 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffect.java b/src/main/java/org/distorted/library/effect/PostprocessEffect.java
index a1f2be3..cf858db 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffect.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffect.java
@@ -1,26 +1,26 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
 
 import org.distorted.library.main.DistortedFramebuffer;
-import org.distorted.library.main.DistortedMaster;
+import org.distorted.library.main.InternalMaster;
 import org.distorted.library.program.DistortedProgram;
 
 import java.lang.reflect.Method;
@@ -33,7 +33,7 @@ import java.util.ArrayList;
 /**
  * Abstract class that represents an Effect that works by running a certain Shader Program(s) on a Framebuffer.
  */
-public abstract class PostprocessEffect extends Effect implements DistortedMaster.Slave
+public abstract class PostprocessEffect extends Effect implements InternalMaster.Slave
   {
   private static final int MIPMAP = 0;
 /**
@@ -251,6 +251,6 @@ public abstract class PostprocessEffect extends Effect implements DistortedMaste
   public void setQuality(EffectQuality quality)
     {
     mJobs.add(new Job(MIPMAP,quality.getLevel()));
-    DistortedMaster.newSlave(this);
+    InternalMaster.newSlave(this);
     }
   }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
index 772ef16..5bbf95a 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
@@ -1,29 +1,29 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
 
 import android.opengl.GLES31;
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedFramebuffer;
-import org.distorted.library.main.DistortedRenderState;
+import org.distorted.library.main.InternalRenderState;
 import org.distorted.library.program.DistortedProgram;
 import org.distorted.library.type.Data1D;
 
@@ -169,7 +169,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
         }
       }
 
-    DistortedRenderState.useStencilMark();
+    InternalRenderState.useStencilMark();
 
     buffer.setAsOutput();
 
@@ -230,7 +230,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
     GLES31.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
     GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
-    DistortedRenderState.unuseStencilMark();
+    InternalRenderState.unuseStencilMark();
 
     return 2;
     }
@@ -239,13 +239,13 @@ public class PostprocessEffectBlur extends PostprocessEffect
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
     final String blurVertex =
 
-        Distorted.GLSL_VERSION   +
+        DistortedLibrary.GLSL_VERSION   +
       "precision lowp float;  \n"+
       "in vec2 a_Position;    \n"+
       "in vec2 a_TexCoord;    \n"+
@@ -261,7 +261,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
 
     final String blurFragment1 =
 
-        Distorted.GLSL_VERSION               +
+        DistortedLibrary.GLSL_VERSION               +
       "#define MAX_BLUR "+MAX_HALO+      "\n"+
       "precision lowp float;              \n"+
       "in vec2 v_TexCoord;                \n"+
@@ -284,7 +284,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
 
     final String blurFragment2 =
 
-        Distorted.GLSL_VERSION               +
+        DistortedLibrary.GLSL_VERSION               +
       "#define MAX_BLUR "+MAX_HALO+      "\n"+
       "precision lowp float;              \n"+
       "in vec2 v_TexCoord;                \n"+
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
index 5355fa2..ea0e575 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
@@ -1,29 +1,29 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
 
 import android.opengl.GLES31;
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedFramebuffer;
-import org.distorted.library.main.DistortedRenderState;
+import org.distorted.library.main.InternalRenderState;
 import org.distorted.library.program.DistortedProgram;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data4D;
@@ -172,7 +172,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
         }
       }
 
-    DistortedRenderState.useStencilMark();
+    InternalRenderState.useStencilMark();
 
     buffer.setAsOutput();
 
@@ -233,7 +233,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
     GLES31.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
     GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
-    DistortedRenderState.unuseStencilMark();
+    InternalRenderState.unuseStencilMark();
 
     return 2;
     }
@@ -242,13 +242,13 @@ public class PostprocessEffectGlow extends PostprocessEffect
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
     final String glowVertex =
 
-        Distorted.GLSL_VERSION   +
+        DistortedLibrary.GLSL_VERSION   +
             "precision lowp float;  \n"+
             "in vec2 a_Position;    \n"+
             "in vec2 a_TexCoord;    \n"+
@@ -264,7 +264,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
 
     final String glowFragment1 =
 
-        Distorted.GLSL_VERSION               +
+        DistortedLibrary.GLSL_VERSION               +
             "#define MAX_BLUR "+MAX_HALO+      "\n"+
             "precision lowp float;              \n"+
             "in vec2 v_TexCoord;                \n"+
@@ -287,7 +287,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
 
     final String glowFragment2 =
 
-        Distorted.GLSL_VERSION               +
+        DistortedLibrary.GLSL_VERSION               +
             "#define MAX_BLUR "+MAX_HALO+      "\n"+
             "precision lowp float;              \n"+
             "in vec2 v_TexCoord;                \n"+
diff --git a/src/main/java/org/distorted/library/effect/VertexEffect.java b/src/main/java/org/distorted/library/effect/VertexEffect.java
index 3e13d17..f2a44d0 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffect.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffect.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectDeform.java b/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
index 669502b..783d590 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -99,7 +99,7 @@ public class VertexEffectDeform extends VertexEffect
 //        0<=C<1 looks completely ridiculous and C<0 destroys the system.
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
index ab43eb0..74f3960 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -119,7 +119,7 @@ public class VertexEffectDistort extends VertexEffect
 // a = vx*nz-vz*nx , b = vy*nz-vz*ny , c = (vx*ny-vy*nx)/(1+nz)    (unless n=(0,0,-1))
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectPinch.java b/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
index 6f44ff9..e919f9a 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -65,7 +65,7 @@ public class VertexEffectPinch extends VertexEffect
 // (where 'line' above passes through the center point and goes along the vector)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectSink.java b/src/main/java/org/distorted/library/effect/VertexEffectSink.java
index 1145d56..979f1cb 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectSink.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectSink.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -54,7 +54,7 @@ public class VertexEffectSink extends VertexEffect
 // when h>1 we are pushing points away from S: P' = P + (1/h-1)*dist(S-P)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java b/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
index 7588b50..0b83a1b 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -63,7 +63,7 @@ public class VertexEffectSwirl extends VertexEffect
 // by (1-d) around the center of the effect S.
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectWave.java b/src/main/java/org/distorted/library/effect/VertexEffectWave.java
index 05cf876..ccddcbd 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectWave.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectWave.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2017 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effect;
@@ -123,7 +123,7 @@ public class VertexEffectWave extends VertexEffect
 // Generally speaking I'd keep to amplitude < length, as the opposite case has some other problems as well.
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Have to call this before the shaders get compiled (i.e before Distorted.onCreate()) for the Effect to work.
+ * Have to call this before the shaders get compiled (i.e before DistortedLibrary.onCreate()) for the Effect to work.
  */
   public static void enable()
     {
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
index 3a4d414..140cc11 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effectqueue;
@@ -22,8 +22,8 @@ package org.distorted.library.effectqueue;
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.EffectName;
 import org.distorted.library.effect.EffectType;
-import org.distorted.library.main.Distorted;
-import org.distorted.library.main.DistortedMaster;
+import org.distorted.library.main.DistortedLibrary;
+import org.distorted.library.main.InternalMaster;
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
@@ -37,7 +37,7 @@ import java.util.HashMap;
  *
  * @y.exclude
  */
-public abstract class EffectQueue implements DistortedMaster.Slave
+public abstract class EffectQueue implements InternalMaster.Slave
   {
   static final int MAIN_VARIANTS = 3; // Number of Main program variants (ATM 3: MAIN, MAIN OIT, PREPROCESS)
 
@@ -100,17 +100,17 @@ public abstract class EffectQueue implements DistortedMaster.Slave
     mIndex              = index;
 
     mJobs.add(new Job(CREATE,numUniforms,false,null));  // create the stuff that depends on max number
-    DistortedMaster.newSlave(this);                     // of uniforms later, on first render.
+    InternalMaster.newSlave(this);                     // of uniforms later, on first render.
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags, long id)
     {
-    queues[0] = (flags & Distorted.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix(id);
-    queues[1] = (flags & Distorted.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex(id);
-    queues[2] = (flags & Distorted.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment(id);
-    queues[3] = (flags & Distorted.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess(id);
+    queues[0] = (flags & DistortedLibrary.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix(id);
+    queues[1] = (flags & DistortedLibrary.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex(id);
+    queues[2] = (flags & DistortedLibrary.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment(id);
+    queues[3] = (flags & DistortedLibrary.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess(id);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -189,7 +189,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
 
   public static boolean setMax(int index, int m)
     {
-    if( !Distorted.isInitialized() || m<=mMax[index] )
+    if( !DistortedLibrary.isInitialized() || m<=mMax[index] )
       {
       mMax[index] = m<0 ? 0:m;
       return true;
@@ -276,7 +276,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
 
     if( ret>0 )
       {
-      DistortedMaster.newSlave(this);
+      InternalMaster.newSlave(this);
       mNumEffectsToBe-=ret;
       }
 
@@ -292,7 +292,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
       if( mEffects[i].getID() == id )
         {
         mJobs.add(new Job(DETACH,0,true,mEffects[i]));
-        DistortedMaster.newSlave(this);
+        InternalMaster.newSlave(this);
         mNumEffectsToBe--;
         return 1;
         }
@@ -310,7 +310,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
       if( mEffects[i]==effect )
         {
         mJobs.add(new Job(DETACH,0,true,mEffects[i]));
-        DistortedMaster.newSlave(this);
+        InternalMaster.newSlave(this);
         mNumEffectsToBe--;
         return 1;
         }
@@ -326,7 +326,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
   public synchronized int abortAll(boolean notify)
     {
     mJobs.add(new Job(DETALL,0,notify,null));
-    DistortedMaster.newSlave(this);
+    InternalMaster.newSlave(this);
     mNumEffectsToBe = 0;
     return mNumEffects;
     }
@@ -338,7 +338,7 @@ public abstract class EffectQueue implements DistortedMaster.Slave
     if( mMax[mIndex]>mNumEffectsToBe || !mCreated )
       {
       mJobs.add(new Job(ATTACH,0,false,effect));
-      DistortedMaster.newSlave(this);
+      InternalMaster.newSlave(this);
       mNumEffectsToBe++;
       return true;
       }
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
index b112f49..ac2db3f 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effectqueue;
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
index d2c5cac..3eea9be 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effectqueue;
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
index fcd4649..64162ec 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effectqueue;
@@ -27,12 +27,12 @@ import org.distorted.library.R;
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.PostprocessEffect;
 import org.distorted.library.effect.VertexEffect;
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedFramebuffer;
 import org.distorted.library.main.DistortedNode;
-import org.distorted.library.main.DistortedOutputSurface;
-import org.distorted.library.main.DistortedRenderState;
-import org.distorted.library.main.DistortedSurface;
+import org.distorted.library.main.InternalOutputSurface;
+import org.distorted.library.main.InternalRenderState;
+import org.distorted.library.main.InternalSurface;
 import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
@@ -117,15 +117,15 @@ public class EffectQueuePostprocess extends EffectQueue
 
     int numV = VertexEffect.getNumEnabled();
 
-    String mainVertHeader= Distorted.GLSL_VERSION + ("#define NUM_VERTEX "   + ( numV>0 ? Distorted.getMax(EffectType.VERTEX  ) : 0 ) + "\n");
-    String mainFragHeader= Distorted.GLSL_VERSION + "\n";
+    String mainVertHeader= DistortedLibrary.GLSL_VERSION + ("#define NUM_VERTEX "   + ( numV>0 ? DistortedLibrary.getMax(EffectType.VERTEX  ) : 0 ) + "\n");
+    String mainFragHeader= DistortedLibrary.GLSL_VERSION + "\n";
 
     String enabledEffectV= VertexEffect.getGLSL();
 
     try
       {
       mPreProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
-                                         enabledEffectV, null, Distorted.GLSL, null);
+                                         enabledEffectV, null, DistortedLibrary.GLSL, null);
       }
     catch(Exception e)
       {
@@ -158,10 +158,10 @@ public class EffectQueuePostprocess extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int preprocess(DistortedOutputSurface buffer, DistortedNode node, float distance, float mipmap, float[] projection)
+  public int preprocess(InternalOutputSurface buffer, DistortedNode node, float distance, float mipmap, float[] projection)
     {
     buffer.setAsOutput();
-    DistortedSurface input = node.getInternalSurface();
+    InternalSurface input = node.getInternalSurface();
 
     if( input.setAsInput() )
       {
@@ -174,8 +174,8 @@ public class EffectQueuePostprocess extends EffectQueue
       int width = buffer.getWidth();
       int height = buffer.getHeight();
 
-      DistortedRenderState.setUpStencilMark(mA!=0.0f);
-      DistortedRenderState.disableBlending();
+      InternalRenderState.setUpStencilMark(mA!=0.0f);
+      InternalRenderState.disableBlending();
 
       GLES31.glViewport(0, 0, width, height );
 
@@ -206,8 +206,8 @@ public class EffectQueuePostprocess extends EffectQueue
 
       GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.getNumVertices() );
 
-      DistortedRenderState.restoreBlending();
-      DistortedRenderState.unsetUpStencilMark();
+      InternalRenderState.restoreBlending();
+      InternalRenderState.unsetUpStencilMark();
 
       return 1;
       }
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
index 7ee0d1c..5822ea2 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.effectqueue;
diff --git a/src/main/java/org/distorted/library/main/Distorted.java b/src/main/java/org/distorted/library/main/Distorted.java
deleted file mode 100644
index 961c5cc..0000000
--- a/src/main/java/org/distorted/library/main/Distorted.java
+++ /dev/null
@@ -1,871 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ConfigurationInfo;
-import android.content.res.Resources;
-import android.opengl.GLES31;
-import android.util.Log;
-
-import org.distorted.library.R;
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effectqueue.EffectQueue;
-import org.distorted.library.effectqueue.EffectQueuePostprocess;
-import org.distorted.library.effect.EffectType;
-import org.distorted.library.effect.FragmentEffect;
-import org.distorted.library.effect.PostprocessEffect;
-import org.distorted.library.effect.VertexEffect;
-import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.message.EffectMessageSender;
-import org.distorted.library.program.DistortedProgram;
-
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * A singleton class used to control various global settings.
- */
-public class Distorted 
-  {
-  public static final int GLSL = 310;
-  public static final String GLSL_VERSION= "#version 310 es\n";
-  /**
-   * When creating an instance of a DistortedTexture from another instance, clone the Bitmap that's
-   * backing up our DistortedTexture.
-   * <p>
-   * This way we can have two DistortedTextures, both backed up by the same Bitmap, to which we can
-   * apply different effects. Used in the copy constructor.
-   */
-  public static final int CLONE_SURFACE = 0x1;
-  /**
-   * When creating an instance of a DistortedEffects from another instance, clone the Matrix Effects.
-   * <p>
-   * This way we can have two different DistortedEffects sharing the MATRIX queue.
-   */
-  public static final int CLONE_MATRIX = 0x2;
-  /**
-   * When creating an instance of a DistortedEffects from another instance, clone the Vertex Effects.
-   * <p>
-   * This way we can have two different DistortedEffects sharing the VERTEX queue.
-   */
-  public static final int CLONE_VERTEX  = 0x4;
-  /**
-   * When creating an instance of a DistortedEffects from another instance, clone the Fragment Effects.
-   * <p>
-   * This way we can have two different DistortedEffects sharing the FRAGMENT queue.
-   */
-  public static final int CLONE_FRAGMENT= 0x8;
-   /**
-   * When creating an instance of a DistortedEffects from another instance, clone the PostProcess Effects.
-   * <p>
-   * This way we can have two different DistortedEffects sharing the POSTPROCESS queue.
-   */
-  public static final int CLONE_POSTPROCESS= 0x10;
-  /**
-   * When creating an instance of a DistortedNode from another instance, clone the children Nodes.
-   * <p>
-   * This is mainly useful for creating many similar sub-trees and rendering then at different places
-   * on the screen with (optionally) different Effects.
-   */
-  public static final int CLONE_CHILDREN= 0x20;
-
-  /**
-   * Work around bugs in ARM Mali driver by, instead to a single FBO, rendering to a circular queue
-   * of FBO_QUEUE_SIZE FBOs. (otherwise we sometimes get a 'full pipeline flush' and the end result
-   * might be missing part of the Objects)
-   *
-   * This bug only exists on Mali driver r12.
-   *
-   * https://community.arm.com/graphics/f/discussions/10285/opengl-es-3-1-on-mali-t880-flashes
-   */
-  static final int FBO_QUEUE_SIZE = 4;
-
-  private static boolean mInitialized=false;
-
-  //////////////////////////////////////////////////////////////////////////////////////////////
-  /// MAIN PROGRAM ///
-  private static DistortedProgram mMainProgram;
-  private static int mMainTextureH;
-
-  /// NORMAL PROGRAM /////
-  private static DistortedProgram mNormalProgram;
-  private static int mNormalMVPMatrixH;
-
-  /// MAIN OIT PROGRAM ///
-  private static DistortedProgram mMainOITProgram;
-  private static int mMainOITTextureH;
-  private static int mMainOITSizeH;
-  private static int mMainOITNumRecordsH;
-
-  /// BLIT PROGRAM ///
-  private static DistortedProgram mBlitProgram;
-  private static int mBlitTextureH;
-  private static int mBlitDepthH;
-  private static final FloatBuffer mQuadPositions;
-
-  static
-    {
-    float[] positionData= { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
-    mQuadPositions = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder()).asFloatBuffer();
-    mQuadPositions.put(positionData).position(0);
-    }
-
-  /// BLIT DEPTH PROGRAM ///
-  private static DistortedProgram mBlitDepthProgram;
-  private static int mBlitDepthTextureH;
-  private static int mBlitDepthDepthTextureH;
-  private static int mBlitDepthDepthH;
-  private static int mBlitDepthTexCorrH;
-
-  /// OIT SSBO BUFFER ///
-  private static int[] mLinkedListSSBO = new int[1];
-  private static int[] mAtomicCounter = new int[Distorted.FBO_QUEUE_SIZE];
-  private static int   mCurrBuffer;
-
-  static
-    {
-    mLinkedListSSBO[0]= -1;
-    mCurrBuffer       =  0;
-
-    for(int i=0; i<Distorted.FBO_QUEUE_SIZE; i++)  mAtomicCounter[i] = -1;
-    }
-
-  ///////////////////////////////////////////////////////////////
-  // meaning: allocate 1.0 screenful of places for transparent
-  // fragments in the SSBO backing up the OIT render method.
-  private static float mBufferSize=1.0f;
-
-  /// OIT CLEAR PROGRAM ///
-  private static DistortedProgram mOITClearProgram;
-  private static int mOITClearDepthH;
-  private static int mOITClearTexCorrH;
-  private static int mOITClearSizeH;
-
-  /// OIT BUILD PROGRAM ///
-  private static DistortedProgram mOITBuildProgram;
-  private static int mOITBuildTextureH;
-  private static int mOITBuildDepthTextureH;
-  private static int mOITBuildDepthH;
-  private static int mOITBuildTexCorrH;
-  private static int mOITBuildSizeH;
-  private static int mOITBuildNumRecordsH;
-
-  /// OIT COLLAPSE PROGRAM ///
-  private static DistortedProgram mOITCollapseProgram;
-  private static int mOITCollapseDepthTextureH;
-  private static int mOITCollapseDepthH;
-  private static int mOITCollapseTexCorrH;
-  private static int mOITCollapseSizeH;
-
-  /// OIT RENDER PROGRAM ///
-  private static DistortedProgram mOITRenderProgram;
-  private static int mOITRenderDepthH;
-  private static int mOITRenderTexCorrH;
-  private static int mOITRenderSizeH;
-
-  /// END PROGRAMS //////
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// private: hide this from Javadoc
-
-  private Distorted()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createPrograms(Resources resources)
-    {
-    // MAIN PROGRAM ////////////////////////////////////
-    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
-    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
-
-    int numF = FragmentEffect.getNumEnabled();
-    int numV = VertexEffect.getNumEnabled();
-
-    String mainVertHeader= Distorted.GLSL_VERSION + ("#define NUM_VERTEX "   + ( numV>0 ? getMax(EffectType.VERTEX  ) : 0 ) + "\n");
-    String mainFragHeader= Distorted.GLSL_VERSION + ("#define NUM_FRAGMENT " + ( numF>0 ? getMax(EffectType.FRAGMENT) : 0 ) + "\n");
-    String enabledEffectV= VertexEffect.getGLSL();
-    String enabledEffectF= FragmentEffect.getGLSL();
-
-    String[] feedback = { "v_Position", "v_endPosition" };
-
-    try
-      {
-      mMainProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
-                                          enabledEffectV, enabledEffectF, Distorted.GLSL, feedback);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile MAIN program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int mainProgramH = mMainProgram.getProgramHandle();
-    EffectQueue.getUniforms(mainProgramH,0);
-    mMainTextureH= GLES31.glGetUniformLocation( mainProgramH, "u_Texture");
-
-    // BLIT PROGRAM ////////////////////////////////////
-    final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
-    final InputStream blitFragStream = resources.openRawResource(R.raw.blit_fragment_shader);
-
-    try
-      {
-      mBlitProgram = new DistortedProgram(blitVertStream,blitFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int blitProgramH = mBlitProgram.getProgramHandle();
-    mBlitTextureH  = GLES31.glGetUniformLocation( blitProgramH, "u_Texture");
-    mBlitDepthH    = GLES31.glGetUniformLocation( blitProgramH, "u_Depth");
-
-    // BLIT DEPTH PROGRAM ////////////////////////////////////
-    final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
-    final InputStream blitDepthFragStream = resources.openRawResource(R.raw.blit_depth_fragment_shader);
-
-    try
-      {
-      mBlitDepthProgram = new DistortedProgram(blitDepthVertStream,blitDepthFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT DEPTH program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
-    mBlitDepthTextureH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Texture");
-    mBlitDepthDepthTextureH = GLES31.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
-    mBlitDepthDepthH        = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Depth");
-    mBlitDepthTexCorrH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_TexCorr");
-
-    // NORMAL PROGRAM //////////////////////////////////////
-    final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
-    final InputStream normalFragmentStream = resources.openRawResource(R.raw.normal_fragment_shader);
-
-    try
-      {
-      mNormalProgram = new DistortedProgram(normalVertexStream,normalFragmentStream, Distorted.GLSL_VERSION, Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile NORMAL program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int normalProgramH = mNormalProgram.getProgramHandle();
-    mNormalMVPMatrixH  = GLES31.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createProgramsOIT(Resources resources)
-    {
-    // MAIN OIT PROGRAM ////////////////////////////////
-    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
-    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
-
-    int numF = FragmentEffect.getNumEnabled();
-    int numV = VertexEffect.getNumEnabled();
-
-    String mainVertHeader= Distorted.GLSL_VERSION +
-                           ("#define NUM_VERTEX "   + ( numV>0 ? getMax(EffectType.VERTEX  ) : 0 ) + "\n") +
-                           ("#define OIT\n");
-    String mainFragHeader= Distorted.GLSL_VERSION +
-                           ("#define NUM_FRAGMENT " + ( numF>0 ? getMax(EffectType.FRAGMENT) : 0 ) + "\n") +
-                           ("#define OIT\n");
-
-    String enabledEffectV= VertexEffect.getGLSL();
-    String enabledEffectF= FragmentEffect.getGLSL();
-
-    try
-      {
-      mMainOITProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
-                                             enabledEffectV, enabledEffectF, Distorted.GLSL, null);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile MAIN OIT program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int mainOITProgramH = mMainOITProgram.getProgramHandle();
-    EffectQueue.getUniforms(mainOITProgramH,1);
-    mMainOITTextureH    = GLES31.glGetUniformLocation( mainOITProgramH, "u_Texture");
-    mMainOITSizeH       = GLES31.glGetUniformLocation( mainOITProgramH, "u_Size");
-    mMainOITNumRecordsH = GLES31.glGetUniformLocation( mainOITProgramH, "u_numRecords");
-
-    // OIT CLEAR PROGRAM ////////////////////////////////////
-    final InputStream oitClearVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
-    final InputStream oitClearFragStream = resources.openRawResource(R.raw.oit_clear_fragment_shader);
-
-    try
-      {
-      mOITClearProgram = new DistortedProgram(oitClearVertStream,oitClearFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT CLEAR program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int oitClearProgramH   = mOITClearProgram.getProgramHandle();
-    mOITClearDepthH        = GLES31.glGetUniformLocation( oitClearProgramH, "u_Depth");
-    mOITClearTexCorrH      = GLES31.glGetUniformLocation( oitClearProgramH, "u_TexCorr");
-    mOITClearSizeH         = GLES31.glGetUniformLocation( oitClearProgramH, "u_Size");
-
-    // OIT BUILD PROGRAM ////////////////////////////////////
-    final InputStream oitBuildVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
-    final InputStream oitBuildFragStream = resources.openRawResource(R.raw.oit_build_fragment_shader);
-
-    try
-      {
-      mOITBuildProgram = new DistortedProgram(oitBuildVertStream,oitBuildFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT BUILD program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int oitBuildProgramH   = mOITBuildProgram.getProgramHandle();
-    mOITBuildTextureH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Texture");
-    mOITBuildDepthTextureH = GLES31.glGetUniformLocation( oitBuildProgramH, "u_DepthTexture");
-    mOITBuildDepthH        = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Depth");
-    mOITBuildTexCorrH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_TexCorr");
-    mOITBuildSizeH         = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Size");
-    mOITBuildNumRecordsH   = GLES31.glGetUniformLocation( oitBuildProgramH, "u_numRecords");
-
-    // OIT COLLAPSE PROGRAM ///////////////////////////
-    final InputStream oitCollapseVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
-    final InputStream oitCollapseFragStream = resources.openRawResource(R.raw.oit_collapse_fragment_shader);
-
-    try
-      {
-      mOITCollapseProgram = new DistortedProgram(oitCollapseVertStream,oitCollapseFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT COLLAPSE program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int oitCollapseProgramH   = mOITCollapseProgram.getProgramHandle();
-    mOITCollapseDepthTextureH = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_DepthTexture");
-    mOITCollapseDepthH        = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Depth");
-    mOITCollapseTexCorrH      = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_TexCorr");
-    mOITCollapseSizeH         = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Size");
-
-    // OIT RENDER PROGRAM ///////////////////////////
-    final InputStream oitRenderVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
-    final InputStream oitRenderFragStream = resources.openRawResource(R.raw.oit_render_fragment_shader);
-
-    try
-      {
-      mOITRenderProgram = new DistortedProgram(oitRenderVertStream,oitRenderFragStream,Distorted.GLSL_VERSION,Distorted.GLSL_VERSION, Distorted.GLSL);
-      }
-    catch(Exception e)
-      {
-      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT RENDER program: "+e.getMessage());
-      throw new RuntimeException(e.getMessage());
-      }
-
-    int oitRenderProgramH   = mOITRenderProgram.getProgramHandle();
-    mOITRenderDepthH        = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Depth");
-    mOITRenderTexCorrH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_TexCorr");
-    mOITRenderSizeH         = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Size");
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void displayNormals(EffectQueue[] queues, MeshBase mesh)
-    {
-    int num = mesh.getNumVertices();
-    int tfo = mesh.getTFO();
-
-    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfo );
-    GLES31.glBeginTransformFeedback( GLES31.GL_POINTS);
-    DistortedRenderState.switchOffDrawing();
-    GLES31.glDrawArrays( GLES31.GL_POINTS, 0, num );
-    DistortedRenderState.restoreDrawing();
-    GLES31.glEndTransformFeedback();
-    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
-
-    Distorted.mNormalProgram.useProgram();
-    GLES31.glUniformMatrix4fv(Distorted.mNormalMVPMatrixH, 1, false, EffectQueue.getMVP(queues) , 0);
-    mesh.bindTransformAttribs(Distorted.mNormalProgram);
-    GLES31.glLineWidth(8.0f);
-    GLES31.glDrawArrays(GLES31.GL_LINES, 0, 2*num);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void drawPrivOIT(EffectQueue[] queues, float halfW, float halfH, MeshBase mesh, DistortedOutputSurface surface, long currTime)
-    {
-    float halfZ = halfW*mesh.getZFactor();
-
-    EffectQueue.compute(queues, currTime, halfW, halfH, halfZ );
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-
-    Distorted.mMainOITProgram.useProgram();
-    GLES31.glUniform1i(Distorted.mMainOITTextureH, 0);
-    GLES31.glUniform2ui(Distorted.mMainOITSizeH, surface.mWidth, surface.mHeight);
-    GLES31.glUniform1ui(Distorted.mMainOITNumRecordsH, (int)(Distorted.mBufferSize*surface.mWidth*surface.mHeight) );
-
-    mesh.bindVertexAttribs(Distorted.mMainOITProgram);
-
-    float inflate     = mesh.getInflate();
-    int width         = surface.mWidth;
-    int height        = surface.mHeight;
-    float distance    = surface.mDistance;
-    float mipmap      = surface.mMipmap;
-    float[] projection= surface.mProjectionMatrix;
-
-    EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 1 );
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.getNumVertices() );
-
-    if( mesh.getShowNormals() )
-      {
-      Distorted.mMainProgram.useProgram();
-      EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 0 );
-      displayNormals(queues,mesh);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void drawPriv(EffectQueue[] queues, float halfW, float halfH, MeshBase mesh, DistortedOutputSurface surface, long currTime)
-    {
-    float halfZ = halfW*mesh.getZFactor();
-
-    EffectQueue.compute(queues, currTime, halfW, halfH, halfZ );
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    Distorted.mMainProgram.useProgram();
-    GLES31.glUniform1i(Distorted.mMainTextureH, 0);
-    mesh.bindVertexAttribs(Distorted.mMainProgram);
-
-    float inflate     = mesh.getInflate();
-    int width         = surface.mWidth;
-    int height        = surface.mHeight;
-    float distance    = surface.mDistance;
-    float mipmap      = surface.mMipmap;
-    float[] projection= surface.mProjectionMatrix;
-
-    EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 0 );
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.getNumVertices() );
-
-    if( mesh.getShowNormals() ) displayNormals(queues,mesh);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void blitPriv(DistortedOutputSurface surface)
-    {
-    mBlitProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform1i(mBlitTextureH, 0);
-    GLES31.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
-    GLES31.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void blitDepthPriv(DistortedOutputSurface surface, float corrW, float corrH)
-    {
-    mBlitDepthProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform1i(mBlitDepthTextureH, 0);
-    GLES31.glUniform1i(mBlitDepthDepthTextureH, 1);
-    GLES31.glUniform2f(mBlitDepthTexCorrH, corrW, corrH );
-    GLES31.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
-    GLES31.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static int printPreviousBuffer()
-    {
-    int counter = 0;
-
-    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
-                                                                GLES31.GL_MAP_READ_BIT);
-    if( atomicBuf!=null )
-      {
-      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
-      counter = atomicIntBuf.get(0);
-      }
-    else
-      {
-      android.util.Log.e("effects", "print: failed to map atomic buffer");
-      }
-
-    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
-
-    return counter;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void zeroBuffer()
-    {
-    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
-        GLES31.GL_MAP_WRITE_BIT|GLES31.GL_MAP_INVALIDATE_BUFFER_BIT);
-    if( atomicBuf!=null )
-      {
-      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
-      atomicIntBuf.put(0,0);
-      }
-    else
-      {
-      android.util.Log.e("effects", "zero: failed to map atomic buffer");
-      }
-
-    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// reset atomic counter to 0
-
-  static int zeroOutAtomic()
-    {
-    int counter = 0;
-
-    if( mAtomicCounter[0]<0 )
-      {
-      GLES31.glGenBuffers(Distorted.FBO_QUEUE_SIZE,mAtomicCounter,0);
-
-      for(int i=0; i<Distorted.FBO_QUEUE_SIZE; i++)
-        {
-        GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[i]);
-        GLES31.glBufferData(GLES31.GL_ATOMIC_COUNTER_BUFFER, 4, null, GLES31.GL_DYNAMIC_DRAW);
-        zeroBuffer();
-        }
-      }
-
-    // reading the value of the buffer on every frame would slow down rendering by
-    // about 3%; doing it only once every 5 frames affects speed by less than 1%.
-    if( mCurrBuffer==0 )
-      {
-      GLES31.glBindBufferBase(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, mAtomicCounter[mCurrBuffer]);
-      counter = printPreviousBuffer();
-      }
-
-    if( ++mCurrBuffer>=Distorted.FBO_QUEUE_SIZE ) mCurrBuffer = 0;
-
-    GLES31.glBindBufferBase(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, mAtomicCounter[mCurrBuffer]);
-    zeroBuffer();
-
-    return counter;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Pass1 of the OIT algorithm. Clear per-pixel head-pointers.
-
-  static void oitClear(DistortedOutputSurface surface, int counter)
-    {
-    if( mLinkedListSSBO[0]<0 )
-      {
-      GLES31.glGenBuffers(1,mLinkedListSSBO,0);
-
-      int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
-      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
-      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES31.GL_DYNAMIC_READ|GLES31.GL_DYNAMIC_DRAW);
-      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
-
-      GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, 1, mLinkedListSSBO[0]);
-      }
-
-    // See if we have overflown the SSBO in one of the previous frames.
-    // If yes, assume we need to make the SSBO larger.
-    float overflow = counter/(mBufferSize*surface.mWidth*surface.mHeight);
-
-    if( overflow>1.0f )
-      {
-      //android.util.Log.e("effects", "previous frame rendered "+counter+
-      //                   " fragments, but there was only "+(mBufferSize*surface.mWidth*surface.mHeight)+" space");
-
-      mBufferSize *= (int)(overflow+1.0f);
-      int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
-      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
-      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES31.GL_DYNAMIC_READ|GLES31.GL_DYNAMIC_DRAW);
-      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
-      }
-
-    mOITClearProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform2f(mOITClearTexCorrH, 1.0f, 1.0f );   // corrections do not really matter here - only present because of common vertex shader.
-    GLES31.glUniform1f( mOITClearDepthH , 1.0f);          // likewise depth
-    GLES31.glUniform2ui(mOITClearSizeH, surface.mWidth, surface.mHeight);
-    GLES31.glVertexAttribPointer(mOITClearProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Pass2 of the OIT algorithm - build per-pixel linked lists.
-
-  static void oitBuild(DistortedOutputSurface surface, float corrW, float corrH)
-    {
-    mOITBuildProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform1i(mOITBuildTextureH, 0);
-    GLES31.glUniform1i(mOITBuildDepthTextureH, 1);
-    GLES31.glUniform2f(mOITBuildTexCorrH, corrW, corrH );
-    GLES31.glUniform2ui(mOITBuildSizeH, surface.mWidth, surface.mHeight);
-    GLES31.glUniform1ui(mOITBuildNumRecordsH, (int)(mBufferSize*surface.mWidth*surface.mHeight) );
-    GLES31.glUniform1f(mOITBuildDepthH , 1.0f-surface.mNear);
-    GLES31.glVertexAttribPointer(mOITBuildProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Pass3 of the OIT algorithm. Cut occluded parts of the linked list.
-
-  static void oitCollapse(DistortedOutputSurface surface, float corrW, float corrH)
-    {
-    mOITCollapseProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform1i(mOITCollapseDepthTextureH, 1);
-    GLES31.glUniform2f(mOITCollapseTexCorrH, corrW, corrH );
-    GLES31.glUniform2ui(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
-    GLES31.glUniform1f( mOITCollapseDepthH , 1.0f-surface.mNear);
-    GLES31.glVertexAttribPointer(mOITCollapseProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Pass4 of the OIT algorithm. Render all the transparent pixels from the per-pixel linked lists.
-
-  static void oitRender(DistortedOutputSurface surface, float corrW, float corrH)
-    {
-    mOITRenderProgram.useProgram();
-
-    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES31.glUniform2f(mOITRenderTexCorrH, corrW, corrH );
-    GLES31.glUniform2ui(mOITRenderSizeH, surface.mWidth, surface.mHeight);
-    GLES31.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
-    GLES31.glVertexAttribPointer(mOITRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
-    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void setSSBOSize(float size)
-    {
-    mBufferSize = size;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// ARM Mali driver r12 has problems when we keep swapping many FBOs (fixed in r22)
-// PowerVR GE8100 compiler fails to compile OIT programs.
-
-  private static void detectBuggyDrivers()
-    {
-    String vendor  = GLES31.glGetString(GLES31.GL_VENDOR);
-    String version = GLES31.glGetString(GLES31.GL_VERSION);
-    String renderer= GLES31.glGetString(GLES31.GL_RENDERER);
-
-    /*
-    android.util.Log.e("DISTORTED", "GLSL Version "+GLES31.glGetString(GLES31.GL_SHADING_LANGUAGE_VERSION));
-    android.util.Log.e("DISTORTED", "GL Version "  +GLES31.glGetString(GLES31.GL_VERSION));
-    android.util.Log.e("DISTORTED", "GL Vendor "   +GLES31.glGetString(GLES31.GL_VENDOR));
-    android.util.Log.e("DISTORTED", "GL Renderer " +GLES31.glGetString(GLES31.GL_RENDERER));
-    */
-
-    if( vendor.contains("ARM") )
-      {
-      if( version.contains("r12") )
-        {
-        android.util.Log.e("DISTORTED", "You are running this on a ARM Mali driver r12.\nThis is a buggy driver, please update to r22. Problems with flashing expected.");
-        }
-      }
-    else if( vendor.contains("Imagination") )
-      {
-      if( renderer.contains("GE8") )
-        {
-        android.util.Log.e("DISTORTED", "You are running this on a PowerVR GE8XXX.\nDue to a buggy compiler OIT rendering will not work");
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Have we called onCreate yet, ie have we initialized the library?
- * @return <code>true</code> if the library is initialized and ready for action.
- */
-  public static boolean isInitialized()
-    {
-    return mInitialized;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * When OpenGL context gets created, call this method so that the library can initialise its internal data structures.
- * I.e. best called from GLSurfaceView.onCreate().
- * <p>
- * Needs to be called from a thread holding the OpenGL context.
- *   
- * @param context Context of the App using the library - used to open up Resources and read Shader code.
- */
-  public static void onCreate(final Context context) throws Exception
-    {
-    final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
-    android.util.Log.e("DISTORTED", "Using OpenGL ES "+configurationInfo.getGlEsVersion());
-
-    mInitialized = true;
-
-    detectBuggyDrivers();
-
-    EffectMessageSender.startSending();
-
-    final Resources resources = context.getResources();
-
-    Exception exception=null;
-
-    try
-      {
-      createPrograms(resources);
-      }
-    catch(Exception ex)
-      {
-      exception = ex;
-      }
-
-    try
-      {
-      createProgramsOIT(resources);
-      }
-    catch(Exception ex)
-      {
-      exception = ex;
-      }
-
-    try
-      {
-      EffectQueuePostprocess.createPrograms(resources);
-      }
-    catch(Exception ex)
-      {
-      exception = ex;
-      }
-
-    try
-      {
-      PostprocessEffect.createPrograms();
-      }
-    catch(Exception ex)
-      {
-      exception = ex;
-      }
-
-    if( exception!=null)
-      {
-      throw exception;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Call this so that the Library can release the OpenGL related data that needs to be recreated.
- * Must be called from Activity.onPause().
- */
-  public static void onPause()
-    {
-    DistortedObject.onPause();
-
-    mLinkedListSSBO[0]= -1;
-
-    for(int i=0; i<Distorted.FBO_QUEUE_SIZE; i++) mAtomicCounter[i] = -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Call this so that the Library can release its internal data structures.
- * Must be called from Activity.onDestroy(). 
- */
-  public static void onDestroy()
-    {
-    DistortedObject.onDestroy();
-    DistortedNodeData.onDestroy();
-    DistortedEffects.onDestroy();
-    DistortedMaster.onDestroy();
-    DistortedOutputSurface.onDestroy();
-    EffectQueue.onDestroy();
-    Effect.onDestroy();
-    EffectMessageSender.stopSending();
-
-    mInitialized = false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Returns the maximum number of effects of a given type that can be simultaneously applied to a
- * single (InputSurface,MeshBase) combo.
- *
- * @param type {@link EffectType}
- * @return The maximum number of effects of a given type.
- */
-  @SuppressWarnings("unused")
-  public static int getMax(EffectType type)
-    {
-    return EffectQueue.getMax(type.ordinal());
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Sets the maximum number of effects that can be stored in a single EffectQueue at one time.
- * This can fail if:
- * <ul>
- * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
- * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
- *     before the Vertex Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
- *     time only decreasing the value of 'max' is permitted.
- * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
- * </ul>
- *
- * @param type {@link EffectType}
- * @param max new maximum number of simultaneous effects. Has to be a non-negative number not greater
- *            than Byte.MAX_VALUE
- * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
- */
-  @SuppressWarnings("unused")
-  public static boolean setMax(EffectType type, int max)
-    {
-    return EffectQueue.setMax(type.ordinal(),max);
-    }
-  }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/main/DistortedBuffer.java b/src/main/java/org/distorted/library/main/DistortedBuffer.java
deleted file mode 100644
index b1e7896..0000000
--- a/src/main/java/org/distorted/library/main/DistortedBuffer.java
+++ /dev/null
@@ -1,108 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2018 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import android.opengl.GLES31;
-import java.nio.Buffer;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER.
- * Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context.
- * <p>
- * Not part of public API, do not document (public only because has to be used in Meshes)
- *
- * @y.exclude
- */
-public class DistortedBuffer extends DistortedObject
-  {
-  public int[] mIndex;
-
-  private int mTarget, mSize, mUsage;
-  private Buffer mBuffer;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public DistortedBuffer(int target, int usage)
-    {
-    super(DistortedObject.TYPE_USER);
-
-    mIndex  = new int[1];
-    mTarget = target;
-    mUsage  = usage;
-    mBuffer = null;
-    mSize   = 0;
-
-    recreate();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// mark for creation only now, when we do have all data ready, in order to avoid the situation
-// when create() would be called before this.
-
-  public void setData(int size, Buffer buffer)
-    {
-    mSize   = size;
-    mBuffer = buffer;
-
-    markForCreation();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
-
-  void create()
-    {
-    if( mIndex[0]<0 )
-      {
-      GLES31.glGenBuffers( 1, mIndex, 0);
-      GLES31.glBindBuffer( mTarget, mIndex[0]);
-      GLES31.glBufferData( mTarget, mSize, mBuffer, mUsage);
-      GLES31.glBindBuffer( mTarget, 0);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
-
-  void delete()
-    {
-    if( mIndex[0]>=0 )
-      {
-      GLES31.glDeleteBuffers(1, mIndex, 0);
-      mIndex[0] = -1;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void recreate()
-    {
-    mIndex[0] = -1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// debugging only
-
-  String printDetails()
-    {
-    return getClass().getSimpleName();
-    }
-  }
diff --git a/src/main/java/org/distorted/library/main/DistortedChildrenList.java b/src/main/java/org/distorted/library/main/DistortedChildrenList.java
deleted file mode 100644
index 2248aed..0000000
--- a/src/main/java/org/distorted/library/main/DistortedChildrenList.java
+++ /dev/null
@@ -1,258 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-package org.distorted.library.main;
-
-import org.distorted.library.mesh.MeshBase;
-
-import java.util.ArrayList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class DistortedChildrenList implements DistortedMaster.Slave
-  {
-  private static final int ATTACH = 0;
-  private static final int DETACH = 1;
-  private static final int DETALL = 2;
-  private static final int SORT   = 3;
-
-  private class Job
-    {
-    int type;
-    DistortedNode node;
-
-    Job(int t, DistortedNode n)
-      {
-      type = t;
-      node = n;
-      }
-    }
-
-  private ArrayList<Job> mJobs;
-  private ArrayList<DistortedNode> mChildren;
-  private DistortedChildrenList.Parent mParent;
-  private int mNumChildren;
-
-  public interface Parent
-    {
-    void adjustIsomorphism();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedChildrenList(DistortedChildrenList.Parent parent)
-    {
-    mParent = parent;
-    mJobs = new ArrayList<>();
-    mChildren = null;
-    mNumChildren = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  int getNumChildren()
-    {
-    return mNumChildren;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedNode getChild(int index)
-    {
-    return mChildren.get(index);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void rearrangeByBuckets(int index,long bucket)
-    {
-    DistortedNode child = mChildren.remove(index);
-    int i;
-
-    for(i=0; i<index; i++)
-      {
-      if( mChildren.get(i).getBucket() > bucket ) break;
-      }
-
-    mChildren.add(i,child);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Can make this logarithmic but the typical number of children is very small anyway.
-//
-// We want to keep same buckets next to each other, while avoiding changes in order of the children
-// (if possible!) We want to keep bucket=0 (i.e. the non-postprocessed children) at the beginning.
-
-  private void addSortingByBuckets(DistortedNode newChild)
-    {
-    int i;
-    long bucket = newChild.getBucket();
-    boolean sameBucket = false;
-
-    for(i=0; i<mNumChildren; i++)
-      {
-      if( mChildren.get(i).getBucket() == bucket )
-        {
-        sameBucket=true;
-        }
-      else if( sameBucket || bucket==0 )
-        {
-        break;
-        }
-      }
-
-    mChildren.add(i,newChild);
-    mNumChildren++;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void attach(DistortedNode node)
-    {
-    mJobs.add(new Job(ATTACH,node));
-    DistortedMaster.newSlave(this);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
-    {
-    DistortedNode node = new DistortedNode(surface,effects,mesh);
-    mJobs.add(new Job(ATTACH,node));
-    DistortedMaster.newSlave(this);
-    return node;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void detach(DistortedNode node)
-    {
-    mJobs.add(new Job(DETACH,node));
-    DistortedMaster.newSlave(this);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void detach(DistortedEffects effects)
-    {
-    long id = effects.getID();
-    DistortedNode node;
-    boolean detached = false;
-
-    for(int i=0; i<mNumChildren; i++)
-      {
-      node = mChildren.get(i);
-
-      if( node.getEffects().getID()==id )
-        {
-        detached = true;
-        mJobs.add(new Job(DETACH,node));
-        DistortedMaster.newSlave(this);
-        break;
-        }
-      }
-
-    if( !detached )
-      {
-      // if we failed to detach any, it still might be the case that
-      // there's an ATTACH job that we need to cancel.
-      int num = mJobs.size();
-      Job job;
-
-      for(int i=0; i<num; i++)
-        {
-        job = mJobs.get(i);
-
-        if( job.type==ATTACH && job.node.getEffects()==effects )
-          {
-          mJobs.remove(i);
-          break;
-          }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void detachAll()
-    {
-    mJobs.add(new Job(DETALL,null));
-    DistortedMaster.newSlave(this);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * This is not really part of the public API. Has to be public only because it is a part of the
- * DistortedSlave interface, which should really be a class that we extend here instead but
- * Java has no multiple inheritance.
- *
- * @y.exclude
- */
-  public void doWork()
-    {
-    int num = mJobs.size();
-
-    if( num>0 )
-      {
-      Job job;
-      int numChanges=0;
-
-      for(int i=0; i<num; i++)
-        {
-        job = mJobs.remove(0);
-
-        switch(job.type)
-          {
-          case ATTACH: numChanges++;
-                       if( mChildren==null ) mChildren = new ArrayList<>(2);
-                       job.node.setParent(mParent);
-                       addSortingByBuckets(job.node);
-                       break;
-          case DETACH: numChanges++;
-                       if( mNumChildren>0 && mChildren.remove(job.node) )
-                         {
-                         job.node.setParent(null);
-                         mNumChildren--;
-                         }
-                       break;
-          case DETALL: numChanges++;
-                       if( mNumChildren>0 )
-                         {
-                         DistortedNode tmp;
-
-                         for(int j=mNumChildren-1; j>=0; j--)
-                           {
-                           tmp = mChildren.remove(j);
-                           tmp.setParent(null);
-                           }
-
-                         mNumChildren = 0;
-                         }
-                       break;
-          case SORT  : mChildren.remove(job.node);
-                       addSortingByBuckets(job.node);
-                       break;
-          }
-        }
-      if( numChanges>0 ) mParent.adjustIsomorphism();
-      }
-    }
-  }
-
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index e117bd3..e64ae65 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.main;
diff --git a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
index b9a8281..a659593 100644
--- a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.main;
@@ -28,7 +28,7 @@ import android.opengl.GLES31;
  * User is able to create offscreen FBOs and both a) render to them b) use their COLOR0 attachment as
  * an input texture. Attaching Depths and/or Stencils is also possible.
  */
-public class DistortedFramebuffer extends DistortedOutputSurface
+public class DistortedFramebuffer extends InternalOutputSurface
   {
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/DistortedLibrary.java b/src/main/java/org/distorted/library/main/DistortedLibrary.java
new file mode 100644
index 0000000..e757c3c
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/DistortedLibrary.java
@@ -0,0 +1,871 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.content.res.Resources;
+import android.opengl.GLES31;
+import android.util.Log;
+
+import org.distorted.library.R;
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effectqueue.EffectQueue;
+import org.distorted.library.effectqueue.EffectQueuePostprocess;
+import org.distorted.library.effect.EffectType;
+import org.distorted.library.effect.FragmentEffect;
+import org.distorted.library.effect.PostprocessEffect;
+import org.distorted.library.effect.VertexEffect;
+import org.distorted.library.mesh.MeshBase;
+import org.distorted.library.message.EffectMessageSender;
+import org.distorted.library.program.DistortedProgram;
+
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * A singleton class used to control various global settings.
+ */
+public class DistortedLibrary
+  {
+  public static final int GLSL = 310;
+  public static final String GLSL_VERSION= "#version 310 es\n";
+  /**
+   * When creating an instance of a DistortedTexture from another instance, clone the Bitmap that's
+   * backing up our DistortedTexture.
+   * <p>
+   * This way we can have two DistortedTextures, both backed up by the same Bitmap, to which we can
+   * apply different effects. Used in the copy constructor.
+   */
+  public static final int CLONE_SURFACE = 0x1;
+  /**
+   * When creating an instance of a DistortedEffects from another instance, clone the Matrix Effects.
+   * <p>
+   * This way we can have two different DistortedEffects sharing the MATRIX queue.
+   */
+  public static final int CLONE_MATRIX = 0x2;
+  /**
+   * When creating an instance of a DistortedEffects from another instance, clone the Vertex Effects.
+   * <p>
+   * This way we can have two different DistortedEffects sharing the VERTEX queue.
+   */
+  public static final int CLONE_VERTEX  = 0x4;
+  /**
+   * When creating an instance of a DistortedEffects from another instance, clone the Fragment Effects.
+   * <p>
+   * This way we can have two different DistortedEffects sharing the FRAGMENT queue.
+   */
+  public static final int CLONE_FRAGMENT= 0x8;
+   /**
+   * When creating an instance of a DistortedEffects from another instance, clone the PostProcess Effects.
+   * <p>
+   * This way we can have two different DistortedEffects sharing the POSTPROCESS queue.
+   */
+  public static final int CLONE_POSTPROCESS= 0x10;
+  /**
+   * When creating an instance of a DistortedNode from another instance, clone the children Nodes.
+   * <p>
+   * This is mainly useful for creating many similar sub-trees and rendering then at different places
+   * on the screen with (optionally) different Effects.
+   */
+  public static final int CLONE_CHILDREN= 0x20;
+
+  /**
+   * Work around bugs in ARM Mali driver by, instead to a single FBO, rendering to a circular queue
+   * of FBO_QUEUE_SIZE FBOs. (otherwise we sometimes get a 'full pipeline flush' and the end result
+   * might be missing part of the Objects)
+   *
+   * This bug only exists on Mali driver r12.
+   *
+   * https://community.arm.com/graphics/f/discussions/10285/opengl-es-3-1-on-mali-t880-flashes
+   */
+  static final int FBO_QUEUE_SIZE = 4;
+
+  private static boolean mInitialized=false;
+
+  //////////////////////////////////////////////////////////////////////////////////////////////
+  /// MAIN PROGRAM ///
+  private static DistortedProgram mMainProgram;
+  private static int mMainTextureH;
+
+  /// NORMAL PROGRAM /////
+  private static DistortedProgram mNormalProgram;
+  private static int mNormalMVPMatrixH;
+
+  /// MAIN OIT PROGRAM ///
+  private static DistortedProgram mMainOITProgram;
+  private static int mMainOITTextureH;
+  private static int mMainOITSizeH;
+  private static int mMainOITNumRecordsH;
+
+  /// BLIT PROGRAM ///
+  private static DistortedProgram mBlitProgram;
+  private static int mBlitTextureH;
+  private static int mBlitDepthH;
+  private static final FloatBuffer mQuadPositions;
+
+  static
+    {
+    float[] positionData= { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
+    mQuadPositions = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder()).asFloatBuffer();
+    mQuadPositions.put(positionData).position(0);
+    }
+
+  /// BLIT DEPTH PROGRAM ///
+  private static DistortedProgram mBlitDepthProgram;
+  private static int mBlitDepthTextureH;
+  private static int mBlitDepthDepthTextureH;
+  private static int mBlitDepthDepthH;
+  private static int mBlitDepthTexCorrH;
+
+  /// OIT SSBO BUFFER ///
+  private static int[] mLinkedListSSBO = new int[1];
+  private static int[] mAtomicCounter = new int[DistortedLibrary.FBO_QUEUE_SIZE];
+  private static int   mCurrBuffer;
+
+  static
+    {
+    mLinkedListSSBO[0]= -1;
+    mCurrBuffer       =  0;
+
+    for(int i = 0; i< DistortedLibrary.FBO_QUEUE_SIZE; i++)  mAtomicCounter[i] = -1;
+    }
+
+  ///////////////////////////////////////////////////////////////
+  // meaning: allocate 1.0 screenful of places for transparent
+  // fragments in the SSBO backing up the OIT render method.
+  private static float mBufferSize=1.0f;
+
+  /// OIT CLEAR PROGRAM ///
+  private static DistortedProgram mOITClearProgram;
+  private static int mOITClearDepthH;
+  private static int mOITClearTexCorrH;
+  private static int mOITClearSizeH;
+
+  /// OIT BUILD PROGRAM ///
+  private static DistortedProgram mOITBuildProgram;
+  private static int mOITBuildTextureH;
+  private static int mOITBuildDepthTextureH;
+  private static int mOITBuildDepthH;
+  private static int mOITBuildTexCorrH;
+  private static int mOITBuildSizeH;
+  private static int mOITBuildNumRecordsH;
+
+  /// OIT COLLAPSE PROGRAM ///
+  private static DistortedProgram mOITCollapseProgram;
+  private static int mOITCollapseDepthTextureH;
+  private static int mOITCollapseDepthH;
+  private static int mOITCollapseTexCorrH;
+  private static int mOITCollapseSizeH;
+
+  /// OIT RENDER PROGRAM ///
+  private static DistortedProgram mOITRenderProgram;
+  private static int mOITRenderDepthH;
+  private static int mOITRenderTexCorrH;
+  private static int mOITRenderSizeH;
+
+  /// END PROGRAMS //////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// private: hide this from Javadoc
+
+  private DistortedLibrary()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createPrograms(Resources resources)
+    {
+    // MAIN PROGRAM ////////////////////////////////////
+    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
+    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
+
+    int numF = FragmentEffect.getNumEnabled();
+    int numV = VertexEffect.getNumEnabled();
+
+    String mainVertHeader= DistortedLibrary.GLSL_VERSION + ("#define NUM_VERTEX "   + ( numV>0 ? getMax(EffectType.VERTEX  ) : 0 ) + "\n");
+    String mainFragHeader= DistortedLibrary.GLSL_VERSION + ("#define NUM_FRAGMENT " + ( numF>0 ? getMax(EffectType.FRAGMENT) : 0 ) + "\n");
+    String enabledEffectV= VertexEffect.getGLSL();
+    String enabledEffectF= FragmentEffect.getGLSL();
+
+    String[] feedback = { "v_Position", "v_endPosition" };
+
+    try
+      {
+      mMainProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
+                                          enabledEffectV, enabledEffectF, DistortedLibrary.GLSL, feedback);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile MAIN program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int mainProgramH = mMainProgram.getProgramHandle();
+    EffectQueue.getUniforms(mainProgramH,0);
+    mMainTextureH= GLES31.glGetUniformLocation( mainProgramH, "u_Texture");
+
+    // BLIT PROGRAM ////////////////////////////////////
+    final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
+    final InputStream blitFragStream = resources.openRawResource(R.raw.blit_fragment_shader);
+
+    try
+      {
+      mBlitProgram = new DistortedProgram(blitVertStream,blitFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int blitProgramH = mBlitProgram.getProgramHandle();
+    mBlitTextureH  = GLES31.glGetUniformLocation( blitProgramH, "u_Texture");
+    mBlitDepthH    = GLES31.glGetUniformLocation( blitProgramH, "u_Depth");
+
+    // BLIT DEPTH PROGRAM ////////////////////////////////////
+    final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
+    final InputStream blitDepthFragStream = resources.openRawResource(R.raw.blit_depth_fragment_shader);
+
+    try
+      {
+      mBlitDepthProgram = new DistortedProgram(blitDepthVertStream,blitDepthFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile BLIT DEPTH program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
+    mBlitDepthTextureH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Texture");
+    mBlitDepthDepthTextureH = GLES31.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
+    mBlitDepthDepthH        = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Depth");
+    mBlitDepthTexCorrH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_TexCorr");
+
+    // NORMAL PROGRAM //////////////////////////////////////
+    final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
+    final InputStream normalFragmentStream = resources.openRawResource(R.raw.normal_fragment_shader);
+
+    try
+      {
+      mNormalProgram = new DistortedProgram(normalVertexStream,normalFragmentStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile NORMAL program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int normalProgramH = mNormalProgram.getProgramHandle();
+    mNormalMVPMatrixH  = GLES31.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createProgramsOIT(Resources resources)
+    {
+    // MAIN OIT PROGRAM ////////////////////////////////
+    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
+    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
+
+    int numF = FragmentEffect.getNumEnabled();
+    int numV = VertexEffect.getNumEnabled();
+
+    String mainVertHeader= DistortedLibrary.GLSL_VERSION +
+                           ("#define NUM_VERTEX "   + ( numV>0 ? getMax(EffectType.VERTEX  ) : 0 ) + "\n") +
+                           ("#define OIT\n");
+    String mainFragHeader= DistortedLibrary.GLSL_VERSION +
+                           ("#define NUM_FRAGMENT " + ( numF>0 ? getMax(EffectType.FRAGMENT) : 0 ) + "\n") +
+                           ("#define OIT\n");
+
+    String enabledEffectV= VertexEffect.getGLSL();
+    String enabledEffectF= FragmentEffect.getGLSL();
+
+    try
+      {
+      mMainOITProgram = new DistortedProgram(mainVertStream, mainFragStream, mainVertHeader, mainFragHeader,
+                                             enabledEffectV, enabledEffectF, DistortedLibrary.GLSL, null);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile MAIN OIT program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int mainOITProgramH = mMainOITProgram.getProgramHandle();
+    EffectQueue.getUniforms(mainOITProgramH,1);
+    mMainOITTextureH    = GLES31.glGetUniformLocation( mainOITProgramH, "u_Texture");
+    mMainOITSizeH       = GLES31.glGetUniformLocation( mainOITProgramH, "u_Size");
+    mMainOITNumRecordsH = GLES31.glGetUniformLocation( mainOITProgramH, "u_numRecords");
+
+    // OIT CLEAR PROGRAM ////////////////////////////////////
+    final InputStream oitClearVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
+    final InputStream oitClearFragStream = resources.openRawResource(R.raw.oit_clear_fragment_shader);
+
+    try
+      {
+      mOITClearProgram = new DistortedProgram(oitClearVertStream,oitClearFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT CLEAR program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int oitClearProgramH   = mOITClearProgram.getProgramHandle();
+    mOITClearDepthH        = GLES31.glGetUniformLocation( oitClearProgramH, "u_Depth");
+    mOITClearTexCorrH      = GLES31.glGetUniformLocation( oitClearProgramH, "u_TexCorr");
+    mOITClearSizeH         = GLES31.glGetUniformLocation( oitClearProgramH, "u_Size");
+
+    // OIT BUILD PROGRAM ////////////////////////////////////
+    final InputStream oitBuildVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
+    final InputStream oitBuildFragStream = resources.openRawResource(R.raw.oit_build_fragment_shader);
+
+    try
+      {
+      mOITBuildProgram = new DistortedProgram(oitBuildVertStream,oitBuildFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT BUILD program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int oitBuildProgramH   = mOITBuildProgram.getProgramHandle();
+    mOITBuildTextureH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Texture");
+    mOITBuildDepthTextureH = GLES31.glGetUniformLocation( oitBuildProgramH, "u_DepthTexture");
+    mOITBuildDepthH        = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Depth");
+    mOITBuildTexCorrH      = GLES31.glGetUniformLocation( oitBuildProgramH, "u_TexCorr");
+    mOITBuildSizeH         = GLES31.glGetUniformLocation( oitBuildProgramH, "u_Size");
+    mOITBuildNumRecordsH   = GLES31.glGetUniformLocation( oitBuildProgramH, "u_numRecords");
+
+    // OIT COLLAPSE PROGRAM ///////////////////////////
+    final InputStream oitCollapseVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
+    final InputStream oitCollapseFragStream = resources.openRawResource(R.raw.oit_collapse_fragment_shader);
+
+    try
+      {
+      mOITCollapseProgram = new DistortedProgram(oitCollapseVertStream,oitCollapseFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT COLLAPSE program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int oitCollapseProgramH   = mOITCollapseProgram.getProgramHandle();
+    mOITCollapseDepthTextureH = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_DepthTexture");
+    mOITCollapseDepthH        = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Depth");
+    mOITCollapseTexCorrH      = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_TexCorr");
+    mOITCollapseSizeH         = GLES31.glGetUniformLocation( oitCollapseProgramH, "u_Size");
+
+    // OIT RENDER PROGRAM ///////////////////////////
+    final InputStream oitRenderVertStream = resources.openRawResource(R.raw.oit_vertex_shader);
+    final InputStream oitRenderFragStream = resources.openRawResource(R.raw.oit_render_fragment_shader);
+
+    try
+      {
+      mOITRenderProgram = new DistortedProgram(oitRenderVertStream,oitRenderFragStream, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL_VERSION, DistortedLibrary.GLSL);
+      }
+    catch(Exception e)
+      {
+      Log.e("EFFECTS", e.getClass().getSimpleName()+" trying to compile OIT RENDER program: "+e.getMessage());
+      throw new RuntimeException(e.getMessage());
+      }
+
+    int oitRenderProgramH   = mOITRenderProgram.getProgramHandle();
+    mOITRenderDepthH        = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Depth");
+    mOITRenderTexCorrH      = GLES31.glGetUniformLocation( oitRenderProgramH, "u_TexCorr");
+    mOITRenderSizeH         = GLES31.glGetUniformLocation( oitRenderProgramH, "u_Size");
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void displayNormals(EffectQueue[] queues, MeshBase mesh)
+    {
+    int num = mesh.getNumVertices();
+    int tfo = mesh.getTFO();
+
+    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfo );
+    GLES31.glBeginTransformFeedback( GLES31.GL_POINTS);
+    InternalRenderState.switchOffDrawing();
+    GLES31.glDrawArrays( GLES31.GL_POINTS, 0, num );
+    InternalRenderState.restoreDrawing();
+    GLES31.glEndTransformFeedback();
+    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
+
+    DistortedLibrary.mNormalProgram.useProgram();
+    GLES31.glUniformMatrix4fv(DistortedLibrary.mNormalMVPMatrixH, 1, false, EffectQueue.getMVP(queues) , 0);
+    mesh.bindTransformAttribs(DistortedLibrary.mNormalProgram);
+    GLES31.glLineWidth(8.0f);
+    GLES31.glDrawArrays(GLES31.GL_LINES, 0, 2*num);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void drawPrivOIT(EffectQueue[] queues, float halfW, float halfH, MeshBase mesh, InternalOutputSurface surface, long currTime)
+    {
+    float halfZ = halfW*mesh.getZFactor();
+
+    EffectQueue.compute(queues, currTime, halfW, halfH, halfZ );
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+
+    DistortedLibrary.mMainOITProgram.useProgram();
+    GLES31.glUniform1i(DistortedLibrary.mMainOITTextureH, 0);
+    GLES31.glUniform2ui(DistortedLibrary.mMainOITSizeH, surface.mWidth, surface.mHeight);
+    GLES31.glUniform1ui(DistortedLibrary.mMainOITNumRecordsH, (int)(DistortedLibrary.mBufferSize*surface.mWidth*surface.mHeight) );
+
+    mesh.bindVertexAttribs(DistortedLibrary.mMainOITProgram);
+
+    float inflate     = mesh.getInflate();
+    int width         = surface.mWidth;
+    int height        = surface.mHeight;
+    float distance    = surface.mDistance;
+    float mipmap      = surface.mMipmap;
+    float[] projection= surface.mProjectionMatrix;
+
+    EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 1 );
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.getNumVertices() );
+
+    if( mesh.getShowNormals() )
+      {
+      DistortedLibrary.mMainProgram.useProgram();
+      EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 0 );
+      displayNormals(queues,mesh);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void drawPriv(EffectQueue[] queues, float halfW, float halfH, MeshBase mesh, InternalOutputSurface surface, long currTime)
+    {
+    float halfZ = halfW*mesh.getZFactor();
+
+    EffectQueue.compute(queues, currTime, halfW, halfH, halfZ );
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    DistortedLibrary.mMainProgram.useProgram();
+    GLES31.glUniform1i(DistortedLibrary.mMainTextureH, 0);
+    mesh.bindVertexAttribs(DistortedLibrary.mMainProgram);
+
+    float inflate     = mesh.getInflate();
+    int width         = surface.mWidth;
+    int height        = surface.mHeight;
+    float distance    = surface.mDistance;
+    float mipmap      = surface.mMipmap;
+    float[] projection= surface.mProjectionMatrix;
+
+    EffectQueue.send(queues, width, height, distance, mipmap, projection, inflate, halfW, halfH, halfZ, 0 );
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.getNumVertices() );
+
+    if( mesh.getShowNormals() ) displayNormals(queues,mesh);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void blitPriv(InternalOutputSurface surface)
+    {
+    mBlitProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mBlitTextureH, 0);
+    GLES31.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void blitDepthPriv(InternalOutputSurface surface, float corrW, float corrH)
+    {
+    mBlitDepthProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mBlitDepthTextureH, 0);
+    GLES31.glUniform1i(mBlitDepthDepthTextureH, 1);
+    GLES31.glUniform2f(mBlitDepthTexCorrH, corrW, corrH );
+    GLES31.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static int printPreviousBuffer()
+    {
+    int counter = 0;
+
+    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
+                                                                GLES31.GL_MAP_READ_BIT);
+    if( atomicBuf!=null )
+      {
+      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
+      counter = atomicIntBuf.get(0);
+      }
+    else
+      {
+      android.util.Log.e("effects", "print: failed to map atomic buffer");
+      }
+
+    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
+
+    return counter;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void zeroBuffer()
+    {
+    ByteBuffer atomicBuf = (ByteBuffer)GLES31.glMapBufferRange( GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, 4,
+        GLES31.GL_MAP_WRITE_BIT|GLES31.GL_MAP_INVALIDATE_BUFFER_BIT);
+    if( atomicBuf!=null )
+      {
+      IntBuffer atomicIntBuf = atomicBuf.order(ByteOrder.nativeOrder()).asIntBuffer();
+      atomicIntBuf.put(0,0);
+      }
+    else
+      {
+      android.util.Log.e("effects", "zero: failed to map atomic buffer");
+      }
+
+    GLES31.glUnmapBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// reset atomic counter to 0
+
+  static int zeroOutAtomic()
+    {
+    int counter = 0;
+
+    if( mAtomicCounter[0]<0 )
+      {
+      GLES31.glGenBuffers(DistortedLibrary.FBO_QUEUE_SIZE,mAtomicCounter,0);
+
+      for(int i = 0; i< DistortedLibrary.FBO_QUEUE_SIZE; i++)
+        {
+        GLES31.glBindBuffer(GLES31.GL_ATOMIC_COUNTER_BUFFER, mAtomicCounter[i]);
+        GLES31.glBufferData(GLES31.GL_ATOMIC_COUNTER_BUFFER, 4, null, GLES31.GL_DYNAMIC_DRAW);
+        zeroBuffer();
+        }
+      }
+
+    // reading the value of the buffer on every frame would slow down rendering by
+    // about 3%; doing it only once every 5 frames affects speed by less than 1%.
+    if( mCurrBuffer==0 )
+      {
+      GLES31.glBindBufferBase(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, mAtomicCounter[mCurrBuffer]);
+      counter = printPreviousBuffer();
+      }
+
+    if( ++mCurrBuffer>= DistortedLibrary.FBO_QUEUE_SIZE ) mCurrBuffer = 0;
+
+    GLES31.glBindBufferBase(GLES31.GL_ATOMIC_COUNTER_BUFFER, 0, mAtomicCounter[mCurrBuffer]);
+    zeroBuffer();
+
+    return counter;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Pass1 of the OIT algorithm. Clear per-pixel head-pointers.
+
+  static void oitClear(InternalOutputSurface surface, int counter)
+    {
+    if( mLinkedListSSBO[0]<0 )
+      {
+      GLES31.glGenBuffers(1,mLinkedListSSBO,0);
+
+      int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
+      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
+      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES31.GL_DYNAMIC_READ|GLES31.GL_DYNAMIC_DRAW);
+      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
+
+      GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER, 1, mLinkedListSSBO[0]);
+      }
+
+    // See if we have overflown the SSBO in one of the previous frames.
+    // If yes, assume we need to make the SSBO larger.
+    float overflow = counter/(mBufferSize*surface.mWidth*surface.mHeight);
+
+    if( overflow>1.0f )
+      {
+      //android.util.Log.e("effects", "previous frame rendered "+counter+
+      //                   " fragments, but there was only "+(mBufferSize*surface.mWidth*surface.mHeight)+" space");
+
+      mBufferSize *= (int)(overflow+1.0f);
+      int size = (int)(surface.mWidth*surface.mHeight*(3*mBufferSize+1)*4);
+      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, mLinkedListSSBO[0]);
+      GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, size, null, GLES31.GL_DYNAMIC_READ|GLES31.GL_DYNAMIC_DRAW);
+      GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);
+      }
+
+    mOITClearProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform2f(mOITClearTexCorrH, 1.0f, 1.0f );   // corrections do not really matter here - only present because of common vertex shader.
+    GLES31.glUniform1f( mOITClearDepthH , 1.0f);          // likewise depth
+    GLES31.glUniform2ui(mOITClearSizeH, surface.mWidth, surface.mHeight);
+    GLES31.glVertexAttribPointer(mOITClearProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Pass2 of the OIT algorithm - build per-pixel linked lists.
+
+  static void oitBuild(InternalOutputSurface surface, float corrW, float corrH)
+    {
+    mOITBuildProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mOITBuildTextureH, 0);
+    GLES31.glUniform1i(mOITBuildDepthTextureH, 1);
+    GLES31.glUniform2f(mOITBuildTexCorrH, corrW, corrH );
+    GLES31.glUniform2ui(mOITBuildSizeH, surface.mWidth, surface.mHeight);
+    GLES31.glUniform1ui(mOITBuildNumRecordsH, (int)(mBufferSize*surface.mWidth*surface.mHeight) );
+    GLES31.glUniform1f(mOITBuildDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mOITBuildProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Pass3 of the OIT algorithm. Cut occluded parts of the linked list.
+
+  static void oitCollapse(InternalOutputSurface surface, float corrW, float corrH)
+    {
+    mOITCollapseProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mOITCollapseDepthTextureH, 1);
+    GLES31.glUniform2f(mOITCollapseTexCorrH, corrW, corrH );
+    GLES31.glUniform2ui(mOITCollapseSizeH, surface.mWidth, surface.mHeight);
+    GLES31.glUniform1f( mOITCollapseDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mOITCollapseProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Pass4 of the OIT algorithm. Render all the transparent pixels from the per-pixel linked lists.
+
+  static void oitRender(InternalOutputSurface surface, float corrW, float corrH)
+    {
+    mOITRenderProgram.useProgram();
+
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform2f(mOITRenderTexCorrH, corrW, corrH );
+    GLES31.glUniform2ui(mOITRenderSizeH, surface.mWidth, surface.mHeight);
+    GLES31.glUniform1f( mOITRenderDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mOITRenderProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void setSSBOSize(float size)
+    {
+    mBufferSize = size;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ARM Mali driver r12 has problems when we keep swapping many FBOs (fixed in r22)
+// PowerVR GE8100 compiler fails to compile OIT programs.
+
+  private static void detectBuggyDrivers()
+    {
+    String vendor  = GLES31.glGetString(GLES31.GL_VENDOR);
+    String version = GLES31.glGetString(GLES31.GL_VERSION);
+    String renderer= GLES31.glGetString(GLES31.GL_RENDERER);
+
+    /*
+    android.util.Log.e("DISTORTED", "GLSL Version "+GLES31.glGetString(GLES31.GL_SHADING_LANGUAGE_VERSION));
+    android.util.Log.e("DISTORTED", "GL Version "  +GLES31.glGetString(GLES31.GL_VERSION));
+    android.util.Log.e("DISTORTED", "GL Vendor "   +GLES31.glGetString(GLES31.GL_VENDOR));
+    android.util.Log.e("DISTORTED", "GL Renderer " +GLES31.glGetString(GLES31.GL_RENDERER));
+    */
+
+    if( vendor.contains("ARM") )
+      {
+      if( version.contains("r12") )
+        {
+        android.util.Log.e("DISTORTED", "You are running this on a ARM Mali driver r12.\nThis is a buggy driver, please update to r22. Problems with flashing expected.");
+        }
+      }
+    else if( vendor.contains("Imagination") )
+      {
+      if( renderer.contains("GE8") )
+        {
+        android.util.Log.e("DISTORTED", "You are running this on a PowerVR GE8XXX.\nDue to a buggy compiler OIT rendering will not work");
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Have we called onCreate yet, ie have we initialized the library?
+ * @return <code>true</code> if the library is initialized and ready for action.
+ */
+  public static boolean isInitialized()
+    {
+    return mInitialized;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * When OpenGL context gets created, call this method so that the library can initialise its internal data structures.
+ * I.e. best called from GLSurfaceView.onCreate().
+ * <p>
+ * Needs to be called from a thread holding the OpenGL context.
+ *   
+ * @param context Context of the App using the library - used to open up Resources and read Shader code.
+ */
+  public static void onCreate(final Context context) throws Exception
+    {
+    final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
+    android.util.Log.e("DISTORTED", "Using OpenGL ES "+configurationInfo.getGlEsVersion());
+
+    mInitialized = true;
+
+    detectBuggyDrivers();
+
+    EffectMessageSender.startSending();
+
+    final Resources resources = context.getResources();
+
+    Exception exception=null;
+
+    try
+      {
+      createPrograms(resources);
+      }
+    catch(Exception ex)
+      {
+      exception = ex;
+      }
+
+    try
+      {
+      createProgramsOIT(resources);
+      }
+    catch(Exception ex)
+      {
+      exception = ex;
+      }
+
+    try
+      {
+      EffectQueuePostprocess.createPrograms(resources);
+      }
+    catch(Exception ex)
+      {
+      exception = ex;
+      }
+
+    try
+      {
+      PostprocessEffect.createPrograms();
+      }
+    catch(Exception ex)
+      {
+      exception = ex;
+      }
+
+    if( exception!=null)
+      {
+      throw exception;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Call this so that the Library can release the OpenGL related data that needs to be recreated.
+ * Must be called from Activity.onPause().
+ */
+  public static void onPause()
+    {
+    InternalObject.onPause();
+
+    mLinkedListSSBO[0]= -1;
+
+    for(int i = 0; i< DistortedLibrary.FBO_QUEUE_SIZE; i++) mAtomicCounter[i] = -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Call this so that the Library can release its internal data structures.
+ * Must be called from Activity.onDestroy(). 
+ */
+  public static void onDestroy()
+    {
+    InternalObject.onDestroy();
+    InternalNodeData.onDestroy();
+    DistortedEffects.onDestroy();
+    InternalMaster.onDestroy();
+    InternalOutputSurface.onDestroy();
+    EffectQueue.onDestroy();
+    Effect.onDestroy();
+    EffectMessageSender.stopSending();
+
+    mInitialized = false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the maximum number of effects of a given type that can be simultaneously applied to a
+ * single (InputSurface,MeshBase) combo.
+ *
+ * @param type {@link EffectType}
+ * @return The maximum number of effects of a given type.
+ */
+  @SuppressWarnings("unused")
+  public static int getMax(EffectType type)
+    {
+    return EffectQueue.getMax(type.ordinal());
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the maximum number of effects that can be stored in a single EffectQueue at one time.
+ * This can fail if:
+ * <ul>
+ * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
+ * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
+ *     before the Vertex Shader gets compiled, i.e. before the call to {@link DistortedLibrary#onCreate}. After this
+ *     time only decreasing the value of 'max' is permitted.
+ * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
+ * </ul>
+ *
+ * @param type {@link EffectType}
+ * @param max new maximum number of simultaneous effects. Has to be a non-negative number not greater
+ *            than Byte.MAX_VALUE
+ * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
+ */
+  @SuppressWarnings("unused")
+  public static boolean setMax(EffectType type, int max)
+    {
+    return EffectQueue.setMax(type.ordinal(),max);
+    }
+  }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/main/DistortedMaster.java b/src/main/java/org/distorted/library/main/DistortedMaster.java
deleted file mode 100644
index fb3ad22..0000000
--- a/src/main/java/org/distorted/library/main/DistortedMaster.java
+++ /dev/null
@@ -1,108 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import java.util.ArrayList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * This static class handles assigning jobs to other classes. It does it once, at the beginning of
- * each frame.
- * <p>
- * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
- *
- * @y.exclude
- */
-public class DistortedMaster
-  {
-  private static ArrayList<Slave> mSlaves = new ArrayList<>();
-
-  public interface Slave
-    {
-    void doWork();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private DistortedMaster()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static boolean toDo()
-    {
-    Slave slave;
-    int num = mSlaves.size();
-
-    try
-      {
-      for(int i=0; i<num; i++)
-        {
-        slave = mSlaves.remove(0);
-
-        if( slave!=null ) slave.doWork();
-        }
-      }
-    catch(IndexOutOfBoundsException ie)
-      {
-      // onDestroy must have been called, ignore
-      }
-
-    return ( num>0 );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void newSlave(Slave s)
-    {
-    int num = mSlaves.size();
-    boolean found = false;
-    Slave tmp;
-
-    try
-      {
-      for(int i=0; i<num; i++)
-        {
-        tmp = mSlaves.get(i);
-
-        if( tmp==s )
-          {
-          found = true;
-          break;
-          }
-        }
-      }
-    catch(IndexOutOfBoundsException ie)
-      {
-      // onDestroy must have been called, ignore
-      }
-
-    if( !found ) mSlaves.add(s);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void onDestroy()
-    {
-    mSlaves.clear();
-    }
-  }
diff --git a/src/main/java/org/distorted/library/main/DistortedNode.java b/src/main/java/org/distorted/library/main/DistortedNode.java
index 51fecd9..3456024 100644
--- a/src/main/java/org/distorted/library/main/DistortedNode.java
+++ b/src/main/java/org/distorted/library/main/DistortedNode.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.main;
@@ -37,15 +37,15 @@ import java.util.Collections;
  * to sub-class 'NodeData'. Two identical sub-trees attached at different points of the main tree
  * will point to the same NodeData; only the first of this is rendered (mData.numRender!).
  */
-public class DistortedNode implements DistortedChildrenList.Parent
+public class DistortedNode implements InternalChildrenList.Parent
   {
   private MeshBase mMesh;
   private DistortedEffects mEffects;
-  private DistortedSurface mSurface;
-  private DistortedRenderState mState;
-  private DistortedNodeData mData;
-  private DistortedChildrenList mChildren;
-  private DistortedChildrenList.Parent mParent;
+  private InternalSurface mSurface;
+  private InternalRenderState mState;
+  private InternalNodeData mData;
+  private InternalChildrenList mChildren;
+  private InternalChildrenList.Parent mParent;
 
   private int mFboW, mFboH, mFboDepthStencil;
   private boolean mRenderWayOIT;
@@ -116,13 +116,13 @@ public class DistortedNode implements DistortedChildrenList.Parent
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * This is not really part of the public API. Has to be public only because it is a part of the
- * DistortedChildrenList.Parent interface.
+ * InternalChildrenList.Parent interface.
  *
  * @y.exclude
  */
   public void adjustIsomorphism()
     {
-    DistortedNodeData newData = DistortedNodeData.returnData(generateIDList());
+    InternalNodeData newData = InternalNodeData.returnData(generateIDList());
     boolean deleteOldFBO = mData.removeData();
     boolean createNewFBO = (mChildren.getNumChildren()>0 && newData.mFBO==null);
 
@@ -148,15 +148,15 @@ public class DistortedNode implements DistortedChildrenList.Parent
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // return the total number of render calls issued
 
-  int drawNoBlend(long currTime, DistortedOutputSurface surface)
+  int drawNoBlend(long currTime, InternalOutputSurface surface)
     {
-    DistortedSurface input = getInternalSurface();
+    InternalSurface input = getInternalSurface();
 
     if( input.setAsInput() )
       {
       mState.apply();
       GLES31.glDisable(GLES31.GL_BLEND);
-      Distorted.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
+      DistortedLibrary.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
       GLES31.glEnable(GLES31.GL_BLEND);
       return 1;
       }
@@ -167,14 +167,14 @@ public class DistortedNode implements DistortedChildrenList.Parent
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Use the Order Independent Transparency method to draw a non-postprocessed child.
 
-  int drawOIT(long currTime, DistortedOutputSurface surface)
+  int drawOIT(long currTime, InternalOutputSurface surface)
     {
-    DistortedSurface input = getInternalSurface();
+    InternalSurface input = getInternalSurface();
 
     if( input.setAsInput() )
       {
       mState.apply();
-      Distorted.drawPrivOIT(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
+      DistortedLibrary.drawPrivOIT(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
       return 1;
       }
 
@@ -184,14 +184,14 @@ public class DistortedNode implements DistortedChildrenList.Parent
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // return the total number of render calls issued
 
-  int draw(long currTime, DistortedOutputSurface surface)
+  int draw(long currTime, InternalOutputSurface surface)
     {
-    DistortedSurface input = getInternalSurface();
+    InternalSurface input = getInternalSurface();
 
     if( input.setAsInput() )
       {
       mState.apply();
-      Distorted.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
+      DistortedLibrary.drawPriv(mEffects.getQueues(), mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
       return 1;
       }
 
@@ -226,7 +226,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
       if( mSurface.setAsInput() )
         {
         numRenders++;
-        Distorted.blitPriv(mData.mFBO);
+        DistortedLibrary.blitPriv(mData.mFBO);
         }
 
       numRenders += mData.mFBO.renderChildren(currTime,numChildren,mChildren,0, mRenderWayOIT);
@@ -241,12 +241,12 @@ public class DistortedNode implements DistortedChildrenList.Parent
     {
     int width  = mFboW <= 0 ? mSurface.getWidth()  : mFboW;
     int height = mFboH <= 0 ? mSurface.getHeight() : mFboH;
-    return new DistortedFramebuffer(1,mFboDepthStencil, DistortedSurface.TYPE_TREE, width, height);
+    return new DistortedFramebuffer(1,mFboDepthStencil, InternalSurface.TYPE_TREE, width, height);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void setParent(DistortedChildrenList.Parent parent)
+  void setParent(InternalChildrenList.Parent parent)
     {
     mParent = parent;
     }
@@ -261,13 +261,13 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * @param effects DistortedEffects to put into the new Node.
  * @param mesh MeshBase to put into the new Node.
  */
-  public DistortedNode(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
+  public DistortedNode(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
     {
     mSurface       = surface;
     mEffects       = effects;
     mMesh          = mesh;
-    mState         = new DistortedRenderState();
-    mChildren      = new DistortedChildrenList(this);
+    mState         = new InternalRenderState();
+    mChildren      = new InternalChildrenList(this);
     mParent        = null;
     mRenderWayOIT  = false;
 
@@ -275,7 +275,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
     mFboH            = 0;  // mSurface's dimensions
     mFboDepthStencil = DistortedFramebuffer.DEPTH_NO_STENCIL;
 
-    mData = DistortedNodeData.returnData(generateIDList());
+    mData = InternalNodeData.returnData(generateIDList());
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////  
@@ -284,15 +284,15 @@ public class DistortedNode implements DistortedChildrenList.Parent
  *     
  * @param node The DistortedNode to copy data from.
  * @param flags bit field composed of a subset of the following:
- *        {@link Distorted#CLONE_SURFACE},  {@link Distorted#CLONE_MATRIX}, {@link Distorted#CLONE_VERTEX},
- *        {@link Distorted#CLONE_FRAGMENT} and {@link Distorted#CLONE_CHILDREN}.
+ *        {@link DistortedLibrary#CLONE_SURFACE},  {@link DistortedLibrary#CLONE_MATRIX}, {@link DistortedLibrary#CLONE_VERTEX},
+ *        {@link DistortedLibrary#CLONE_FRAGMENT} and {@link DistortedLibrary#CLONE_CHILDREN}.
  *        For example flags = CLONE_SURFACE | CLONE_CHILDREN.
  */
   public DistortedNode(DistortedNode node, int flags)
     {
     mEffects      = new DistortedEffects(node.mEffects,flags);
     mMesh         = node.mMesh;
-    mState        = new DistortedRenderState();
+    mState        = new InternalRenderState();
     mParent       = null;
     mRenderWayOIT = false;
 
@@ -300,7 +300,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
     mFboH            = node.mFboH;
     mFboDepthStencil = node.mFboDepthStencil;
 
-    if( (flags & Distorted.CLONE_SURFACE) != 0 )
+    if( (flags & DistortedLibrary.CLONE_SURFACE) != 0 )
       {
       mSurface = node.mSurface;
       }
@@ -311,7 +311,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
 
       if( node.mSurface instanceof DistortedTexture )
         {
-        mSurface = new DistortedTexture(w,h, DistortedSurface.TYPE_TREE);
+        mSurface = new DistortedTexture(w,h, InternalSurface.TYPE_TREE);
         }
       else if( node.mSurface instanceof DistortedFramebuffer )
         {
@@ -323,20 +323,20 @@ public class DistortedNode implements DistortedChildrenList.Parent
           depthStencil = (hasStencil ? DistortedFramebuffer.BOTH_DEPTH_STENCIL:DistortedFramebuffer.DEPTH_NO_STENCIL);
           }
 
-        mSurface = new DistortedFramebuffer(1,depthStencil,DistortedSurface.TYPE_TREE,w,h);
+        mSurface = new DistortedFramebuffer(1,depthStencil, InternalSurface.TYPE_TREE,w,h);
         }
       }
 
-    if( (flags & Distorted.CLONE_CHILDREN) != 0 )
+    if( (flags & DistortedLibrary.CLONE_CHILDREN) != 0 )
       {
       mChildren = node.mChildren;
       }
     else
       {
-      mChildren = new DistortedChildrenList(this);
+      mChildren = new InternalChildrenList(this);
       }
 
-    mData = DistortedNodeData.returnData(generateIDList());
+    mData = InternalNodeData.returnData(generateIDList());
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -375,7 +375,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
     mRenderWayOIT = oit;
 
     if( initialSize>0.0f && initialSize<10.0f )
-      Distorted.setSSBOSize(initialSize);
+      DistortedLibrary.setSSBOSize(initialSize);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -383,7 +383,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * Adds a new child to the last position in the list of our Node's children.
  * <p>
  * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
+ * InternalMaster (by calling doWork())
  *
  * @param node The new Node to add.
  */
@@ -397,14 +397,14 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * Adds a new child to the last position in the list of our Node's children.
  * <p>
  * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
+ * InternalMaster (by calling doWork())
  *
  * @param surface InputSurface to initialize our child Node with.
  * @param effects DistortedEffects to initialize our child Node with.
  * @param mesh MeshBase to initialize our child Node with.
  * @return the newly constructed child Node, or null if we couldn't allocate resources.
  */
-  public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
+  public DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
     {
     return mChildren.attach(surface,effects,mesh);
     }
@@ -414,7 +414,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * Removes the first occurrence of a specified child from the list of children of our Node.
  * <p>
  * We cannot do this mid-render - actual detachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
+ * InternalMaster (by calling doWork())
  *
  * @param node The Node to remove.
  */
@@ -431,7 +431,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * of them having the same Effects but - for instance - different Mesh. Use with care.
  * <p>
  * We cannot do this mid-render - actual detachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
+ * InternalMaster (by calling doWork())
  *
  * @param effects DistortedEffects to remove.
  */
@@ -445,7 +445,7 @@ public class DistortedNode implements DistortedChildrenList.Parent
  * Removes all children Nodes.
  * <p>
  * We cannot do this mid-render - actual detachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
+ * InternalMaster (by calling doWork())
  */
   public void detachAll()
     {
@@ -465,22 +465,22 @@ public class DistortedNode implements DistortedChildrenList.Parent
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Returns the DistortedSurface object that's in the Node.
+ * Returns the InternalSurface object that's in the Node.
  *
- * @return The DistortedSurface contained in the Node.
+ * @return The InternalSurface contained in the Node.
  */
-  public DistortedSurface getSurface()
+  public InternalSurface getSurface()
     {
     return mSurface;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
   /**
-   * Returns the DistortedSurface object that's in the Node.
+   * Returns the InternalSurface object that's in the Node.
    *
-   * @return The DistortedSurface contained in the Node (if a leaf), or the FBO (if an internal Node)
+   * @return The InternalSurface contained in the Node (if a leaf), or the FBO (if an internal Node)
    */
-  public DistortedSurface getInternalSurface()
+  public InternalSurface getInternalSurface()
     {
     return mChildren.getNumChildren()==0 ? mSurface : mData.mFBO;
     }
diff --git a/src/main/java/org/distorted/library/main/DistortedNodeData.java b/src/main/java/org/distorted/library/main/DistortedNodeData.java
deleted file mode 100644
index 8befa60..0000000
--- a/src/main/java/org/distorted/library/main/DistortedNodeData.java
+++ /dev/null
@@ -1,119 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * This is a member of DistortedNode. Makes sure two isomorphic Nodes only get rendered once.
- */
-class DistortedNodeData
-  {
-  private static HashMap<ArrayList<Long>, DistortedNodeData> mMapNodeID = new HashMap<>();
-  private static long mNextNodeID =0;
-
-  private final ArrayList<Long> key;
-  private int numPointingNodes;
-  private long currTime;
-
-  final long ID;
-  DistortedFramebuffer mFBO;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private DistortedNodeData(long id, ArrayList<Long> k)
-    {
-    ID              = id;
-    key             = k;
-    numPointingNodes= 1;
-    currTime        =-1;
-    mFBO            = null;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static synchronized void onDestroy()
-    {
-    mNextNodeID = 0;
-    mMapNodeID.clear();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  static void debugMap()
-    {
-    DistortedNodeData tmp;
-
-    for(ArrayList<Long> key: mMapNodeID.keySet())
-      {
-      tmp = mMapNodeID.get(key);
-      android.util.Log.e("NodeData", "NodeID: "+tmp.ID+" <-- "+key);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static DistortedNodeData returnData(ArrayList<Long> list)
-    {
-    DistortedNodeData newData = mMapNodeID.get(list);
-
-    if( newData!=null )
-      {
-      newData.numPointingNodes++;
-      }
-    else
-      {
-      newData = new DistortedNodeData(++mNextNodeID,list);
-      mMapNodeID.put(list,newData);
-      }
-
-    return newData;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean removeData()
-    {
-    if( --numPointingNodes==0 )
-      {
-      mMapNodeID.remove(key);
-
-      if( mFBO!=null ) return true;
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  boolean notRenderedYetAtThisTime(long time)
-    {
-    if( currTime!=time )
-      {
-      currTime = time;
-      return true;
-      }
-
-    return false;
-    }
-  }
diff --git a/src/main/java/org/distorted/library/main/DistortedObject.java b/src/main/java/org/distorted/library/main/DistortedObject.java
deleted file mode 100644
index 5fe7dff..0000000
--- a/src/main/java/org/distorted/library/main/DistortedObject.java
+++ /dev/null
@@ -1,260 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Any Object which gets uploaded to GPU memory and thus needs to be re-created (transparently to
- * applications!) whenever we lose OpenGL context.
- *
- * Keep all objects created in a static LinkedList. The point: we need to be able to mark
- * Objects for deletion, and delete all marked Objects later at a convenient time (that's
- * because we can only delete from a thread that holds the OpenGL context so here we provide a
- * framework where one is able to mark for deletion at any time and actual deletion takes place
- * on the next render).
-*/
-abstract class DistortedObject
-{
-  static final int FAILED_TO_CREATE = 1;
-  static final int NOT_CREATED_YET  = 2;
-  static final int DONT_CREATE      = 3;
-  static final int CREATED          = 4;
-
-  static final int TYPE_USER = 0;
-  static final int TYPE_TREE = 1;
-  static final int TYPE_SYST = 2;
-
-  private static final int JOB_CREATE = 0;
-  private static final int JOB_DELETE = 1;
-
-  private class Job
-    {
-    DistortedObject object;
-    int action;
-
-    Job(DistortedObject o, int a)
-      {
-      object = o;
-      action = a;
-      }
-    }
-
-  private static boolean mToDo = false;
-  private static LinkedList<DistortedObject> mDoneList = new LinkedList<>();
-  private static HashMap<Long,Job> mToDoMap = new HashMap<>();
-  private static long mNextClientID = 0;
-  private static long mNextSystemID = 0;
-
-  private final static Object mDoneLock = new Object();
-  private final static Object mToDoLock = new Object();
-
-  private long mID;
-  private int mType;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract void create();
-  abstract void delete();
-  abstract void recreate();
-  abstract String printDetails();
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
-
-  static boolean toDo()
-    {
-    if( mToDo )
-      {
-      Job job;
-      DistortedObject object;
-
-      synchronized(mToDoLock)
-        {
-        for(Long key: mToDoMap.keySet())
-          {
-          job = mToDoMap.get(key);
-          object = job.object;
-
-          if( job.action==JOB_CREATE )
-            {
-            object.create();
-            mDoneList.add(object);
-            }
-          else if( job.action==JOB_DELETE )
-            {
-            object.delete();
-            }
-          }
-
-        mToDoMap.clear();
-        mToDo = false;
-        }
-
-      return true;
-      }
-
-    return false;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void onPause()
-    {
-    DistortedObject object;
-
-    synchronized(mDoneLock)
-      {
-      synchronized(mToDoLock)
-        {
-        int num = mDoneList.size();
-
-        try
-          {
-          for (int i = 0; i < num; i++)
-            {
-            object = mDoneList.removeFirst();
-            mToDoMap.put(object.mID, object.new Job(object, JOB_CREATE));
-            object.recreate();
-            }
-          }
-        catch( Exception ex )
-          {
-          // something else removed an object in the meantime; ignore
-          }
-        }
-      }
-
-    mToDo = true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void onDestroy()
-    {
-    synchronized(mToDoLock)
-      {
-      synchronized(mDoneLock)
-        {
-        mToDoMap.clear();
-        mDoneList.clear();
-
-        mToDo = true;
-        mNextClientID = 0;
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @SuppressWarnings("unused")
-  static void debugLists()
-    {
-    android.util.Log.e("Object", "Done list:");
-
-    for(DistortedObject object : mDoneList)
-      {
-      object.print("");
-      }
-
-    android.util.Log.e("Object", "ToDo list:");
-
-    Job job;
-
-    for(Long key: mToDoMap.keySet())
-      {
-      job = mToDoMap.get(key);
-      job.object.print(job.action==JOB_CREATE ? " create":" delete");
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void print(String msg)
-    {
-    String str = "ID:"+mID;
-
-    switch(mType)
-      {
-      case TYPE_SYST: str+=" SYSTEM "; break;
-      case TYPE_USER: str+=" USER   "; break;
-      case TYPE_TREE: str+=" TREE   "; break;
-      default       : str+=" ERROR? ";
-      }
-
-    android.util.Log.e("Object", str+printDetails()+msg);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedObject(int type)
-    {
-    mID  = type==TYPE_SYST ? --mNextSystemID : ++mNextClientID;
-    mType= type;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void markForCreation()
-    {
-    synchronized(mDoneLock)
-      {
-      mDoneList.remove(this);
-      }
-
-    synchronized(mToDoLock)
-      {
-      mToDoMap.put(mID, new Job(this,JOB_CREATE) );
-      mToDo = true;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
- */
-  public void markForDeletion()
-    {
-    synchronized(mDoneLock)
-      {
-      mDoneList.remove(this);
-      }
-
-    synchronized(mToDoLock)
-      {
-      mToDoMap.put(mID, new Job(this,JOB_DELETE) );
-      mToDo = true;
-      }
-    }
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return unique ID of this Object.
- */
-  public long getID()
-    {
-    return mID;
-    }
-
-}
diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
deleted file mode 100644
index 2acbecd..0000000
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ /dev/null
@@ -1,930 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import android.opengl.GLES31;
-import android.opengl.Matrix;
-
-import org.distorted.library.effect.EffectQuality;
-import org.distorted.library.effectqueue.EffectQueuePostprocess;
-import org.distorted.library.mesh.MeshBase;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * This is not really part of the public API.
- *
- * @y.exclude
- */
-public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedChildrenList.Parent
-{
-  public static final int NO_DEPTH_NO_STENCIL = 0;
-  public static final int DEPTH_NO_STENCIL    = 1;
-  public static final int BOTH_DEPTH_STENCIL  = 2;
-
-  float mFOV, mDistance, mNear;
-  float[] mProjectionMatrix;
-
-  int mDepthStencilCreated;
-  int mDepthStencil;
-  int[] mDepthStencilH;
-  int[] mFBOH;
-
-  float mMipmap;
-
-  int mRealWidth;   // the Surface can be backed up with a texture that is
-  int mRealHeight;  // larger than the viewport we have to it.
-                    // mWidth,mHeight are the sizes of the Viewport, those -
-                    // sizes of the backing up texture.
-
-  int mCurrFBO;     // internal current FBO (see Distorted.FBO_QUEUE_SIZE)
-
-  private static DistortedFramebuffer[] mBuffer=null; // Global buffers used for postprocessing.
-  private long[] mTime;
-  private float mClearR, mClearG, mClearB, mClearA, mClearDepth;
-  private int mClear, mClearStencil;
-  private boolean mRenderWayOIT;
-  private DistortedChildrenList mChildren;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedOutputSurface(int width, int height, int createColor, int numfbos, int numcolors, int depthStencil, int fbo, int type)
-    {
-    super(width,height,createColor,numfbos,numcolors,type);
-
-    mRenderWayOIT = false;
-    mCurrFBO      = 0;
-
-    mDepthStencilH = new int[numfbos];
-    mFBOH          = new int[numfbos];
-
-    mTime = new long[numfbos];
-    for(int i=0; i<mNumFBOs;i++) mTime[i]=0;
-
-    mRealWidth = width;
-    mRealHeight= height;
-
-    mProjectionMatrix = new float[16];
-
-    mFOV = 60.0f;
-    mNear=  0.5f;
-
-    mDepthStencilCreated= (depthStencil== NO_DEPTH_NO_STENCIL ? DONT_CREATE:NOT_CREATED_YET);
-    mDepthStencil = depthStencil;
-
-    mFBOH[0]         = fbo;
-    mDepthStencilH[0]= 0;
-
-    mClearR = 0.0f;
-    mClearG = 0.0f;
-    mClearB = 0.0f;
-    mClearA = 0.0f;
-
-    mClearDepth = 1.0f;
-    mClearStencil = 0;
-    mClear = GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_COLOR_BUFFER_BIT;
-
-    mMipmap = 1.0f;
-
-    mChildren = new DistortedChildrenList(this);
-
-    createProjection();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void createProjection()
-    {
-    if( mWidth>0 && mHeight>1 )
-      {
-      if( mFOV>0.0f )  // perspective projection
-        {
-        float a = 2.0f*(float)Math.tan(mFOV*Math.PI/360);
-        float q = mWidth*mNear;
-        float c = mHeight*mNear;
-
-        float left   = -q/2;
-        float right  = +q/2;
-        float bottom = -c/2;
-        float top    = +c/2;
-        float near   =  c/a;
-
-        mDistance    = mHeight/a;
-        float far    = 2*mDistance-near;
-
-        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
-        }
-      else             // parallel projection
-        {
-        float left   = -mWidth/2.0f;
-        float right  = +mWidth/2.0f;
-        float bottom = -mHeight/2.0f;
-        float top    = +mHeight/2.0f;
-        float near   = mWidth+mHeight-mHeight*(1.0f-mNear);
-        mDistance    = mWidth+mHeight;
-        float far    = mWidth+mHeight+mHeight*(1.0f-mNear);
-
-        Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void createPostprocessingBuffers(int width, int height, float near)
-    {
-    final float CLEAR_R = 1.0f;
-    final float CLEAR_G = 1.0f;
-    final float CLEAR_B = 1.0f;
-    final float CLEAR_A = 0.0f;
-    final float CLEAR_D = 1.0f;
-    final int   CLEAR_S = 0;
-
-    mBuffer = new DistortedFramebuffer[EffectQuality.LENGTH];
-    float mipmap=1.0f;
-
-    for (int j=0; j<EffectQuality.LENGTH; j++)
-      {
-      mBuffer[j] = new DistortedFramebuffer(Distorted.FBO_QUEUE_SIZE,2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
-      mBuffer[j].mMipmap = mipmap;
-      mBuffer[j].mNear = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
-      mBuffer[j].glClearColor(CLEAR_R, CLEAR_G, CLEAR_B, CLEAR_A);
-
-      mipmap *= EffectQuality.MULTIPLIER;
-      }
-
-    DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
-
-    DistortedRenderState.colorDepthStencilOn();
-    GLES31.glClearColor(CLEAR_R, CLEAR_G, CLEAR_B, CLEAR_A);
-    GLES31.glClearDepthf(CLEAR_D);
-    GLES31.glClearStencil(CLEAR_S);
-
-    for (int j=0; j<EffectQuality.LENGTH; j++)
-      {
-      for(int k=0; k<Distorted.FBO_QUEUE_SIZE; k++)
-        {
-        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBuffer[j].mFBOH[k]);
-        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k+1], 0);
-        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
-        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k  ], 0);
-        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
-        }
-      }
-
-    DistortedRenderState.colorDepthStencilRestore();
-
-    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static synchronized void onDestroy()
-    {
-    if( mBuffer!=null )
-      {
-      for (int j = 0; j < EffectQuality.LENGTH; j++)
-        {
-        mBuffer[j] = null;
-        }
-
-      mBuffer = null;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// The postprocessing buffers mBuffer[] are generally speaking too large (there's just one static
-// set of them) so before we use them for output, we need to adjust the Viewport as if they were
-// smaller. That takes care of outputting pixels to them. When we use them as input, we have to
-// adjust the texture coords - see the get{Width|Height}Correction functions.
-//
-// Also, adjust the Buffers so their Projection is the same like the surface we are supposed to be
-// rendering to.
-
-  private static void clonePostprocessingViewportAndProjection(DistortedOutputSurface from)
-    {
-    if( mBuffer[0].mWidth != from.mWidth || mBuffer[0].mHeight != from.mHeight ||
-        mBuffer[0].mFOV   != from.mFOV   || mBuffer[0].mNear   != from.mNear    )
-      {
-      DistortedOutputSurface surface;
-
-      for(int i=0; i<EffectQuality.LENGTH; i++)
-        {
-        surface = mBuffer[i];
-
-        surface.mWidth  = (int)(from.mWidth *surface.mMipmap);
-        surface.mHeight = (int)(from.mHeight*surface.mMipmap);
-        surface.mFOV    = from.mFOV;
-        surface.mNear   = from.mNear;  // Near plane is independent of the mipmap level
-
-        surface.createProjection();
-
-        int maxw = surface.mWidth  > surface.mRealWidth  ? surface.mWidth  : surface.mRealWidth;
-        int maxh = surface.mHeight > surface.mRealHeight ? surface.mHeight : surface.mRealHeight;
-
-        if (maxw > surface.mRealWidth || maxh > surface.mRealHeight)
-          {
-          surface.mRealWidth = maxw;
-          surface.mRealHeight = maxh;
-
-          surface.recreate();
-          surface.create();
-          }
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int blitWithDepth(long currTime, DistortedOutputSurface buffer,int fbo)
-    {
-    GLES31.glViewport(0, 0, mWidth, mHeight);
-    setAsOutput(currTime);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
-
-    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-    GLES31.glStencilMask(0x00);
-
-    Distorted.blitDepthPriv(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
-
-    // clear buffers
-    GLES31.glStencilMask(0xff);
-    GLES31.glDepthMask(true);
-    GLES31.glColorMask(true,true,true,true);
-    GLES31.glClearColor(buffer.mClearR,buffer.mClearG,buffer.mClearB,buffer.mClearA);
-    GLES31.glClearDepthf(buffer.mClearDepth);
-    GLES31.glClearStencil(buffer.mClearStencil);
-
-    buffer.setAsOutput();
-    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo+1], 0);
-    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
-    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo  ], 0);
-    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private static void oitClear(DistortedOutputSurface buffer)
-    {
-    int counter = Distorted.zeroOutAtomic();
-    Distorted.oitClear(buffer,counter);
-    GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private int oitBuild(long time, DistortedOutputSurface buffer, int fbo)
-    {
-    GLES31.glViewport(0, 0, mWidth, mHeight);
-    setAsOutput(time);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
-
-    DistortedRenderState.colorDepthStencilOn();
-    DistortedRenderState.enableDepthTest();
-
-    Distorted.oitBuild(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
-    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
-    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
-
-    DistortedRenderState.colorDepthStencilRestore();
-    DistortedRenderState.restoreDepthTest();
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// two phases: 1. collapse the SSBO 2. blend the ssbo's color
-
-  private int oitRender(long currTime, int fbo)
-    {
-    float corrW = getWidthCorrection();
-    float corrH = getHeightCorrection();
-
-    // Do the Collapse Pass only if we do have a Depth attachment.
-    // Otherwise there's no point (in fact we then would create a feedback loop!)
-
-    if( mDepthStencilH[fbo] != 0 )
-      {
-      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
-      GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
-      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mDepthStencilH[fbo]);
-      DistortedRenderState.switchOffColorDepthStencil();
-      Distorted.oitCollapse(this, corrW, corrH);
-      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
-      }
-
-    setAsOutput(currTime);
-    DistortedRenderState.switchColorDepthOnStencilOff();
-    Distorted.oitRender(this, corrW, corrH);
-    DistortedRenderState.restoreColorDepthStencil();
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  private void clear()
-    {
-    DistortedRenderState.colorDepthStencilOn();
-    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
-    GLES31.glClearDepthf(mClearDepth);
-    GLES31.glClearStencil(mClearStencil);
-    GLES31.glClear(mClear);
-    DistortedRenderState.colorDepthStencilRestore();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void setCurrFBO(int fbo)
-    {
-    mCurrFBO = fbo;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Render all children, one by one. If there are no postprocessing effects, just render to THIS.
-// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
-// to a whole buffer (lastQueue.postprocess) and merge it (this.oitBuild or blitWithDepth - depending
-// on the type of rendering)
-
-  int renderChildren(long time, int numChildren, DistortedChildrenList children, int fbo, boolean oit)
-    {
-    int numRenders=0, bucketChange=0;
-    DistortedNode child;
-    DistortedFramebuffer buffer=null;
-    EffectQueuePostprocess lastQueue=null, currQueue;
-    long lastBucket=0, currBucket;
-    boolean renderDirectly=false;
-
-    setCurrFBO(fbo);
-
-    if( mBuffer!=null )
-      {
-      for (int i=0; i<EffectQuality.LENGTH; i++) mBuffer[i].setCurrFBO(fbo);
-      }
-
-    if( oit && numChildren>0 )
-      {
-      oitClear(this);
-      }
-
-    for(int i=0; i<numChildren; i++)
-      {
-      child = children.getChild(i);
-      currQueue = (EffectQueuePostprocess)child.getEffects().getQueues()[3];
-      currBucket= currQueue.getID();
-
-      if( currBucket==0 )
-        {
-        setAsOutput(time);
-
-        if( oit )
-          {
-          numRenders += child.drawOIT(time, this);
-          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-          }
-        else
-          {
-          numRenders += child.draw(time, this);
-          }
-        }
-      else
-        {
-        if( mBuffer==null )
-          {
-          createPostprocessingBuffers(mWidth,mHeight,mNear);
-          for (int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].setCurrFBO(fbo);
-          }
-
-        if( lastBucket!=currBucket )
-          {
-          if( lastBucket==0 )
-            {
-            clonePostprocessingViewportAndProjection(this);
-            }
-          else
-            {
-            for(int j=bucketChange; j<i; j++) numRenders += lastQueue.preprocess( buffer,children.getChild(j), buffer.mDistance, buffer.mMipmap, buffer.mProjectionMatrix );
-            numRenders += lastQueue.postprocess(buffer);
-
-            if( oit )
-              {
-              numRenders += oitBuild(time, buffer, fbo);
-              GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-              }
-            else
-              {
-              numRenders += blitWithDepth(time, buffer, fbo);
-              }
-            buffer.clearBuffer(fbo);
-            }
-
-          buffer= mBuffer[currQueue.getQuality()];
-          bucketChange= i;
-          renderDirectly = currQueue.getRender();
-          }
-
-        if( renderDirectly )
-          {
-          setAsOutput(time);
-
-          if( oit )
-            {
-            numRenders += child.drawOIT(time, this);
-            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-            }
-          else
-            {
-            numRenders += child.draw(time, this);
-            }
-          }
-        else
-          {
-          buffer.setAsOutput(time);
-          child.drawNoBlend(time, buffer);
-          }
-
-        if( i==numChildren-1 )
-          {
-          for(int j=bucketChange; j<numChildren; j++) numRenders += currQueue.preprocess( buffer,children.getChild(j), buffer.mDistance, buffer.mMipmap, buffer.mProjectionMatrix );
-          numRenders += currQueue.postprocess(buffer);
-
-          if( oit )
-            {
-            numRenders += oitBuild(time, buffer, fbo);
-            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-            buffer.clearBuffer(fbo);
-            }
-          else
-            {
-            numRenders += blitWithDepth(time, buffer,fbo);
-            }
-          }
-        } // end else (postprocessed child)
-
-      lastQueue = currQueue;
-      lastBucket= currBucket;
-      } // end main for loop
-
-    if( oit && numChildren>0 )
-      {
-      numRenders += oitRender(time, fbo);  // merge the OIT linked list
-      }
-
-    return numRenders;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Not part of the public API.
- *
- * @y.exclude
- */
-  public void adjustIsomorphism() { }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Not part of the Public API.
- *
- * @y.exclude
- */
-  public float getWidthCorrection()
-    {
-    return (float)mWidth/mRealWidth;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Not part of the Public API.
- *
- * @y.exclude
- */
-  public float getHeightCorrection()
-    {
-    return (float)mHeight/mRealHeight;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void clearBuffer(int fbo)
-    {
-    DistortedRenderState.colorDepthStencilOn();
-
-    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
-    GLES31.glClearDepthf(mClearDepth);
-    GLES31.glClearStencil(mClearStencil);
-
-    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
-    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[2*fbo+1], 0);
-    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
-    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[2*fbo  ], 0);
-    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
-
-    DistortedRenderState.colorDepthStencilRestore();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void setAsOutput(long time)
-    {
-    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
-
-    if( mTime[mCurrFBO]!=time )
-      {
-      mTime[mCurrFBO] = time;
-      clear();
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Draws all the attached children to this OutputSurface's 0th FBO.
- * <p>
- * Must be called from a thread holding OpenGL Context.
- *
- * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
- * @return Number of objects rendered.
- */
-  public int render(long time)
-    {
-    return render(time,0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Draws all the attached children to this OutputSurface.
- * <p>
- * Must be called from a thread holding OpenGL Context.
- *
- * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
- * @param fbo The surface can have many FBOs backing it up - render this to FBO number 'fbo'.
- * @return Number of objects rendered.
- */
-  public int render(long time, int fbo)
-    {
-    DistortedMaster.toDo();
-    toDo();
-    DistortedRenderState.reset();
-
-    int numRenders=0, numChildren = mChildren.getNumChildren();
-    DistortedNode node;
-    long oldBucket=0, newBucket;
-
-    for(int i=0; i<numChildren; i++)
-      {
-      node = mChildren.getChild(i);
-      newBucket = node.getBucket();
-      numRenders += node.renderRecursive(time);
-      if( newBucket<oldBucket ) mChildren.rearrangeByBuckets(i,newBucket);
-      else oldBucket=newBucket;
-      }
-
-    numRenders += renderChildren(time,numChildren,mChildren,fbo, mRenderWayOIT);
-
-    return numRenders;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Bind this Surface as a Framebuffer we can render to.
- * <p>
- * This version does not attempt to clear anything.
- */
-  public void setAsOutput()
-    {
-    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the Near plane of the Projection included in the Surface.
- *
- * @return the Near plane.
- */
-  public float getNear()
-    {
-    return mNear;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Set mipmap level.
- * <p>
- * Trick for speeding up your renders - one can create a pyramid of OutputSurface objects, each next
- * one some constant FACTOR smaller than the previous (0.5 is the common value), then set the Mipmap
- * Level of the i-th object to be FACTOR^i (we start counting from 0). When rendering any scene into
- * such prepared OutputSurface, the library will make sure to scale any Effects used so that the end
- * scene will end up looking identical no matter which object we render to. Identical, that is, except
- * for the loss of quality and gain in speed associated with rendering to a smaller Surface.
- * <p>
- * Example: if you create two FBOs, one 1000x1000 and another 500x500 in size, and set the second one
- * mipmap to 0.5 (the first one's is 1.0 by default), define Effects to be a single move by (100,100),
- * and render a skinned Mesh into both FBO, the end result will look proportionally the same, because
- * in the second case the move vector (100,100) will be auto-scaled to (50,50).
- *
- * @param mipmap The mipmap level. Acceptable range: 0&lt;mipmap&lt;infinity, although mipmap&gt;1
- *               does not make any sense (that would result in loss of speed and no gain in quality)
- */
-  public void setMipmap(float mipmap)
-    {
-    mMipmap = mipmap;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Set the (R,G,B,A) values of GLES31.glClearColor() to set up color with which to clear
- * this Surface at the beginning of each frame.
- *
- * @param r the Red component. Default: 0.0f
- * @param g the Green component. Default: 0.0f
- * @param b the Blue component. Default: 0.0f
- * @param a the Alpha component. Default: 0.0f
- */
-  public void glClearColor(float r, float g, float b, float a)
-    {
-    mClearR = r;
-    mClearG = g;
-    mClearB = b;
-    mClearA = a;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Uses glClearDepthf() to set up a value with which to clear
- * the Depth buffer of our Surface at the beginning of each frame.
- *
- * @param d the Depth. Default: 1.0f
- */
-  public void glClearDepthf(float d)
-    {
-    mClearDepth = d;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Uses glClearStencil() to set up a value with which to clear the
- * Stencil buffer of our Surface at the beginning of each frame.
- *
- * @param s the Stencil. Default: 0
- */
-  public void glClearStencil(int s)
-    {
-    mClearStencil = s;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Which buffers to Clear at the beginning of each frame?
- * <p>
- * Valid values: 0, or bitwise OR of one or more values from the set GL_COLOR_BUFFER_BIT,
- *               GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
- * Default: GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT.
- *
- * @param mask bitwise OR of BUFFER_BITs to clear.
- */
-  public void glClear(int mask)
-    {
-    mClear = mask;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Create new Projection matrix.
- *
- * @param fov Vertical 'field of view' of the Projection frustrum (in degrees).
- *            Valid values: 0<=fov<180. FOV==0 means 'parallel projection'.
- * @param near Distance between the screen plane and the near plane.
- *             Valid vaules: 0<near<1. When near==0 (illegal!), the Near Plane is exactly at the tip of
- *             the pyramid. When near==1 (illegal!) the near plane is equivalent to the screen plane.
- */
-  public void setProjection(float fov, float near)
-    {
-    if( fov < 180.0f && fov >=0.0f )
-      {
-      mFOV = fov;
-      }
-
-    if( near<   1.0f && near> 0.0f )
-      {
-      mNear= near;
-      }
-    else if( near<=0.0f )
-      {
-      mNear = 0.01f;
-      }
-    else if( near>=1.0f )
-      {
-      mNear=0.99f;
-      }
-
-    if( mBuffer!=null )
-      {
-      for(int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].mNear = mNear;
-      }
-
-    createProjection();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the vertical field of view angle.
- *
- * @return Vertival Field of View Angle, in degrees.
- */
-  public float getFOV()
-    {
-    return mFOV;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Resize the underlying Framebuffer.
- * <p>
- * This method can be safely called mid-render as it doesn't interfere with rendering.
- *
- * @param width The new width.
- * @param height The new height.
- */
-  public void resize(int width, int height)
-    {
-    if( mWidth!=width || mHeight!=height )
-      {
-      mWidth = mRealWidth = width;
-      mHeight= mRealHeight= height;
-
-      createProjection();
-
-      if( mColorCreated==CREATED )
-        {
-        markForCreation();
-        recreate();
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return true if the Surface contains a DEPTH attachment.
- *
- * @return <bold>true</bold> if the Surface contains a DEPTH attachment.
- */
-  public boolean hasDepth()
-    {
-    return mDepthStencilCreated==CREATED;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return true if the Surface contains a STENCIL attachment.
- *
- * @return <bold>true</bold> if the Surface contains a STENCIL attachment.
- */
-  public boolean hasStencil()
-    {
-    return (mDepthStencilCreated==CREATED && mDepthStencil==BOTH_DEPTH_STENCIL);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * When rendering this Node, should we use the Order Independent Transparency render more?
- * <p>
- * There are two modes of rendering: the fast 'normal' way, which however renders transparent
- * fragments in different ways depending on which fragments get rendered first, or the slower
- * 'oit' way, which renders transparent fragments correctly regardless of their order.
- *
- * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
- */
-  public void setOrderIndependentTransparency(boolean oit)
-    {
-    mRenderWayOIT = oit;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * When rendering this Node, should we use the Order Independent Transparency render more?
- * <p>
- * There are two modes of rendering: the fast 'normal' way, which however renders transparent
- * fragments in different ways depending on which fragments get rendered first, or the slower
- * 'oit' way, which renders transparent fragments correctly regardless of their order.
- *
- * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
- * @param initialSize Initial number of transparent fragments we expect, in screenfuls.
- *                    I.e '1.0' means 'the scene we are going to render contains about 1 screen
- *                    worth of transparent fragments'. Valid values: 0.0 &lt; initialSize &lt; 10.0
- *                    Even if you get this wrong, the library will detect that there are more
- *                    transparent fragments than it has space for and readjust its internal buffers,
- *                    but only after a few frames during which one will probably see missing objects.
- */
-public void setOrderIndependentTransparency(boolean oit, float initialSize)
-  {
-  mRenderWayOIT = oit;
-
-  if( initialSize>0.0f && initialSize<10.0f )
-    Distorted.setSSBOSize(initialSize);
-  }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Adds a new child to the last position in the list of our Surface's children.
- * <p>
- * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
- *
- * @param node The new Node to add.
- */
-  public void attach(DistortedNode node)
-    {
-    mChildren.attach(node);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Adds a new child to the last position in the list of our Surface's children.
- * <p>
- * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
- *
- * @param surface InputSurface to initialize our child Node with.
- * @param effects DistortedEffects to initialize our child Node with.
- * @param mesh MeshBase to initialize our child Node with.
- * @return the newly constructed child Node, or null if we couldn't allocate resources.
- */
-  public DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
-    {
-    return mChildren.attach(surface,effects,mesh);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Removes the first occurrence of a specified child from the list of children of our Surface.
- * <p>
- * A bit questionable method as there can be many different Nodes attached as children, some
- * of them having the same Effects but - for instance - different Mesh. Use with care.
- * <p>
- * We cannot do this mid-render - actual detachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
- *
- * @param effects DistortedEffects to remove.
- */
-  public void detach(DistortedEffects effects)
-    {
-    mChildren.detach(effects);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Removes the first occurrence of a specified child from the list of children of our Surface.
- * <p>
- * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
- *
- * @param node The Node to remove.
- */
-  public void detach(DistortedNode node)
-    {
-    mChildren.detach(node);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Removes all children Nodes.
- * <p>
- * We cannot do this mid-render - actual attachment will be done just before the next render, by the
- * DistortedMaster (by calling doWork())
- */
-  public void detachAll()
-    {
-    mChildren.detachAll();
-    }
-}
diff --git a/src/main/java/org/distorted/library/main/DistortedRenderState.java b/src/main/java/org/distorted/library/main/DistortedRenderState.java
deleted file mode 100644
index e67f1b4..0000000
--- a/src/main/java/org/distorted/library/main/DistortedRenderState.java
+++ /dev/null
@@ -1,867 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import android.opengl.GLES31;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Remember the OpenGL state.
- * <p>
- * This is a member of DistortedNode. Remembers the OpenGL state we want to set just before rendering
- * the Node.
- * <p>
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-public class DistortedRenderState
-{
-  // TODO: figure this out dynamically; this assumes 8 bit stencil buffer.
-  private static final int STENCIL_MASK = (1<<8)-1;
-
-  private static class RenderState
-    {
-    private int colorMaskR, colorMaskG, colorMaskB, colorMaskA;
-    private int depthMask;
-    private int stencilMask;
-    private int depthTest;
-    private int stencilTest;
-    private int stencilFuncFunc, stencilFuncRef, stencilFuncMask;
-    private int stencilOpSfail, stencilOpDpfail, stencilOpDppass;
-    private int depthFunc;
-    private int blend;
-    private int blendSrc, blendDst;
-    }
-
-  private RenderState mState;          // state the current object wants to have
-  static private RenderState cState = new RenderState();   // current OpenGL Stave
-  static private RenderState sState = new RenderState();   // saved OpenGL state
-
-  private int mClear;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// default: color writes on, depth test and writes on, blending on, stencil off.
-
-  DistortedRenderState()
-    {
-    mState = new RenderState();
-
-    mState.colorMaskR = 1;
-    mState.colorMaskG = 1;
-    mState.colorMaskB = 1;
-    mState.colorMaskA = 1;
-
-    mState.depthTest  = 1;
-    mState.depthMask  = 1;
-    mState.depthFunc  = GLES31.GL_LEQUAL;
-
-    mState.blend      = 1;
-    mState.blendSrc   = GLES31.GL_SRC_ALPHA;
-    mState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
-
-    mState.stencilTest     = 0;
-    mState.stencilMask     = STENCIL_MASK;
-    mState.stencilFuncFunc = GLES31.GL_NEVER;
-    mState.stencilFuncRef  = 0;
-    mState.stencilFuncMask = STENCIL_MASK;
-    mState.stencilOpSfail  = GLES31.GL_KEEP;
-    mState.stencilOpDpfail = GLES31.GL_KEEP;
-    mState.stencilOpDppass = GLES31.GL_KEEP;
-
-    mClear = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// reset state of everything to a known state.
-
-  static void reset()
-    {
-    cState.colorMaskR = 1;
-    cState.colorMaskG = 1;
-    cState.colorMaskB = 1;
-    cState.colorMaskA = 1;
-    GLES31.glColorMask(true,true,true,true);
-
-    cState.depthTest = 1;
-    cState.depthMask = 1;
-    cState.depthFunc = GLES31.GL_LEQUAL;
-    GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-    GLES31.glDepthMask(true);
-    GLES31.glDepthFunc(cState.depthFunc);
-
-    cState.stencilTest     = 0;
-    cState.stencilMask     = STENCIL_MASK;
-    cState.stencilFuncFunc = GLES31.GL_NEVER;
-    cState.stencilFuncRef  = 0;
-    cState.stencilFuncMask = STENCIL_MASK;
-    cState.stencilOpSfail  = GLES31.GL_KEEP;
-    cState.stencilOpDpfail = GLES31.GL_KEEP;
-    cState.stencilOpDppass = GLES31.GL_KEEP;
-    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-    GLES31.glStencilMask(cState.stencilMask);
-
-    cState.blend      = 1;
-    cState.blendSrc   = GLES31.GL_SRC_ALPHA;
-    cState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
-    GLES31.glEnable(GLES31.GL_BLEND);
-    GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void colorDepthStencilOn()
-    {
-    sState.colorMaskR = cState.colorMaskR;
-    sState.colorMaskG = cState.colorMaskG;
-    sState.colorMaskB = cState.colorMaskB;
-    sState.colorMaskA = cState.colorMaskA;
-
-    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
-      {
-      cState.colorMaskR = 1;
-      cState.colorMaskG = 1;
-      cState.colorMaskB = 1;
-      cState.colorMaskA = 1;
-      GLES31.glColorMask(true,true,true,true);
-      }
-
-    sState.depthMask = cState.depthMask;
-
-    if( cState.depthMask!=1 )
-      {
-      cState.depthMask = 1;
-      GLES31.glDepthMask(true);
-      }
-
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilMask!= STENCIL_MASK )
-      {
-      cState.stencilMask = STENCIL_MASK;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void colorDepthStencilRestore()
-    {
-    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
-      {
-      cState.colorMaskR = sState.colorMaskR;
-      cState.colorMaskG = sState.colorMaskG;
-      cState.colorMaskB = sState.colorMaskB;
-      cState.colorMaskA = sState.colorMaskA;
-      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
-      }
-    if( sState.depthMask!=cState.depthMask )
-      {
-      cState.depthMask = sState.depthMask;
-      GLES31.glDepthMask(cState.depthMask==1);
-      }
-    if( sState.stencilMask!=cState.stencilMask )
-      {
-      cState.stencilMask = sState.stencilMask;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void disableBlending()
-    {
-    sState.blend = cState.blend;
-
-    if (cState.blend != 0)
-      {
-      cState.blend = 0;
-      GLES31.glDisable(GLES31.GL_BLEND);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void restoreBlending()
-    {
-    if (sState.blend != cState.blend)
-      {
-      cState.blend = sState.blend;
-
-      if (cState.blend == 0)
-        {
-        GLES31.glDisable(GLES31.GL_BLEND);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_BLEND);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void enableDepthTest()
-    {
-    sState.depthTest = cState.depthTest;
-
-    if (cState.depthTest != 1)
-      {
-      cState.depthTest = 1;
-      GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void restoreDepthTest()
-    {
-    if (sState.depthTest != cState.depthTest)
-      {
-      cState.depthTest = sState.depthTest;
-
-      if (cState.depthTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void switchOffDrawing()
-    {
-    GLES31.glEnable(GLES31.GL_SCISSOR_TEST);
-    GLES31.glScissor(0,0,0,0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void restoreDrawing()
-    {
-    GLES31.glDisable(GLES31.GL_SCISSOR_TEST);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void switchOffColorDepthStencil()
-    {
-    sState.stencilTest = cState.stencilTest;
-
-    if( cState.stencilTest!=0 )
-      {
-      cState.stencilTest = 0;
-      //android.util.Log.d("State", "stencil test off");
-      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-      }
-
-    sState.depthTest = cState.depthTest;
-
-    if( cState.depthTest!=0 )
-      {
-      cState.depthTest = 0;
-      //android.util.Log.d("State", "depth test off");
-      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-      }
-
-    sState.colorMaskR = cState.colorMaskR;
-    sState.colorMaskG = cState.colorMaskG;
-    sState.colorMaskB = cState.colorMaskB;
-    sState.colorMaskA = cState.colorMaskA;
-
-    if( cState.colorMaskR!=0 || cState.colorMaskG!=0 || cState.colorMaskB!=0 || cState.colorMaskA!=0 )
-      {
-      cState.colorMaskR = 0;
-      cState.colorMaskG = 0;
-      cState.colorMaskB = 0;
-      cState.colorMaskA = 0;
-      //android.util.Log.d("State", "switch off color writing");
-      GLES31.glColorMask(false,false,false,false);
-      }
-
-    sState.depthMask = cState.depthMask;
-
-    if( cState.depthMask!=0 )
-      {
-      cState.depthMask = 0;
-      //android.util.Log.d("State", "switch off depth writing");
-      GLES31.glDepthMask(false);
-      }
-
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilMask!= 0x00 )
-      {
-      cState.stencilMask = 0x00;
-      //android.util.Log.d("State", "stencil mask off");
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void switchColorDepthOnStencilOff()
-    {
-    sState.stencilTest = cState.stencilTest;
-
-    if( cState.stencilTest!=0 )
-      {
-      cState.stencilTest = 0;
-      //android.util.Log.d("State", "stencil test off");
-      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-      }
-
-    sState.depthTest = cState.depthTest;
-
-    if( cState.depthTest!=0 )
-      {
-      cState.depthTest = 0;
-      //android.util.Log.d("State", "depth test off");
-      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-      }
-
-    sState.colorMaskR = cState.colorMaskR;
-    sState.colorMaskG = cState.colorMaskG;
-    sState.colorMaskB = cState.colorMaskB;
-    sState.colorMaskA = cState.colorMaskA;
-
-    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
-      {
-      cState.colorMaskR = 1;
-      cState.colorMaskG = 1;
-      cState.colorMaskB = 1;
-      cState.colorMaskA = 1;
-      //android.util.Log.d("State", "switch on color writing");
-      GLES31.glColorMask(true,true,true,true);
-      }
-
-    sState.depthMask = cState.depthMask;
-
-    if( cState.depthMask!=1 )
-      {
-      cState.depthMask = 1;
-      //android.util.Log.d("State", "switch on depth writing");
-      GLES31.glDepthMask(true);
-      }
-
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilMask!= 0x00 )
-      {
-      cState.stencilMask = 0x00;
-      //android.util.Log.d("State", "stencil mask off");
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  static void restoreColorDepthStencil()
-    {
-    if( sState.stencilTest!=cState.stencilTest )
-      {
-      cState.stencilTest = sState.stencilTest;
-
-      if (cState.stencilTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-        }
-      }
-    if( sState.depthTest!=cState.depthTest )
-      {
-      cState.depthTest = sState.depthTest;
-
-      if (cState.depthTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-        }
-      }
-    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
-      {
-      cState.colorMaskR = sState.colorMaskR;
-      cState.colorMaskG = sState.colorMaskG;
-      cState.colorMaskB = sState.colorMaskB;
-      cState.colorMaskA = sState.colorMaskA;
-      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
-      }
-    if( sState.depthMask!=cState.depthMask )
-      {
-      cState.depthMask = sState.depthMask;
-      GLES31.glDepthMask(cState.depthMask==1);
-      }
-    if( sState.stencilMask!=cState.stencilMask )
-      {
-      cState.stencilMask = sState.stencilMask;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void setUpStencilMark(boolean color)
-    {
-    sState.stencilTest = cState.stencilTest;
-
-    if( cState.stencilTest!=1 )
-      {
-      cState.stencilTest = 1;
-      //android.util.Log.d("State", "stencil test on");
-      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-      }
-
-    sState.stencilFuncFunc = cState.stencilFuncFunc;
-    sState.stencilFuncRef  = cState.stencilFuncRef;
-    sState.stencilFuncMask = cState.stencilFuncMask;
-
-    if( cState.stencilFuncFunc!=GLES31.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
-      {
-      cState.stencilFuncFunc = GLES31.GL_ALWAYS;
-      cState.stencilFuncRef  = 1;
-      cState.stencilFuncMask = STENCIL_MASK;
-      //android.util.Log.d("State", "stencil func on");
-      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
-      }
-
-    sState.stencilOpSfail = cState.stencilOpSfail;
-    sState.stencilOpDpfail= cState.stencilOpDpfail;
-    sState.stencilOpDppass= cState.stencilOpDppass;
-
-    if( cState.stencilOpSfail!=GLES31.GL_KEEP || cState.stencilOpDpfail!=GLES31.GL_KEEP || cState.stencilOpDppass!=GLES31.GL_REPLACE )
-      {
-      cState.stencilOpSfail = GLES31.GL_KEEP;
-      cState.stencilOpDpfail= GLES31.GL_KEEP;
-      cState.stencilOpDppass= GLES31.GL_REPLACE;
-      //android.util.Log.d("State", "stencil op on");
-      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
-      }
-
-    sState.colorMaskR = cState.colorMaskR;
-    sState.colorMaskG = cState.colorMaskG;
-    sState.colorMaskB = cState.colorMaskB;
-    sState.colorMaskA = cState.colorMaskA;
-
-    int clr = color ? 1:0;
-
-    if( cState.colorMaskR!=clr || cState.colorMaskG!=clr || cState.colorMaskB!=clr || cState.colorMaskA!=clr )
-      {
-      cState.colorMaskR = clr;
-      cState.colorMaskG = clr;
-      cState.colorMaskB = clr;
-      cState.colorMaskA = clr;
-      //android.util.Log.d("State", "switch off color writing");
-      GLES31.glColorMask(color,color,color,color);
-      }
-
-    sState.depthMask = cState.depthMask;
-
-    if( cState.depthMask!=1 )
-      {
-      cState.depthMask = 1;
-      //android.util.Log.d("State", "switch on depth writing");
-      GLES31.glDepthMask(true);
-      }
-
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilMask!= STENCIL_MASK )
-      {
-      cState.stencilMask = STENCIL_MASK;
-      //android.util.Log.d("State", "stencil mask on");
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static void unsetUpStencilMark()
-    {
-    if( sState.stencilTest!=cState.stencilTest )
-      {
-      cState.stencilTest = sState.stencilTest;
-
-      if (cState.stencilTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-        }
-      }
-    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
-      {
-      cState.colorMaskR = sState.colorMaskR;
-      cState.colorMaskG = sState.colorMaskG;
-      cState.colorMaskB = sState.colorMaskB;
-      cState.colorMaskA = sState.colorMaskA;
-      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
-      }
-    if( sState.depthMask!=cState.depthMask )
-      {
-      cState.depthMask = sState.depthMask;
-      GLES31.glDepthMask(cState.depthMask==1);
-      }
-    if( sState.stencilMask!=cState.stencilMask )
-      {
-      cState.stencilMask = sState.stencilMask;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-  public static void useStencilMark()
-    {
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilTest!=1 )
-      {
-      cState.stencilTest = 1;
-      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-      }
-
-    sState.stencilFuncFunc = cState.stencilFuncFunc;
-    sState.stencilFuncRef  = cState.stencilFuncRef;
-    sState.stencilFuncMask = cState.stencilFuncMask;
-
-    if( cState.stencilFuncFunc!=GLES31.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
-      {
-      cState.stencilFuncFunc = GLES31.GL_EQUAL;
-      cState.stencilFuncRef  = 1;
-      cState.stencilFuncMask = STENCIL_MASK;
-      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
-      }
-
-    sState.stencilMask = cState.stencilMask;
-
-    if( cState.stencilMask!= 0x00 )
-      {
-      cState.stencilMask = 0x00;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-
-    sState.depthMask = cState.depthMask;
-
-    if( cState.depthMask!=0 )
-      {
-      cState.depthMask = 0;
-      GLES31.glDepthMask(false);
-      }
-
-    sState.depthTest = cState.depthTest;
-
-    if( cState.depthTest!=0 )
-      {
-      cState.depthTest = 0;
-      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Only for use by the library itself.
- *
- * @y.exclude
- */
-  public static void unuseStencilMark()
-    {
-    if( sState.stencilTest!=cState.stencilTest )
-      {
-      cState.stencilTest = sState.stencilTest;
-
-      if (cState.stencilTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-        }
-      }
-    if( sState.stencilFuncFunc!=cState.stencilFuncFunc || sState.stencilFuncRef!=cState.stencilFuncRef || sState.stencilFuncMask!=cState.stencilFuncMask )
-      {
-      cState.stencilFuncFunc = sState.stencilFuncFunc;
-      cState.stencilFuncRef  = sState.stencilFuncRef ;
-      cState.stencilFuncMask = sState.stencilFuncMask;
-      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
-      }
-    if( sState.stencilMask!=cState.stencilMask )
-      {
-      cState.stencilMask = sState.stencilMask;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-    if( sState.depthMask!=cState.depthMask )
-      {
-      cState.depthMask = sState.depthMask;
-      GLES31.glDepthMask(cState.depthMask==1);
-      }
-    if( sState.depthTest!=cState.depthTest )
-      {
-      cState.depthTest = sState.depthTest;
-
-      if (cState.depthTest == 0)
-        {
-        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-        }
-      else
-        {
-        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-        }
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void apply()
-    {
-    //android.util.Log.e("State", "APPLYING STATE");
-
-    /////////////////////////////////////////////////////
-    // 1. Write to color buffer?
-    if( mState.colorMaskR!=cState.colorMaskR || mState.colorMaskG!=cState.colorMaskG || mState.colorMaskB!=cState.colorMaskB || mState.colorMaskA!=cState.colorMaskA)
-      {
-      //android.util.Log.d("State", "setting color mask");
-      cState.colorMaskR = mState.colorMaskR;
-      cState.colorMaskG = mState.colorMaskG;
-      cState.colorMaskB = mState.colorMaskB;
-      cState.colorMaskA = mState.colorMaskA;
-      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
-      }
-
-    /////////////////////////////////////////////////////
-    // 2. Enable Depth test?
-    if( mState.depthTest!=cState.depthTest )
-      {
-      cState.depthTest = mState.depthTest;
-
-      if (cState.depthTest == 0)
-        {
-        //android.util.Log.d("State", "disabling depth test");
-        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-        }
-      else
-        {
-        //android.util.Log.d("State", "enable depth test");
-        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
-        }
-      }
-
-    /////////////////////////////////////////////////////
-    // 3. Change Depth Function?
-    if( mState.depthFunc!=cState.depthFunc )
-      {
-      //android.util.Log.d("State", "setting depth func");
-      cState.depthFunc = mState.depthFunc;
-      GLES31.glDepthFunc(cState.depthFunc);
-      }
-
-    /////////////////////////////////////////////////////
-    // 4. Write to Depth buffer?
-    if( mState.depthMask!=cState.depthMask )
-      {
-      //android.util.Log.d("State", "setting depth mask");
-      cState.depthMask = mState.depthMask;
-      GLES31.glDepthMask(cState.depthMask==1);
-      }
-
-    /////////////////////////////////////////////////////
-    // 5. Enable Blending?
-    if( mState.blend!=cState.blend )
-      {
-      cState.blend = mState.blend;
-
-      if (cState.blend == 0)
-        {
-        //android.util.Log.d("State", "disabling blending");
-        GLES31.glDisable(GLES31.GL_BLEND);
-        }
-      else
-        {
-        //android.util.Log.d("State", "enabling blending");
-        GLES31.glEnable(GLES31.GL_BLEND);
-        }
-      }
-
-    /////////////////////////////////////////////////////
-    // 6. Change Blend function?
-    if( mState.blendSrc!=cState.blendSrc || mState.blendDst!=cState.blendDst )
-      {
-      //android.util.Log.d("State", "setting blend function");
-      cState.blendSrc = mState.blendSrc;
-      cState.blendDst = mState.blendDst;
-      GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
-      }
-
-    /////////////////////////////////////////////////////
-    // 7. Enable/Disable Stencil Test?
-    if( mState.stencilTest!=cState.stencilTest )
-      {
-      cState.stencilTest = mState.stencilTest;
-
-      if (cState.stencilTest == 0)
-        {
-        //android.util.Log.d("State", "disabling stencil test");
-        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-        }
-      else
-        {
-        //android.util.Log.d("State", "enabling stencil test");
-        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
-        }
-      }
-
-    /////////////////////////////////////////////////////
-    // 8. Adjust Stencil function?
-    if( mState.stencilFuncFunc!=cState.stencilFuncFunc || mState.stencilFuncRef!=cState.stencilFuncRef || mState.stencilFuncMask!=cState.stencilFuncMask )
-      {
-      //android.util.Log.d("State", "setting stencil function");
-      cState.stencilFuncFunc = mState.stencilFuncFunc;
-      cState.stencilFuncRef  = mState.stencilFuncRef ;
-      cState.stencilFuncMask = mState.stencilFuncMask;
-      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
-      }
-
-    /////////////////////////////////////////////////////
-    // 9. Adjust Stencil operation?
-    if( mState.stencilOpSfail!=cState.stencilOpSfail || mState.stencilOpDpfail!=cState.stencilOpDpfail || mState.stencilOpDppass!=cState.stencilOpDppass )
-      {
-      //android.util.Log.d("State", "setting stencil op");
-      cState.stencilOpSfail = mState.stencilOpSfail;
-      cState.stencilOpDpfail= mState.stencilOpDpfail;
-      cState.stencilOpDppass= mState.stencilOpDppass;
-      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
-      }
-
-    /////////////////////////////////////////////////////
-    // 10. Write to Stencil buffer?
-    if( mState.stencilMask!=cState.stencilMask )
-      {
-      //android.util.Log.d("State", "setting stencil mask");
-      cState.stencilMask = mState.stencilMask;
-      GLES31.glStencilMask(cState.stencilMask);
-      }
-
-    /////////////////////////////////////////////////////
-    // 11. Clear buffers?
-    if( mClear!=0 )
-      {
-      //android.util.Log.d("State", "clearing buffer");
-      GLES31.glClear(mClear);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glColorMask(boolean r, boolean g, boolean b, boolean a)
-    {
-    mState.colorMaskR = (r ? 1:0);
-    mState.colorMaskG = (g ? 1:0);
-    mState.colorMaskB = (b ? 1:0);
-    mState.colorMaskA = (a ? 1:0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glDepthMask(boolean mask)
-    {
-    mState.depthMask = (mask ? 1:0);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glStencilMask(int mask)
-    {
-    mState.stencilMask = mask;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glEnable(int test)
-    {
-         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 1;
-    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 1;
-    else if( test==GLES31.GL_BLEND        ) mState.blend       = 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glDisable(int test)
-    {
-         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 0;
-    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 0;
-    else if( test==GLES31.GL_BLEND        ) mState.blend       = 0;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glStencilFunc(int func, int ref, int mask)
-    {
-    mState.stencilFuncFunc = func;
-    mState.stencilFuncRef  = ref;
-    mState.stencilFuncMask = mask;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glStencilOp(int sfail, int dpfail, int dppass)
-    {
-    mState.stencilOpSfail = sfail;
-    mState.stencilOpDpfail= dpfail;
-    mState.stencilOpDppass= dppass;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glDepthFunc(int func)
-    {
-    mState.depthFunc = func;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glBlendFunc(int src, int dst)
-    {
-    mState.blendSrc = src;
-    mState.blendDst = dst;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void glClear(int mask)
-    {
-    mClear = mask;
-    }
-}
diff --git a/src/main/java/org/distorted/library/main/DistortedScreen.java b/src/main/java/org/distorted/library/main/DistortedScreen.java
index 7754a58..33165fd 100644
--- a/src/main/java/org/distorted/library/main/DistortedScreen.java
+++ b/src/main/java/org/distorted/library/main/DistortedScreen.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.main;
@@ -72,7 +72,7 @@ public class DistortedScreen extends DistortedFramebuffer
  */
   public DistortedScreen()
     {
-    super(Distorted.FBO_QUEUE_SIZE,1,BOTH_DEPTH_STENCIL, TYPE_SYST, 1,1);
+    super(DistortedLibrary.FBO_QUEUE_SIZE,1,BOTH_DEPTH_STENCIL, TYPE_SYST, 1,1);
     mShowFPS = false;
     mCurRenderedFBO = 0;
     mToBeBlittedFBO = 0;
@@ -116,7 +116,7 @@ public class DistortedScreen extends DistortedFramebuffer
 
     GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
 
-    // workaround for the Mali issues: blit the framebuffer we have computed Distorted.FBO_QUEUE_SIZE
+    // workaround for the Mali issues: blit the framebuffer we have computed DistortedLibrary.FBO_QUEUE_SIZE
     // frames ago. Looks like FBO_QUEUE_SIZE=2 solves the issue already but I decided to play it safe and
     // make it equal to 3.
     // This of course introduces a delay and uses more memory, but it does not appear to have any effect
@@ -129,19 +129,19 @@ public class DistortedScreen extends DistortedFramebuffer
     GLES31.glDisable(GLES31.GL_DEPTH_TEST);
     GLES31.glDisable(GLES31.GL_BLEND);
 
-    Distorted.blitPriv(this);
+    DistortedLibrary.blitPriv(this);
 
     if( mShowFPS && fpsTexture.setAsInput())
       {
-      Distorted.drawPriv(fpsEffects.getQueues(), FPS_W / 2.0f, FPS_H / 2.0f, fpsMesh, this, time);
+      DistortedLibrary.drawPriv(fpsEffects.getQueues(), FPS_W / 2.0f, FPS_H / 2.0f, fpsMesh, this, time);
       }
 
-    if( ++mCurRenderedFBO>=Distorted.FBO_QUEUE_SIZE )
+    if( ++mCurRenderedFBO>= DistortedLibrary.FBO_QUEUE_SIZE )
       {
       mCurRenderedFBO = 0;
       if (mFirstCircle) mFirstCircle = false;
       }
-    if( !mFirstCircle && ++mToBeBlittedFBO>=Distorted.FBO_QUEUE_SIZE )
+    if( !mFirstCircle && ++mToBeBlittedFBO>= DistortedLibrary.FBO_QUEUE_SIZE )
       {
       mToBeBlittedFBO=0;
       }
diff --git a/src/main/java/org/distorted/library/main/DistortedSurface.java b/src/main/java/org/distorted/library/main/DistortedSurface.java
deleted file mode 100644
index b69989a..0000000
--- a/src/main/java/org/distorted/library/main/DistortedSurface.java
+++ /dev/null
@@ -1,125 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.main;
-
-import android.opengl.GLES31;
-
-import org.distorted.library.mesh.MeshBase;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * This is not really part of the public API.
- *
- * @y.exclude
- */
-public abstract class DistortedSurface extends DistortedObject
-{
-  int mColorCreated;
-  int mNumColors;
-  int mNumFBOs;
-  int[] mColorH;
-  int mWidth, mHeight;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  DistortedSurface(int width, int height, int create, int numfbos, int numcolors, int type)
-    {
-    super(type);
-
-    mNumFBOs      = numfbos;
-    mNumColors    = numcolors;
-    mWidth        = width ;
-    mHeight       = height;
-    mColorCreated = create;
-
-    int total = mNumFBOs*mNumColors;
-
-    if( total>0 )
-      {
-      mColorH = new int[total];
-      for( int i=0; i<total; i++ )  mColorH[i] = 0;
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// debugging only
-
-  String printDetails()
-    {
-    return getClass().getSimpleName()+" "+mWidth+"x"+mHeight;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the width of this Surface.
- *
- * @return width of the Object, in pixels.
- */
-  public int getWidth()
-    {
-    return mWidth;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the height of this Surface.
- *
- * @return height of the Object, in pixels.
- */
-  public int getHeight()
-    {
-    return mHeight;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Return the depth of this Surface.
- * <p>
- * Admittedly quite a strange method. Why do we need to pass a Mesh to it? Because one cannot determine
- * 'depth' of a Surface (bitmap really!) when rendered based only on the texture itself, that depends
- * on the Mesh it is rendered with.
- *
- * @return depth of the Object, in pixels.
- */
-  public int getDepth(MeshBase mesh)
-    {
-    return mesh==null ? 0 : (int)(mWidth*mesh.getZFactor() );
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Bind the underlying rectangle of pixels as a OpenGL Texture.
- *
- * @return <code>true</code> if successful.
- */
-  public boolean setAsInput()
-    {
-    if( mColorH[0]>0 )
-      {
-      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
-      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
-      return true;
-      }
-
-    return false;
-    }
-}
diff --git a/src/main/java/org/distorted/library/main/DistortedTexture.java b/src/main/java/org/distorted/library/main/DistortedTexture.java
index 9bfe051..6a245a3 100644
--- a/src/main/java/org/distorted/library/main/DistortedTexture.java
+++ b/src/main/java/org/distorted/library/main/DistortedTexture.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.main;
@@ -32,7 +32,7 @@ import android.opengl.GLUtils;
  * <p>
  * Create a Texture of arbitrary size and feed some pixels to it via the setTexture() method.
  */
-public class DistortedTexture extends DistortedSurface
+public class DistortedTexture extends InternalSurface
   {
   private Bitmap mBmp;
 
diff --git a/src/main/java/org/distorted/library/main/InternalBuffer.java b/src/main/java/org/distorted/library/main/InternalBuffer.java
new file mode 100644
index 0000000..8fa1c58
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalBuffer.java
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2018 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.opengl.GLES31;
+import java.nio.Buffer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER.
+ * Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context.
+ * <p>
+ * Not part of public API, do not document (public only because has to be used in Meshes)
+ *
+ * @y.exclude
+ */
+public class InternalBuffer extends InternalObject
+  {
+  public int[] mIndex;
+
+  private int mTarget, mSize, mUsage;
+  private Buffer mBuffer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public InternalBuffer(int target, int usage)
+    {
+    super(InternalObject.TYPE_USER);
+
+    mIndex  = new int[1];
+    mTarget = target;
+    mUsage  = usage;
+    mBuffer = null;
+    mSize   = 0;
+
+    recreate();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// mark for creation only now, when we do have all data ready, in order to avoid the situation
+// when create() would be called before this.
+
+  public void setData(int size, Buffer buffer)
+    {
+    mSize   = size;
+    mBuffer = buffer;
+
+    markForCreation();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// must be called from a thread holding OpenGL Context
+
+  void create()
+    {
+    if( mIndex[0]<0 )
+      {
+      GLES31.glGenBuffers( 1, mIndex, 0);
+      GLES31.glBindBuffer( mTarget, mIndex[0]);
+      GLES31.glBufferData( mTarget, mSize, mBuffer, mUsage);
+      GLES31.glBindBuffer( mTarget, 0);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// must be called from a thread holding OpenGL Context
+
+  void delete()
+    {
+    if( mIndex[0]>=0 )
+      {
+      GLES31.glDeleteBuffers(1, mIndex, 0);
+      mIndex[0] = -1;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void recreate()
+    {
+    mIndex[0] = -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// debugging only
+
+  String printDetails()
+    {
+    return getClass().getSimpleName();
+    }
+  }
diff --git a/src/main/java/org/distorted/library/main/InternalChildrenList.java b/src/main/java/org/distorted/library/main/InternalChildrenList.java
new file mode 100644
index 0000000..81c8bf4
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalChildrenList.java
@@ -0,0 +1,258 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+package org.distorted.library.main;
+
+import org.distorted.library.mesh.MeshBase;
+
+import java.util.ArrayList;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class InternalChildrenList implements InternalMaster.Slave
+  {
+  private static final int ATTACH = 0;
+  private static final int DETACH = 1;
+  private static final int DETALL = 2;
+  private static final int SORT   = 3;
+
+  private class Job
+    {
+    int type;
+    DistortedNode node;
+
+    Job(int t, DistortedNode n)
+      {
+      type = t;
+      node = n;
+      }
+    }
+
+  private ArrayList<Job> mJobs;
+  private ArrayList<DistortedNode> mChildren;
+  private InternalChildrenList.Parent mParent;
+  private int mNumChildren;
+
+  public interface Parent
+    {
+    void adjustIsomorphism();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  InternalChildrenList(InternalChildrenList.Parent parent)
+    {
+    mParent = parent;
+    mJobs = new ArrayList<>();
+    mChildren = null;
+    mNumChildren = 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getNumChildren()
+    {
+    return mNumChildren;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  DistortedNode getChild(int index)
+    {
+    return mChildren.get(index);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void rearrangeByBuckets(int index,long bucket)
+    {
+    DistortedNode child = mChildren.remove(index);
+    int i;
+
+    for(i=0; i<index; i++)
+      {
+      if( mChildren.get(i).getBucket() > bucket ) break;
+      }
+
+    mChildren.add(i,child);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Can make this logarithmic but the typical number of children is very small anyway.
+//
+// We want to keep same buckets next to each other, while avoiding changes in order of the children
+// (if possible!) We want to keep bucket=0 (i.e. the non-postprocessed children) at the beginning.
+
+  private void addSortingByBuckets(DistortedNode newChild)
+    {
+    int i;
+    long bucket = newChild.getBucket();
+    boolean sameBucket = false;
+
+    for(i=0; i<mNumChildren; i++)
+      {
+      if( mChildren.get(i).getBucket() == bucket )
+        {
+        sameBucket=true;
+        }
+      else if( sameBucket || bucket==0 )
+        {
+        break;
+        }
+      }
+
+    mChildren.add(i,newChild);
+    mNumChildren++;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void attach(DistortedNode node)
+    {
+    mJobs.add(new Job(ATTACH,node));
+    InternalMaster.newSlave(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
+    {
+    DistortedNode node = new DistortedNode(surface,effects,mesh);
+    mJobs.add(new Job(ATTACH,node));
+    InternalMaster.newSlave(this);
+    return node;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void detach(DistortedNode node)
+    {
+    mJobs.add(new Job(DETACH,node));
+    InternalMaster.newSlave(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void detach(DistortedEffects effects)
+    {
+    long id = effects.getID();
+    DistortedNode node;
+    boolean detached = false;
+
+    for(int i=0; i<mNumChildren; i++)
+      {
+      node = mChildren.get(i);
+
+      if( node.getEffects().getID()==id )
+        {
+        detached = true;
+        mJobs.add(new Job(DETACH,node));
+        InternalMaster.newSlave(this);
+        break;
+        }
+      }
+
+    if( !detached )
+      {
+      // if we failed to detach any, it still might be the case that
+      // there's an ATTACH job that we need to cancel.
+      int num = mJobs.size();
+      Job job;
+
+      for(int i=0; i<num; i++)
+        {
+        job = mJobs.get(i);
+
+        if( job.type==ATTACH && job.node.getEffects()==effects )
+          {
+          mJobs.remove(i);
+          break;
+          }
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void detachAll()
+    {
+    mJobs.add(new Job(DETALL,null));
+    InternalMaster.newSlave(this);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * This is not really part of the public API. Has to be public only because it is a part of the
+ * DistortedSlave interface, which should really be a class that we extend here instead but
+ * Java has no multiple inheritance.
+ *
+ * @y.exclude
+ */
+  public void doWork()
+    {
+    int num = mJobs.size();
+
+    if( num>0 )
+      {
+      Job job;
+      int numChanges=0;
+
+      for(int i=0; i<num; i++)
+        {
+        job = mJobs.remove(0);
+
+        switch(job.type)
+          {
+          case ATTACH: numChanges++;
+                       if( mChildren==null ) mChildren = new ArrayList<>(2);
+                       job.node.setParent(mParent);
+                       addSortingByBuckets(job.node);
+                       break;
+          case DETACH: numChanges++;
+                       if( mNumChildren>0 && mChildren.remove(job.node) )
+                         {
+                         job.node.setParent(null);
+                         mNumChildren--;
+                         }
+                       break;
+          case DETALL: numChanges++;
+                       if( mNumChildren>0 )
+                         {
+                         DistortedNode tmp;
+
+                         for(int j=mNumChildren-1; j>=0; j--)
+                           {
+                           tmp = mChildren.remove(j);
+                           tmp.setParent(null);
+                           }
+
+                         mNumChildren = 0;
+                         }
+                       break;
+          case SORT  : mChildren.remove(job.node);
+                       addSortingByBuckets(job.node);
+                       break;
+          }
+        }
+      if( numChanges>0 ) mParent.adjustIsomorphism();
+      }
+    }
+  }
+
diff --git a/src/main/java/org/distorted/library/main/InternalMaster.java b/src/main/java/org/distorted/library/main/InternalMaster.java
new file mode 100644
index 0000000..0af9442
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalMaster.java
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import java.util.ArrayList;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * This static class handles assigning jobs to other classes. It does it once, at the beginning of
+ * each frame.
+ * <p>
+ * Not part of public API, do not document (public only because has to be used in PostprocessEffects)
+ *
+ * @y.exclude
+ */
+public class InternalMaster
+  {
+  private static ArrayList<Slave> mSlaves = new ArrayList<>();
+
+  public interface Slave
+    {
+    void doWork();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private InternalMaster()
+    {
+
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static boolean toDo()
+    {
+    Slave slave;
+    int num = mSlaves.size();
+
+    try
+      {
+      for(int i=0; i<num; i++)
+        {
+        slave = mSlaves.remove(0);
+
+        if( slave!=null ) slave.doWork();
+        }
+      }
+    catch(IndexOutOfBoundsException ie)
+      {
+      // onDestroy must have been called, ignore
+      }
+
+    return ( num>0 );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void newSlave(Slave s)
+    {
+    int num = mSlaves.size();
+    boolean found = false;
+    Slave tmp;
+
+    try
+      {
+      for(int i=0; i<num; i++)
+        {
+        tmp = mSlaves.get(i);
+
+        if( tmp==s )
+          {
+          found = true;
+          break;
+          }
+        }
+      }
+    catch(IndexOutOfBoundsException ie)
+      {
+      // onDestroy must have been called, ignore
+      }
+
+    if( !found ) mSlaves.add(s);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void onDestroy()
+    {
+    mSlaves.clear();
+    }
+  }
diff --git a/src/main/java/org/distorted/library/main/InternalNodeData.java b/src/main/java/org/distorted/library/main/InternalNodeData.java
new file mode 100644
index 0000000..8db7221
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalNodeData.java
@@ -0,0 +1,119 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * This is a member of DistortedNode. Makes sure two isomorphic Nodes only get rendered once.
+ */
+class InternalNodeData
+  {
+  private static HashMap<ArrayList<Long>, InternalNodeData> mMapNodeID = new HashMap<>();
+  private static long mNextNodeID =0;
+
+  private final ArrayList<Long> key;
+  private int numPointingNodes;
+  private long currTime;
+
+  final long ID;
+  DistortedFramebuffer mFBO;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private InternalNodeData(long id, ArrayList<Long> k)
+    {
+    ID              = id;
+    key             = k;
+    numPointingNodes= 1;
+    currTime        =-1;
+    mFBO            = null;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static synchronized void onDestroy()
+    {
+    mNextNodeID = 0;
+    mMapNodeID.clear();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  static void debugMap()
+    {
+    InternalNodeData tmp;
+
+    for(ArrayList<Long> key: mMapNodeID.keySet())
+      {
+      tmp = mMapNodeID.get(key);
+      android.util.Log.e("NodeData", "NodeID: "+tmp.ID+" <-- "+key);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static InternalNodeData returnData(ArrayList<Long> list)
+    {
+    InternalNodeData newData = mMapNodeID.get(list);
+
+    if( newData!=null )
+      {
+      newData.numPointingNodes++;
+      }
+    else
+      {
+      newData = new InternalNodeData(++mNextNodeID,list);
+      mMapNodeID.put(list,newData);
+      }
+
+    return newData;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean removeData()
+    {
+    if( --numPointingNodes==0 )
+      {
+      mMapNodeID.remove(key);
+
+      if( mFBO!=null ) return true;
+      }
+
+    return false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  boolean notRenderedYetAtThisTime(long time)
+    {
+    if( currTime!=time )
+      {
+      currTime = time;
+      return true;
+      }
+
+    return false;
+    }
+  }
diff --git a/src/main/java/org/distorted/library/main/InternalObject.java b/src/main/java/org/distorted/library/main/InternalObject.java
new file mode 100644
index 0000000..17fa013
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalObject.java
@@ -0,0 +1,260 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Any Object which gets uploaded to GPU memory and thus needs to be re-created (transparently to
+ * applications!) whenever we lose OpenGL context.
+ *
+ * Keep all objects created in a static LinkedList. The point: we need to be able to mark
+ * Objects for deletion, and delete all marked Objects later at a convenient time (that's
+ * because we can only delete from a thread that holds the OpenGL context so here we provide a
+ * framework where one is able to mark for deletion at any time and actual deletion takes place
+ * on the next render).
+*/
+abstract class InternalObject
+{
+  static final int FAILED_TO_CREATE = 1;
+  static final int NOT_CREATED_YET  = 2;
+  static final int DONT_CREATE      = 3;
+  static final int CREATED          = 4;
+
+  static final int TYPE_USER = 0;
+  static final int TYPE_TREE = 1;
+  static final int TYPE_SYST = 2;
+
+  private static final int JOB_CREATE = 0;
+  private static final int JOB_DELETE = 1;
+
+  private class Job
+    {
+    InternalObject object;
+    int action;
+
+    Job(InternalObject o, int a)
+      {
+      object = o;
+      action = a;
+      }
+    }
+
+  private static boolean mToDo = false;
+  private static LinkedList<InternalObject> mDoneList = new LinkedList<>();
+  private static HashMap<Long,Job> mToDoMap = new HashMap<>();
+  private static long mNextClientID = 0;
+  private static long mNextSystemID = 0;
+
+  private final static Object mDoneLock = new Object();
+  private final static Object mToDoLock = new Object();
+
+  private long mID;
+  private int mType;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  abstract void create();
+  abstract void delete();
+  abstract void recreate();
+  abstract String printDetails();
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// must be called from a thread holding OpenGL Context
+
+  static boolean toDo()
+    {
+    if( mToDo )
+      {
+      Job job;
+      InternalObject object;
+
+      synchronized(mToDoLock)
+        {
+        for(Long key: mToDoMap.keySet())
+          {
+          job = mToDoMap.get(key);
+          object = job.object;
+
+          if( job.action==JOB_CREATE )
+            {
+            object.create();
+            mDoneList.add(object);
+            }
+          else if( job.action==JOB_DELETE )
+            {
+            object.delete();
+            }
+          }
+
+        mToDoMap.clear();
+        mToDo = false;
+        }
+
+      return true;
+      }
+
+    return false;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void onPause()
+    {
+    InternalObject object;
+
+    synchronized(mDoneLock)
+      {
+      synchronized(mToDoLock)
+        {
+        int num = mDoneList.size();
+
+        try
+          {
+          for (int i = 0; i < num; i++)
+            {
+            object = mDoneList.removeFirst();
+            mToDoMap.put(object.mID, object.new Job(object, JOB_CREATE));
+            object.recreate();
+            }
+          }
+        catch( Exception ex )
+          {
+          // something else removed an object in the meantime; ignore
+          }
+        }
+      }
+
+    mToDo = true;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void onDestroy()
+    {
+    synchronized(mToDoLock)
+      {
+      synchronized(mDoneLock)
+        {
+        mToDoMap.clear();
+        mDoneList.clear();
+
+        mToDo = true;
+        mNextClientID = 0;
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  @SuppressWarnings("unused")
+  static void debugLists()
+    {
+    android.util.Log.e("Object", "Done list:");
+
+    for(InternalObject object : mDoneList)
+      {
+      object.print("");
+      }
+
+    android.util.Log.e("Object", "ToDo list:");
+
+    Job job;
+
+    for(Long key: mToDoMap.keySet())
+      {
+      job = mToDoMap.get(key);
+      job.object.print(job.action==JOB_CREATE ? " create":" delete");
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void print(String msg)
+    {
+    String str = "ID:"+mID;
+
+    switch(mType)
+      {
+      case TYPE_SYST: str+=" SYSTEM "; break;
+      case TYPE_USER: str+=" USER   "; break;
+      case TYPE_TREE: str+=" TREE   "; break;
+      default       : str+=" ERROR? ";
+      }
+
+    android.util.Log.e("Object", str+printDetails()+msg);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  InternalObject(int type)
+    {
+    mID  = type==TYPE_SYST ? --mNextSystemID : ++mNextClientID;
+    mType= type;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void markForCreation()
+    {
+    synchronized(mDoneLock)
+      {
+      mDoneList.remove(this);
+      }
+
+    synchronized(mToDoLock)
+      {
+      mToDoMap.put(mID, new Job(this,JOB_CREATE) );
+      mToDo = true;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
+ */
+  public void markForDeletion()
+    {
+    synchronized(mDoneLock)
+      {
+      mDoneList.remove(this);
+      }
+
+    synchronized(mToDoLock)
+      {
+      mToDoMap.put(mID, new Job(this,JOB_DELETE) );
+      mToDo = true;
+      }
+    }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return unique ID of this Object.
+ */
+  public long getID()
+    {
+    return mID;
+    }
+
+}
diff --git a/src/main/java/org/distorted/library/main/InternalOutputSurface.java b/src/main/java/org/distorted/library/main/InternalOutputSurface.java
new file mode 100644
index 0000000..c201388
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalOutputSurface.java
@@ -0,0 +1,930 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.opengl.GLES31;
+import android.opengl.Matrix;
+
+import org.distorted.library.effect.EffectQuality;
+import org.distorted.library.effectqueue.EffectQueuePostprocess;
+import org.distorted.library.mesh.MeshBase;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * This is not really part of the public API.
+ *
+ * @y.exclude
+ */
+public abstract class InternalOutputSurface extends InternalSurface implements InternalChildrenList.Parent
+{
+  public static final int NO_DEPTH_NO_STENCIL = 0;
+  public static final int DEPTH_NO_STENCIL    = 1;
+  public static final int BOTH_DEPTH_STENCIL  = 2;
+
+  float mFOV, mDistance, mNear;
+  float[] mProjectionMatrix;
+
+  int mDepthStencilCreated;
+  int mDepthStencil;
+  int[] mDepthStencilH;
+  int[] mFBOH;
+
+  float mMipmap;
+
+  int mRealWidth;   // the Surface can be backed up with a texture that is
+  int mRealHeight;  // larger than the viewport we have to it.
+                    // mWidth,mHeight are the sizes of the Viewport, those -
+                    // sizes of the backing up texture.
+
+  int mCurrFBO;     // internal current FBO (see DistortedLibrary.FBO_QUEUE_SIZE)
+
+  private static DistortedFramebuffer[] mBuffer=null; // Global buffers used for postprocessing.
+  private long[] mTime;
+  private float mClearR, mClearG, mClearB, mClearA, mClearDepth;
+  private int mClear, mClearStencil;
+  private boolean mRenderWayOIT;
+  private InternalChildrenList mChildren;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  InternalOutputSurface(int width, int height, int createColor, int numfbos, int numcolors, int depthStencil, int fbo, int type)
+    {
+    super(width,height,createColor,numfbos,numcolors,type);
+
+    mRenderWayOIT = false;
+    mCurrFBO      = 0;
+
+    mDepthStencilH = new int[numfbos];
+    mFBOH          = new int[numfbos];
+
+    mTime = new long[numfbos];
+    for(int i=0; i<mNumFBOs;i++) mTime[i]=0;
+
+    mRealWidth = width;
+    mRealHeight= height;
+
+    mProjectionMatrix = new float[16];
+
+    mFOV = 60.0f;
+    mNear=  0.5f;
+
+    mDepthStencilCreated= (depthStencil== NO_DEPTH_NO_STENCIL ? DONT_CREATE:NOT_CREATED_YET);
+    mDepthStencil = depthStencil;
+
+    mFBOH[0]         = fbo;
+    mDepthStencilH[0]= 0;
+
+    mClearR = 0.0f;
+    mClearG = 0.0f;
+    mClearB = 0.0f;
+    mClearA = 0.0f;
+
+    mClearDepth = 1.0f;
+    mClearStencil = 0;
+    mClear = GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_COLOR_BUFFER_BIT;
+
+    mMipmap = 1.0f;
+
+    mChildren = new InternalChildrenList(this);
+
+    createProjection();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void createProjection()
+    {
+    if( mWidth>0 && mHeight>1 )
+      {
+      if( mFOV>0.0f )  // perspective projection
+        {
+        float a = 2.0f*(float)Math.tan(mFOV*Math.PI/360);
+        float q = mWidth*mNear;
+        float c = mHeight*mNear;
+
+        float left   = -q/2;
+        float right  = +q/2;
+        float bottom = -c/2;
+        float top    = +c/2;
+        float near   =  c/a;
+
+        mDistance    = mHeight/a;
+        float far    = 2*mDistance-near;
+
+        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
+        }
+      else             // parallel projection
+        {
+        float left   = -mWidth/2.0f;
+        float right  = +mWidth/2.0f;
+        float bottom = -mHeight/2.0f;
+        float top    = +mHeight/2.0f;
+        float near   = mWidth+mHeight-mHeight*(1.0f-mNear);
+        mDistance    = mWidth+mHeight;
+        float far    = mWidth+mHeight+mHeight*(1.0f-mNear);
+
+        Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void createPostprocessingBuffers(int width, int height, float near)
+    {
+    final float CLEAR_R = 1.0f;
+    final float CLEAR_G = 1.0f;
+    final float CLEAR_B = 1.0f;
+    final float CLEAR_A = 0.0f;
+    final float CLEAR_D = 1.0f;
+    final int   CLEAR_S = 0;
+
+    mBuffer = new DistortedFramebuffer[EffectQuality.LENGTH];
+    float mipmap=1.0f;
+
+    for (int j=0; j<EffectQuality.LENGTH; j++)
+      {
+      mBuffer[j] = new DistortedFramebuffer(DistortedLibrary.FBO_QUEUE_SIZE,2,BOTH_DEPTH_STENCIL,TYPE_SYST, (int)(width*mipmap), (int)(height*mipmap) );
+      mBuffer[j].mMipmap = mipmap;
+      mBuffer[j].mNear = near;  // copy mNear as well (for blitting- see PostprocessEffect.apply() )
+      mBuffer[j].glClearColor(CLEAR_R, CLEAR_G, CLEAR_B, CLEAR_A);
+
+      mipmap *= EffectQuality.MULTIPLIER;
+      }
+
+    InternalObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
+
+    InternalRenderState.colorDepthStencilOn();
+    GLES31.glClearColor(CLEAR_R, CLEAR_G, CLEAR_B, CLEAR_A);
+    GLES31.glClearDepthf(CLEAR_D);
+    GLES31.glClearStencil(CLEAR_S);
+
+    for (int j=0; j<EffectQuality.LENGTH; j++)
+      {
+      for(int k = 0; k< DistortedLibrary.FBO_QUEUE_SIZE; k++)
+        {
+        GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mBuffer[j].mFBOH[k]);
+        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k+1], 0);
+        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT | GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_STENCIL_BUFFER_BIT);
+        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[2*k  ], 0);
+        GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
+        }
+      }
+
+    InternalRenderState.colorDepthStencilRestore();
+
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static synchronized void onDestroy()
+    {
+    if( mBuffer!=null )
+      {
+      for (int j = 0; j < EffectQuality.LENGTH; j++)
+        {
+        mBuffer[j] = null;
+        }
+
+      mBuffer = null;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// The postprocessing buffers mBuffer[] are generally speaking too large (there's just one static
+// set of them) so before we use them for output, we need to adjust the Viewport as if they were
+// smaller. That takes care of outputting pixels to them. When we use them as input, we have to
+// adjust the texture coords - see the get{Width|Height}Correction functions.
+//
+// Also, adjust the Buffers so their Projection is the same like the surface we are supposed to be
+// rendering to.
+
+  private static void clonePostprocessingViewportAndProjection(InternalOutputSurface from)
+    {
+    if( mBuffer[0].mWidth != from.mWidth || mBuffer[0].mHeight != from.mHeight ||
+        mBuffer[0].mFOV   != from.mFOV   || mBuffer[0].mNear   != from.mNear    )
+      {
+      InternalOutputSurface surface;
+
+      for(int i=0; i<EffectQuality.LENGTH; i++)
+        {
+        surface = mBuffer[i];
+
+        surface.mWidth  = (int)(from.mWidth *surface.mMipmap);
+        surface.mHeight = (int)(from.mHeight*surface.mMipmap);
+        surface.mFOV    = from.mFOV;
+        surface.mNear   = from.mNear;  // Near plane is independent of the mipmap level
+
+        surface.createProjection();
+
+        int maxw = surface.mWidth  > surface.mRealWidth  ? surface.mWidth  : surface.mRealWidth;
+        int maxh = surface.mHeight > surface.mRealHeight ? surface.mHeight : surface.mRealHeight;
+
+        if (maxw > surface.mRealWidth || maxh > surface.mRealHeight)
+          {
+          surface.mRealWidth = maxw;
+          surface.mRealHeight = maxh;
+
+          surface.recreate();
+          surface.create();
+          }
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int blitWithDepth(long currTime, InternalOutputSurface buffer, int fbo)
+    {
+    GLES31.glViewport(0, 0, mWidth, mHeight);
+    setAsOutput(currTime);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
+
+    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+    GLES31.glStencilMask(0x00);
+
+    DistortedLibrary.blitDepthPriv(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+
+    // clear buffers
+    GLES31.glStencilMask(0xff);
+    GLES31.glDepthMask(true);
+    GLES31.glColorMask(true,true,true,true);
+    GLES31.glClearColor(buffer.mClearR,buffer.mClearG,buffer.mClearB,buffer.mClearA);
+    GLES31.glClearDepthf(buffer.mClearDepth);
+    GLES31.glClearStencil(buffer.mClearStencil);
+
+    buffer.setAsOutput();
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo+1], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo  ], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private static void oitClear(InternalOutputSurface buffer)
+    {
+    int counter = DistortedLibrary.zeroOutAtomic();
+    DistortedLibrary.oitClear(buffer,counter);
+    GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int oitBuild(long time, InternalOutputSurface buffer, int fbo)
+    {
+    GLES31.glViewport(0, 0, mWidth, mHeight);
+    setAsOutput(time);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[fbo]);
+
+    InternalRenderState.colorDepthStencilOn();
+    InternalRenderState.enableDepthTest();
+
+    DistortedLibrary.oitBuild(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+
+    InternalRenderState.colorDepthStencilRestore();
+    InternalRenderState.restoreDepthTest();
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// two phases: 1. collapse the SSBO 2. blend the ssbo's color
+
+  private int oitRender(long currTime, int fbo)
+    {
+    float corrW = getWidthCorrection();
+    float corrH = getHeightCorrection();
+
+    // Do the Collapse Pass only if we do have a Depth attachment.
+    // Otherwise there's no point (in fact we then would create a feedback loop!)
+
+    if( mDepthStencilH[fbo] != 0 )
+      {
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
+      GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mDepthStencilH[fbo]);
+      InternalRenderState.switchOffColorDepthStencil();
+      DistortedLibrary.oitCollapse(this, corrW, corrH);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+      }
+
+    setAsOutput(currTime);
+    InternalRenderState.switchColorDepthOnStencilOff();
+    DistortedLibrary.oitRender(this, corrW, corrH);
+    InternalRenderState.restoreColorDepthStencil();
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void clear()
+    {
+    InternalRenderState.colorDepthStencilOn();
+    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
+    GLES31.glClearDepthf(mClearDepth);
+    GLES31.glClearStencil(mClearStencil);
+    GLES31.glClear(mClear);
+    InternalRenderState.colorDepthStencilRestore();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void setCurrFBO(int fbo)
+    {
+    mCurrFBO = fbo;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Render all children, one by one. If there are no postprocessing effects, just render to THIS.
+// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing
+// to a whole buffer (lastQueue.postprocess) and merge it (this.oitBuild or blitWithDepth - depending
+// on the type of rendering)
+
+  int renderChildren(long time, int numChildren, InternalChildrenList children, int fbo, boolean oit)
+    {
+    int numRenders=0, bucketChange=0;
+    DistortedNode child;
+    DistortedFramebuffer buffer=null;
+    EffectQueuePostprocess lastQueue=null, currQueue;
+    long lastBucket=0, currBucket;
+    boolean renderDirectly=false;
+
+    setCurrFBO(fbo);
+
+    if( mBuffer!=null )
+      {
+      for (int i=0; i<EffectQuality.LENGTH; i++) mBuffer[i].setCurrFBO(fbo);
+      }
+
+    if( oit && numChildren>0 )
+      {
+      oitClear(this);
+      }
+
+    for(int i=0; i<numChildren; i++)
+      {
+      child = children.getChild(i);
+      currQueue = (EffectQueuePostprocess)child.getEffects().getQueues()[3];
+      currBucket= currQueue.getID();
+
+      if( currBucket==0 )
+        {
+        setAsOutput(time);
+
+        if( oit )
+          {
+          numRenders += child.drawOIT(time, this);
+          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+          }
+        else
+          {
+          numRenders += child.draw(time, this);
+          }
+        }
+      else
+        {
+        if( mBuffer==null )
+          {
+          createPostprocessingBuffers(mWidth,mHeight,mNear);
+          for (int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].setCurrFBO(fbo);
+          }
+
+        if( lastBucket!=currBucket )
+          {
+          if( lastBucket==0 )
+            {
+            clonePostprocessingViewportAndProjection(this);
+            }
+          else
+            {
+            for(int j=bucketChange; j<i; j++) numRenders += lastQueue.preprocess( buffer,children.getChild(j), buffer.mDistance, buffer.mMipmap, buffer.mProjectionMatrix );
+            numRenders += lastQueue.postprocess(buffer);
+
+            if( oit )
+              {
+              numRenders += oitBuild(time, buffer, fbo);
+              GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+              }
+            else
+              {
+              numRenders += blitWithDepth(time, buffer, fbo);
+              }
+            buffer.clearBuffer(fbo);
+            }
+
+          buffer= mBuffer[currQueue.getQuality()];
+          bucketChange= i;
+          renderDirectly = currQueue.getRender();
+          }
+
+        if( renderDirectly )
+          {
+          setAsOutput(time);
+
+          if( oit )
+            {
+            numRenders += child.drawOIT(time, this);
+            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+            }
+          else
+            {
+            numRenders += child.draw(time, this);
+            }
+          }
+        else
+          {
+          buffer.setAsOutput(time);
+          child.drawNoBlend(time, buffer);
+          }
+
+        if( i==numChildren-1 )
+          {
+          for(int j=bucketChange; j<numChildren; j++) numRenders += currQueue.preprocess( buffer,children.getChild(j), buffer.mDistance, buffer.mMipmap, buffer.mProjectionMatrix );
+          numRenders += currQueue.postprocess(buffer);
+
+          if( oit )
+            {
+            numRenders += oitBuild(time, buffer, fbo);
+            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+            buffer.clearBuffer(fbo);
+            }
+          else
+            {
+            numRenders += blitWithDepth(time, buffer,fbo);
+            }
+          }
+        } // end else (postprocessed child)
+
+      lastQueue = currQueue;
+      lastBucket= currBucket;
+      } // end main for loop
+
+    if( oit && numChildren>0 )
+      {
+      numRenders += oitRender(time, fbo);  // merge the OIT linked list
+      }
+
+    return numRenders;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Not part of the public API.
+ *
+ * @y.exclude
+ */
+  public void adjustIsomorphism() { }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Not part of the Public API.
+ *
+ * @y.exclude
+ */
+  public float getWidthCorrection()
+    {
+    return (float)mWidth/mRealWidth;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Not part of the Public API.
+ *
+ * @y.exclude
+ */
+  public float getHeightCorrection()
+    {
+    return (float)mHeight/mRealHeight;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void clearBuffer(int fbo)
+    {
+    InternalRenderState.colorDepthStencilOn();
+
+    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
+    GLES31.glClearDepthf(mClearDepth);
+    GLES31.glClearStencil(mClearStencil);
+
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]);
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[2*fbo+1], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[2*fbo  ], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
+
+    InternalRenderState.colorDepthStencilRestore();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void setAsOutput(long time)
+    {
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
+
+    if( mTime[mCurrFBO]!=time )
+      {
+      mTime[mCurrFBO] = time;
+      clear();
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Draws all the attached children to this OutputSurface's 0th FBO.
+ * <p>
+ * Must be called from a thread holding OpenGL Context.
+ *
+ * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
+ * @return Number of objects rendered.
+ */
+  public int render(long time)
+    {
+    return render(time,0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Draws all the attached children to this OutputSurface.
+ * <p>
+ * Must be called from a thread holding OpenGL Context.
+ *
+ * @param time Current time, in milliseconds. This will be passed to all the Effects stored in the children Nodes.
+ * @param fbo The surface can have many FBOs backing it up - render this to FBO number 'fbo'.
+ * @return Number of objects rendered.
+ */
+  public int render(long time, int fbo)
+    {
+    InternalMaster.toDo();
+    toDo();
+    InternalRenderState.reset();
+
+    int numRenders=0, numChildren = mChildren.getNumChildren();
+    DistortedNode node;
+    long oldBucket=0, newBucket;
+
+    for(int i=0; i<numChildren; i++)
+      {
+      node = mChildren.getChild(i);
+      newBucket = node.getBucket();
+      numRenders += node.renderRecursive(time);
+      if( newBucket<oldBucket ) mChildren.rearrangeByBuckets(i,newBucket);
+      else oldBucket=newBucket;
+      }
+
+    numRenders += renderChildren(time,numChildren,mChildren,fbo, mRenderWayOIT);
+
+    return numRenders;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bind this Surface as a Framebuffer we can render to.
+ * <p>
+ * This version does not attempt to clear anything.
+ */
+  public void setAsOutput()
+    {
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return the Near plane of the Projection included in the Surface.
+ *
+ * @return the Near plane.
+ */
+  public float getNear()
+    {
+    return mNear;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Set mipmap level.
+ * <p>
+ * Trick for speeding up your renders - one can create a pyramid of OutputSurface objects, each next
+ * one some constant FACTOR smaller than the previous (0.5 is the common value), then set the Mipmap
+ * Level of the i-th object to be FACTOR^i (we start counting from 0). When rendering any scene into
+ * such prepared OutputSurface, the library will make sure to scale any Effects used so that the end
+ * scene will end up looking identical no matter which object we render to. Identical, that is, except
+ * for the loss of quality and gain in speed associated with rendering to a smaller Surface.
+ * <p>
+ * Example: if you create two FBOs, one 1000x1000 and another 500x500 in size, and set the second one
+ * mipmap to 0.5 (the first one's is 1.0 by default), define Effects to be a single move by (100,100),
+ * and render a skinned Mesh into both FBO, the end result will look proportionally the same, because
+ * in the second case the move vector (100,100) will be auto-scaled to (50,50).
+ *
+ * @param mipmap The mipmap level. Acceptable range: 0&lt;mipmap&lt;infinity, although mipmap&gt;1
+ *               does not make any sense (that would result in loss of speed and no gain in quality)
+ */
+  public void setMipmap(float mipmap)
+    {
+    mMipmap = mipmap;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Set the (R,G,B,A) values of GLES31.glClearColor() to set up color with which to clear
+ * this Surface at the beginning of each frame.
+ *
+ * @param r the Red component. Default: 0.0f
+ * @param g the Green component. Default: 0.0f
+ * @param b the Blue component. Default: 0.0f
+ * @param a the Alpha component. Default: 0.0f
+ */
+  public void glClearColor(float r, float g, float b, float a)
+    {
+    mClearR = r;
+    mClearG = g;
+    mClearB = b;
+    mClearA = a;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Uses glClearDepthf() to set up a value with which to clear
+ * the Depth buffer of our Surface at the beginning of each frame.
+ *
+ * @param d the Depth. Default: 1.0f
+ */
+  public void glClearDepthf(float d)
+    {
+    mClearDepth = d;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Uses glClearStencil() to set up a value with which to clear the
+ * Stencil buffer of our Surface at the beginning of each frame.
+ *
+ * @param s the Stencil. Default: 0
+ */
+  public void glClearStencil(int s)
+    {
+    mClearStencil = s;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Which buffers to Clear at the beginning of each frame?
+ * <p>
+ * Valid values: 0, or bitwise OR of one or more values from the set GL_COLOR_BUFFER_BIT,
+ *               GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
+ * Default: GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT.
+ *
+ * @param mask bitwise OR of BUFFER_BITs to clear.
+ */
+  public void glClear(int mask)
+    {
+    mClear = mask;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Create new Projection matrix.
+ *
+ * @param fov Vertical 'field of view' of the Projection frustrum (in degrees).
+ *            Valid values: 0<=fov<180. FOV==0 means 'parallel projection'.
+ * @param near Distance between the screen plane and the near plane.
+ *             Valid vaules: 0<near<1. When near==0 (illegal!), the Near Plane is exactly at the tip of
+ *             the pyramid. When near==1 (illegal!) the near plane is equivalent to the screen plane.
+ */
+  public void setProjection(float fov, float near)
+    {
+    if( fov < 180.0f && fov >=0.0f )
+      {
+      mFOV = fov;
+      }
+
+    if( near<   1.0f && near> 0.0f )
+      {
+      mNear= near;
+      }
+    else if( near<=0.0f )
+      {
+      mNear = 0.01f;
+      }
+    else if( near>=1.0f )
+      {
+      mNear=0.99f;
+      }
+
+    if( mBuffer!=null )
+      {
+      for(int j=0; j<EffectQuality.LENGTH; j++) mBuffer[j].mNear = mNear;
+      }
+
+    createProjection();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return the vertical field of view angle.
+ *
+ * @return Vertival Field of View Angle, in degrees.
+ */
+  public float getFOV()
+    {
+    return mFOV;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Resize the underlying Framebuffer.
+ * <p>
+ * This method can be safely called mid-render as it doesn't interfere with rendering.
+ *
+ * @param width The new width.
+ * @param height The new height.
+ */
+  public void resize(int width, int height)
+    {
+    if( mWidth!=width || mHeight!=height )
+      {
+      mWidth = mRealWidth = width;
+      mHeight= mRealHeight= height;
+
+      createProjection();
+
+      if( mColorCreated==CREATED )
+        {
+        markForCreation();
+        recreate();
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return true if the Surface contains a DEPTH attachment.
+ *
+ * @return <bold>true</bold> if the Surface contains a DEPTH attachment.
+ */
+  public boolean hasDepth()
+    {
+    return mDepthStencilCreated==CREATED;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return true if the Surface contains a STENCIL attachment.
+ *
+ * @return <bold>true</bold> if the Surface contains a STENCIL attachment.
+ */
+  public boolean hasStencil()
+    {
+    return (mDepthStencilCreated==CREATED && mDepthStencil==BOTH_DEPTH_STENCIL);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * When rendering this Node, should we use the Order Independent Transparency render more?
+ * <p>
+ * There are two modes of rendering: the fast 'normal' way, which however renders transparent
+ * fragments in different ways depending on which fragments get rendered first, or the slower
+ * 'oit' way, which renders transparent fragments correctly regardless of their order.
+ *
+ * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
+ */
+  public void setOrderIndependentTransparency(boolean oit)
+    {
+    mRenderWayOIT = oit;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * When rendering this Node, should we use the Order Independent Transparency render more?
+ * <p>
+ * There are two modes of rendering: the fast 'normal' way, which however renders transparent
+ * fragments in different ways depending on which fragments get rendered first, or the slower
+ * 'oit' way, which renders transparent fragments correctly regardless of their order.
+ *
+ * @param oit True if we want to render more slowly, but in a way which accounts for transparency.
+ * @param initialSize Initial number of transparent fragments we expect, in screenfuls.
+ *                    I.e '1.0' means 'the scene we are going to render contains about 1 screen
+ *                    worth of transparent fragments'. Valid values: 0.0 &lt; initialSize &lt; 10.0
+ *                    Even if you get this wrong, the library will detect that there are more
+ *                    transparent fragments than it has space for and readjust its internal buffers,
+ *                    but only after a few frames during which one will probably see missing objects.
+ */
+public void setOrderIndependentTransparency(boolean oit, float initialSize)
+  {
+  mRenderWayOIT = oit;
+
+  if( initialSize>0.0f && initialSize<10.0f )
+    DistortedLibrary.setSSBOSize(initialSize);
+  }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a new child to the last position in the list of our Surface's children.
+ * <p>
+ * We cannot do this mid-render - actual attachment will be done just before the next render, by the
+ * InternalMaster (by calling doWork())
+ *
+ * @param node The new Node to add.
+ */
+  public void attach(DistortedNode node)
+    {
+    mChildren.attach(node);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a new child to the last position in the list of our Surface's children.
+ * <p>
+ * We cannot do this mid-render - actual attachment will be done just before the next render, by the
+ * InternalMaster (by calling doWork())
+ *
+ * @param surface InputSurface to initialize our child Node with.
+ * @param effects DistortedEffects to initialize our child Node with.
+ * @param mesh MeshBase to initialize our child Node with.
+ * @return the newly constructed child Node, or null if we couldn't allocate resources.
+ */
+  public DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
+    {
+    return mChildren.attach(surface,effects,mesh);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Removes the first occurrence of a specified child from the list of children of our Surface.
+ * <p>
+ * A bit questionable method as there can be many different Nodes attached as children, some
+ * of them having the same Effects but - for instance - different Mesh. Use with care.
+ * <p>
+ * We cannot do this mid-render - actual detachment will be done just before the next render, by the
+ * InternalMaster (by calling doWork())
+ *
+ * @param effects DistortedEffects to remove.
+ */
+  public void detach(DistortedEffects effects)
+    {
+    mChildren.detach(effects);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Removes the first occurrence of a specified child from the list of children of our Surface.
+ * <p>
+ * We cannot do this mid-render - actual attachment will be done just before the next render, by the
+ * InternalMaster (by calling doWork())
+ *
+ * @param node The Node to remove.
+ */
+  public void detach(DistortedNode node)
+    {
+    mChildren.detach(node);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Removes all children Nodes.
+ * <p>
+ * We cannot do this mid-render - actual attachment will be done just before the next render, by the
+ * InternalMaster (by calling doWork())
+ */
+  public void detachAll()
+    {
+    mChildren.detachAll();
+    }
+}
diff --git a/src/main/java/org/distorted/library/main/InternalRenderState.java b/src/main/java/org/distorted/library/main/InternalRenderState.java
new file mode 100644
index 0000000..772e600
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalRenderState.java
@@ -0,0 +1,867 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.opengl.GLES31;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Remember the OpenGL state.
+ * <p>
+ * This is a member of DistortedNode. Remembers the OpenGL state we want to set just before rendering
+ * the Node.
+ * <p>
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+public class InternalRenderState
+{
+  // TODO: figure this out dynamically; this assumes 8 bit stencil buffer.
+  private static final int STENCIL_MASK = (1<<8)-1;
+
+  private static class RenderState
+    {
+    private int colorMaskR, colorMaskG, colorMaskB, colorMaskA;
+    private int depthMask;
+    private int stencilMask;
+    private int depthTest;
+    private int stencilTest;
+    private int stencilFuncFunc, stencilFuncRef, stencilFuncMask;
+    private int stencilOpSfail, stencilOpDpfail, stencilOpDppass;
+    private int depthFunc;
+    private int blend;
+    private int blendSrc, blendDst;
+    }
+
+  private RenderState mState;          // state the current object wants to have
+  static private RenderState cState = new RenderState();   // current OpenGL Stave
+  static private RenderState sState = new RenderState();   // saved OpenGL state
+
+  private int mClear;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// default: color writes on, depth test and writes on, blending on, stencil off.
+
+  InternalRenderState()
+    {
+    mState = new RenderState();
+
+    mState.colorMaskR = 1;
+    mState.colorMaskG = 1;
+    mState.colorMaskB = 1;
+    mState.colorMaskA = 1;
+
+    mState.depthTest  = 1;
+    mState.depthMask  = 1;
+    mState.depthFunc  = GLES31.GL_LEQUAL;
+
+    mState.blend      = 1;
+    mState.blendSrc   = GLES31.GL_SRC_ALPHA;
+    mState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
+
+    mState.stencilTest     = 0;
+    mState.stencilMask     = STENCIL_MASK;
+    mState.stencilFuncFunc = GLES31.GL_NEVER;
+    mState.stencilFuncRef  = 0;
+    mState.stencilFuncMask = STENCIL_MASK;
+    mState.stencilOpSfail  = GLES31.GL_KEEP;
+    mState.stencilOpDpfail = GLES31.GL_KEEP;
+    mState.stencilOpDppass = GLES31.GL_KEEP;
+
+    mClear = 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// reset state of everything to a known state.
+
+  static void reset()
+    {
+    cState.colorMaskR = 1;
+    cState.colorMaskG = 1;
+    cState.colorMaskB = 1;
+    cState.colorMaskA = 1;
+    GLES31.glColorMask(true,true,true,true);
+
+    cState.depthTest = 1;
+    cState.depthMask = 1;
+    cState.depthFunc = GLES31.GL_LEQUAL;
+    GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+    GLES31.glDepthMask(true);
+    GLES31.glDepthFunc(cState.depthFunc);
+
+    cState.stencilTest     = 0;
+    cState.stencilMask     = STENCIL_MASK;
+    cState.stencilFuncFunc = GLES31.GL_NEVER;
+    cState.stencilFuncRef  = 0;
+    cState.stencilFuncMask = STENCIL_MASK;
+    cState.stencilOpSfail  = GLES31.GL_KEEP;
+    cState.stencilOpDpfail = GLES31.GL_KEEP;
+    cState.stencilOpDppass = GLES31.GL_KEEP;
+    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+    GLES31.glStencilMask(cState.stencilMask);
+
+    cState.blend      = 1;
+    cState.blendSrc   = GLES31.GL_SRC_ALPHA;
+    cState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
+    GLES31.glEnable(GLES31.GL_BLEND);
+    GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void colorDepthStencilOn()
+    {
+    sState.colorMaskR = cState.colorMaskR;
+    sState.colorMaskG = cState.colorMaskG;
+    sState.colorMaskB = cState.colorMaskB;
+    sState.colorMaskA = cState.colorMaskA;
+
+    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
+      {
+      cState.colorMaskR = 1;
+      cState.colorMaskG = 1;
+      cState.colorMaskB = 1;
+      cState.colorMaskA = 1;
+      GLES31.glColorMask(true,true,true,true);
+      }
+
+    sState.depthMask = cState.depthMask;
+
+    if( cState.depthMask!=1 )
+      {
+      cState.depthMask = 1;
+      GLES31.glDepthMask(true);
+      }
+
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilMask!= STENCIL_MASK )
+      {
+      cState.stencilMask = STENCIL_MASK;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void colorDepthStencilRestore()
+    {
+    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
+      {
+      cState.colorMaskR = sState.colorMaskR;
+      cState.colorMaskG = sState.colorMaskG;
+      cState.colorMaskB = sState.colorMaskB;
+      cState.colorMaskA = sState.colorMaskA;
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      }
+    if( sState.depthMask!=cState.depthMask )
+      {
+      cState.depthMask = sState.depthMask;
+      GLES31.glDepthMask(cState.depthMask==1);
+      }
+    if( sState.stencilMask!=cState.stencilMask )
+      {
+      cState.stencilMask = sState.stencilMask;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void disableBlending()
+    {
+    sState.blend = cState.blend;
+
+    if (cState.blend != 0)
+      {
+      cState.blend = 0;
+      GLES31.glDisable(GLES31.GL_BLEND);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void restoreBlending()
+    {
+    if (sState.blend != cState.blend)
+      {
+      cState.blend = sState.blend;
+
+      if (cState.blend == 0)
+        {
+        GLES31.glDisable(GLES31.GL_BLEND);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_BLEND);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void enableDepthTest()
+    {
+    sState.depthTest = cState.depthTest;
+
+    if (cState.depthTest != 1)
+      {
+      cState.depthTest = 1;
+      GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void restoreDepthTest()
+    {
+    if (sState.depthTest != cState.depthTest)
+      {
+      cState.depthTest = sState.depthTest;
+
+      if (cState.depthTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void switchOffDrawing()
+    {
+    GLES31.glEnable(GLES31.GL_SCISSOR_TEST);
+    GLES31.glScissor(0,0,0,0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void restoreDrawing()
+    {
+    GLES31.glDisable(GLES31.GL_SCISSOR_TEST);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void switchOffColorDepthStencil()
+    {
+    sState.stencilTest = cState.stencilTest;
+
+    if( cState.stencilTest!=0 )
+      {
+      cState.stencilTest = 0;
+      //android.util.Log.d("State", "stencil test off");
+      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+      }
+
+    sState.depthTest = cState.depthTest;
+
+    if( cState.depthTest!=0 )
+      {
+      cState.depthTest = 0;
+      //android.util.Log.d("State", "depth test off");
+      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+      }
+
+    sState.colorMaskR = cState.colorMaskR;
+    sState.colorMaskG = cState.colorMaskG;
+    sState.colorMaskB = cState.colorMaskB;
+    sState.colorMaskA = cState.colorMaskA;
+
+    if( cState.colorMaskR!=0 || cState.colorMaskG!=0 || cState.colorMaskB!=0 || cState.colorMaskA!=0 )
+      {
+      cState.colorMaskR = 0;
+      cState.colorMaskG = 0;
+      cState.colorMaskB = 0;
+      cState.colorMaskA = 0;
+      //android.util.Log.d("State", "switch off color writing");
+      GLES31.glColorMask(false,false,false,false);
+      }
+
+    sState.depthMask = cState.depthMask;
+
+    if( cState.depthMask!=0 )
+      {
+      cState.depthMask = 0;
+      //android.util.Log.d("State", "switch off depth writing");
+      GLES31.glDepthMask(false);
+      }
+
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilMask!= 0x00 )
+      {
+      cState.stencilMask = 0x00;
+      //android.util.Log.d("State", "stencil mask off");
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void switchColorDepthOnStencilOff()
+    {
+    sState.stencilTest = cState.stencilTest;
+
+    if( cState.stencilTest!=0 )
+      {
+      cState.stencilTest = 0;
+      //android.util.Log.d("State", "stencil test off");
+      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+      }
+
+    sState.depthTest = cState.depthTest;
+
+    if( cState.depthTest!=0 )
+      {
+      cState.depthTest = 0;
+      //android.util.Log.d("State", "depth test off");
+      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+      }
+
+    sState.colorMaskR = cState.colorMaskR;
+    sState.colorMaskG = cState.colorMaskG;
+    sState.colorMaskB = cState.colorMaskB;
+    sState.colorMaskA = cState.colorMaskA;
+
+    if( cState.colorMaskR!=1 || cState.colorMaskG!=1 || cState.colorMaskB!=1 || cState.colorMaskA!=1 )
+      {
+      cState.colorMaskR = 1;
+      cState.colorMaskG = 1;
+      cState.colorMaskB = 1;
+      cState.colorMaskA = 1;
+      //android.util.Log.d("State", "switch on color writing");
+      GLES31.glColorMask(true,true,true,true);
+      }
+
+    sState.depthMask = cState.depthMask;
+
+    if( cState.depthMask!=1 )
+      {
+      cState.depthMask = 1;
+      //android.util.Log.d("State", "switch on depth writing");
+      GLES31.glDepthMask(true);
+      }
+
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilMask!= 0x00 )
+      {
+      cState.stencilMask = 0x00;
+      //android.util.Log.d("State", "stencil mask off");
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void restoreColorDepthStencil()
+    {
+    if( sState.stencilTest!=cState.stencilTest )
+      {
+      cState.stencilTest = sState.stencilTest;
+
+      if (cState.stencilTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+        }
+      }
+    if( sState.depthTest!=cState.depthTest )
+      {
+      cState.depthTest = sState.depthTest;
+
+      if (cState.depthTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+        }
+      }
+    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
+      {
+      cState.colorMaskR = sState.colorMaskR;
+      cState.colorMaskG = sState.colorMaskG;
+      cState.colorMaskB = sState.colorMaskB;
+      cState.colorMaskA = sState.colorMaskA;
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      }
+    if( sState.depthMask!=cState.depthMask )
+      {
+      cState.depthMask = sState.depthMask;
+      GLES31.glDepthMask(cState.depthMask==1);
+      }
+    if( sState.stencilMask!=cState.stencilMask )
+      {
+      cState.stencilMask = sState.stencilMask;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void setUpStencilMark(boolean color)
+    {
+    sState.stencilTest = cState.stencilTest;
+
+    if( cState.stencilTest!=1 )
+      {
+      cState.stencilTest = 1;
+      //android.util.Log.d("State", "stencil test on");
+      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+      }
+
+    sState.stencilFuncFunc = cState.stencilFuncFunc;
+    sState.stencilFuncRef  = cState.stencilFuncRef;
+    sState.stencilFuncMask = cState.stencilFuncMask;
+
+    if( cState.stencilFuncFunc!=GLES31.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
+      {
+      cState.stencilFuncFunc = GLES31.GL_ALWAYS;
+      cState.stencilFuncRef  = 1;
+      cState.stencilFuncMask = STENCIL_MASK;
+      //android.util.Log.d("State", "stencil func on");
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      }
+
+    sState.stencilOpSfail = cState.stencilOpSfail;
+    sState.stencilOpDpfail= cState.stencilOpDpfail;
+    sState.stencilOpDppass= cState.stencilOpDppass;
+
+    if( cState.stencilOpSfail!=GLES31.GL_KEEP || cState.stencilOpDpfail!=GLES31.GL_KEEP || cState.stencilOpDppass!=GLES31.GL_REPLACE )
+      {
+      cState.stencilOpSfail = GLES31.GL_KEEP;
+      cState.stencilOpDpfail= GLES31.GL_KEEP;
+      cState.stencilOpDppass= GLES31.GL_REPLACE;
+      //android.util.Log.d("State", "stencil op on");
+      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
+      }
+
+    sState.colorMaskR = cState.colorMaskR;
+    sState.colorMaskG = cState.colorMaskG;
+    sState.colorMaskB = cState.colorMaskB;
+    sState.colorMaskA = cState.colorMaskA;
+
+    int clr = color ? 1:0;
+
+    if( cState.colorMaskR!=clr || cState.colorMaskG!=clr || cState.colorMaskB!=clr || cState.colorMaskA!=clr )
+      {
+      cState.colorMaskR = clr;
+      cState.colorMaskG = clr;
+      cState.colorMaskB = clr;
+      cState.colorMaskA = clr;
+      //android.util.Log.d("State", "switch off color writing");
+      GLES31.glColorMask(color,color,color,color);
+      }
+
+    sState.depthMask = cState.depthMask;
+
+    if( cState.depthMask!=1 )
+      {
+      cState.depthMask = 1;
+      //android.util.Log.d("State", "switch on depth writing");
+      GLES31.glDepthMask(true);
+      }
+
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilMask!= STENCIL_MASK )
+      {
+      cState.stencilMask = STENCIL_MASK;
+      //android.util.Log.d("State", "stencil mask on");
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void unsetUpStencilMark()
+    {
+    if( sState.stencilTest!=cState.stencilTest )
+      {
+      cState.stencilTest = sState.stencilTest;
+
+      if (cState.stencilTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+        }
+      }
+    if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
+      {
+      cState.colorMaskR = sState.colorMaskR;
+      cState.colorMaskG = sState.colorMaskG;
+      cState.colorMaskB = sState.colorMaskB;
+      cState.colorMaskA = sState.colorMaskA;
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      }
+    if( sState.depthMask!=cState.depthMask )
+      {
+      cState.depthMask = sState.depthMask;
+      GLES31.glDepthMask(cState.depthMask==1);
+      }
+    if( sState.stencilMask!=cState.stencilMask )
+      {
+      cState.stencilMask = sState.stencilMask;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public static void useStencilMark()
+    {
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilTest!=1 )
+      {
+      cState.stencilTest = 1;
+      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+      }
+
+    sState.stencilFuncFunc = cState.stencilFuncFunc;
+    sState.stencilFuncRef  = cState.stencilFuncRef;
+    sState.stencilFuncMask = cState.stencilFuncMask;
+
+    if( cState.stencilFuncFunc!=GLES31.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
+      {
+      cState.stencilFuncFunc = GLES31.GL_EQUAL;
+      cState.stencilFuncRef  = 1;
+      cState.stencilFuncMask = STENCIL_MASK;
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      }
+
+    sState.stencilMask = cState.stencilMask;
+
+    if( cState.stencilMask!= 0x00 )
+      {
+      cState.stencilMask = 0x00;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+
+    sState.depthMask = cState.depthMask;
+
+    if( cState.depthMask!=0 )
+      {
+      cState.depthMask = 0;
+      GLES31.glDepthMask(false);
+      }
+
+    sState.depthTest = cState.depthTest;
+
+    if( cState.depthTest!=0 )
+      {
+      cState.depthTest = 0;
+      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public static void unuseStencilMark()
+    {
+    if( sState.stencilTest!=cState.stencilTest )
+      {
+      cState.stencilTest = sState.stencilTest;
+
+      if (cState.stencilTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+        }
+      }
+    if( sState.stencilFuncFunc!=cState.stencilFuncFunc || sState.stencilFuncRef!=cState.stencilFuncRef || sState.stencilFuncMask!=cState.stencilFuncMask )
+      {
+      cState.stencilFuncFunc = sState.stencilFuncFunc;
+      cState.stencilFuncRef  = sState.stencilFuncRef ;
+      cState.stencilFuncMask = sState.stencilFuncMask;
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      }
+    if( sState.stencilMask!=cState.stencilMask )
+      {
+      cState.stencilMask = sState.stencilMask;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+    if( sState.depthMask!=cState.depthMask )
+      {
+      cState.depthMask = sState.depthMask;
+      GLES31.glDepthMask(cState.depthMask==1);
+      }
+    if( sState.depthTest!=cState.depthTest )
+      {
+      cState.depthTest = sState.depthTest;
+
+      if (cState.depthTest == 0)
+        {
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+        }
+      else
+        {
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+        }
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void apply()
+    {
+    //android.util.Log.e("State", "APPLYING STATE");
+
+    /////////////////////////////////////////////////////
+    // 1. Write to color buffer?
+    if( mState.colorMaskR!=cState.colorMaskR || mState.colorMaskG!=cState.colorMaskG || mState.colorMaskB!=cState.colorMaskB || mState.colorMaskA!=cState.colorMaskA)
+      {
+      //android.util.Log.d("State", "setting color mask");
+      cState.colorMaskR = mState.colorMaskR;
+      cState.colorMaskG = mState.colorMaskG;
+      cState.colorMaskB = mState.colorMaskB;
+      cState.colorMaskA = mState.colorMaskA;
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      }
+
+    /////////////////////////////////////////////////////
+    // 2. Enable Depth test?
+    if( mState.depthTest!=cState.depthTest )
+      {
+      cState.depthTest = mState.depthTest;
+
+      if (cState.depthTest == 0)
+        {
+        //android.util.Log.d("State", "disabling depth test");
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+        }
+      else
+        {
+        //android.util.Log.d("State", "enable depth test");
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+        }
+      }
+
+    /////////////////////////////////////////////////////
+    // 3. Change Depth Function?
+    if( mState.depthFunc!=cState.depthFunc )
+      {
+      //android.util.Log.d("State", "setting depth func");
+      cState.depthFunc = mState.depthFunc;
+      GLES31.glDepthFunc(cState.depthFunc);
+      }
+
+    /////////////////////////////////////////////////////
+    // 4. Write to Depth buffer?
+    if( mState.depthMask!=cState.depthMask )
+      {
+      //android.util.Log.d("State", "setting depth mask");
+      cState.depthMask = mState.depthMask;
+      GLES31.glDepthMask(cState.depthMask==1);
+      }
+
+    /////////////////////////////////////////////////////
+    // 5. Enable Blending?
+    if( mState.blend!=cState.blend )
+      {
+      cState.blend = mState.blend;
+
+      if (cState.blend == 0)
+        {
+        //android.util.Log.d("State", "disabling blending");
+        GLES31.glDisable(GLES31.GL_BLEND);
+        }
+      else
+        {
+        //android.util.Log.d("State", "enabling blending");
+        GLES31.glEnable(GLES31.GL_BLEND);
+        }
+      }
+
+    /////////////////////////////////////////////////////
+    // 6. Change Blend function?
+    if( mState.blendSrc!=cState.blendSrc || mState.blendDst!=cState.blendDst )
+      {
+      //android.util.Log.d("State", "setting blend function");
+      cState.blendSrc = mState.blendSrc;
+      cState.blendDst = mState.blendDst;
+      GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
+      }
+
+    /////////////////////////////////////////////////////
+    // 7. Enable/Disable Stencil Test?
+    if( mState.stencilTest!=cState.stencilTest )
+      {
+      cState.stencilTest = mState.stencilTest;
+
+      if (cState.stencilTest == 0)
+        {
+        //android.util.Log.d("State", "disabling stencil test");
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+        }
+      else
+        {
+        //android.util.Log.d("State", "enabling stencil test");
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
+        }
+      }
+
+    /////////////////////////////////////////////////////
+    // 8. Adjust Stencil function?
+    if( mState.stencilFuncFunc!=cState.stencilFuncFunc || mState.stencilFuncRef!=cState.stencilFuncRef || mState.stencilFuncMask!=cState.stencilFuncMask )
+      {
+      //android.util.Log.d("State", "setting stencil function");
+      cState.stencilFuncFunc = mState.stencilFuncFunc;
+      cState.stencilFuncRef  = mState.stencilFuncRef ;
+      cState.stencilFuncMask = mState.stencilFuncMask;
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      }
+
+    /////////////////////////////////////////////////////
+    // 9. Adjust Stencil operation?
+    if( mState.stencilOpSfail!=cState.stencilOpSfail || mState.stencilOpDpfail!=cState.stencilOpDpfail || mState.stencilOpDppass!=cState.stencilOpDppass )
+      {
+      //android.util.Log.d("State", "setting stencil op");
+      cState.stencilOpSfail = mState.stencilOpSfail;
+      cState.stencilOpDpfail= mState.stencilOpDpfail;
+      cState.stencilOpDppass= mState.stencilOpDppass;
+      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
+      }
+
+    /////////////////////////////////////////////////////
+    // 10. Write to Stencil buffer?
+    if( mState.stencilMask!=cState.stencilMask )
+      {
+      //android.util.Log.d("State", "setting stencil mask");
+      cState.stencilMask = mState.stencilMask;
+      GLES31.glStencilMask(cState.stencilMask);
+      }
+
+    /////////////////////////////////////////////////////
+    // 11. Clear buffers?
+    if( mClear!=0 )
+      {
+      //android.util.Log.d("State", "clearing buffer");
+      GLES31.glClear(mClear);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glColorMask(boolean r, boolean g, boolean b, boolean a)
+    {
+    mState.colorMaskR = (r ? 1:0);
+    mState.colorMaskG = (g ? 1:0);
+    mState.colorMaskB = (b ? 1:0);
+    mState.colorMaskA = (a ? 1:0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glDepthMask(boolean mask)
+    {
+    mState.depthMask = (mask ? 1:0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glStencilMask(int mask)
+    {
+    mState.stencilMask = mask;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glEnable(int test)
+    {
+         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 1;
+    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 1;
+    else if( test==GLES31.GL_BLEND        ) mState.blend       = 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glDisable(int test)
+    {
+         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 0;
+    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 0;
+    else if( test==GLES31.GL_BLEND        ) mState.blend       = 0;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glStencilFunc(int func, int ref, int mask)
+    {
+    mState.stencilFuncFunc = func;
+    mState.stencilFuncRef  = ref;
+    mState.stencilFuncMask = mask;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glStencilOp(int sfail, int dpfail, int dppass)
+    {
+    mState.stencilOpSfail = sfail;
+    mState.stencilOpDpfail= dpfail;
+    mState.stencilOpDppass= dppass;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glDepthFunc(int func)
+    {
+    mState.depthFunc = func;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glBlendFunc(int src, int dst)
+    {
+    mState.blendSrc = src;
+    mState.blendDst = dst;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void glClear(int mask)
+    {
+    mClear = mask;
+    }
+}
diff --git a/src/main/java/org/distorted/library/main/InternalSurface.java b/src/main/java/org/distorted/library/main/InternalSurface.java
new file mode 100644
index 0000000..2a8b44a
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/InternalSurface.java
@@ -0,0 +1,125 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of DistortedLibrary.                                                               //
+//                                                                                               //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.opengl.GLES31;
+
+import org.distorted.library.mesh.MeshBase;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * This is not really part of the public API.
+ *
+ * @y.exclude
+ */
+public abstract class InternalSurface extends InternalObject
+{
+  int mColorCreated;
+  int mNumColors;
+  int mNumFBOs;
+  int[] mColorH;
+  int mWidth, mHeight;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  InternalSurface(int width, int height, int create, int numfbos, int numcolors, int type)
+    {
+    super(type);
+
+    mNumFBOs      = numfbos;
+    mNumColors    = numcolors;
+    mWidth        = width ;
+    mHeight       = height;
+    mColorCreated = create;
+
+    int total = mNumFBOs*mNumColors;
+
+    if( total>0 )
+      {
+      mColorH = new int[total];
+      for( int i=0; i<total; i++ )  mColorH[i] = 0;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// debugging only
+
+  String printDetails()
+    {
+    return getClass().getSimpleName()+" "+mWidth+"x"+mHeight;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return the width of this Surface.
+ *
+ * @return width of the Object, in pixels.
+ */
+  public int getWidth()
+    {
+    return mWidth;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return the height of this Surface.
+ *
+ * @return height of the Object, in pixels.
+ */
+  public int getHeight()
+    {
+    return mHeight;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Return the depth of this Surface.
+ * <p>
+ * Admittedly quite a strange method. Why do we need to pass a Mesh to it? Because one cannot determine
+ * 'depth' of a Surface (bitmap really!) when rendered based only on the texture itself, that depends
+ * on the Mesh it is rendered with.
+ *
+ * @return depth of the Object, in pixels.
+ */
+  public int getDepth(MeshBase mesh)
+    {
+    return mesh==null ? 0 : (int)(mWidth*mesh.getZFactor() );
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bind the underlying rectangle of pixels as a OpenGL Texture.
+ *
+ * @return <code>true</code> if successful.
+ */
+  public boolean setAsInput()
+    {
+    if( mColorH[0]>0 )
+      {
+      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
+      return true;
+      }
+
+    return false;
+    }
+}
diff --git a/src/main/java/org/distorted/library/mesh/MeshBase.java b/src/main/java/org/distorted/library/mesh/MeshBase.java
index abf7e36..af7fbf5 100644
--- a/src/main/java/org/distorted/library/mesh/MeshBase.java
+++ b/src/main/java/org/distorted/library/mesh/MeshBase.java
@@ -1,28 +1,28 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.mesh;
 
 import android.opengl.GLES31;
 
-import org.distorted.library.main.Distorted;
-import org.distorted.library.main.DistortedBuffer;
+import org.distorted.library.main.DistortedLibrary;
+import org.distorted.library.main.InternalBuffer;
 import org.distorted.library.program.DistortedProgram;
 
 import java.nio.ByteBuffer;
@@ -61,7 +61,7 @@ public abstract class MeshBase
    private static final int VERT_SIZE  = VERT_ATTRIBS*BYTES_PER_FLOAT;
 
    private boolean mShowNormals;       // when rendering this mesh, draw normal vectors?
-   private DistortedBuffer mVBO, mTFO; // main vertex buffer and transform feedback buffer
+   private InternalBuffer mVBO, mTFO; // main vertex buffer and transform feedback buffer
    private final float zFactor;        // strange workaround for the fact that we need to somehow store the 'depth'
                                        // of the Mesh. Used in DistortedEffects. See DistortedTexture.getDepth().
    private int mNumVertices;
@@ -75,8 +75,8 @@ public abstract class MeshBase
      zFactor      = factor;
      mShowNormals = false;
 
-     mVBO = new DistortedBuffer(GLES31.GL_ARRAY_BUFFER             , GLES31.GL_STATIC_READ);
-     mTFO = new DistortedBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, GLES31.GL_STATIC_READ);
+     mVBO = new InternalBuffer(GLES31.GL_ARRAY_BUFFER             , GLES31.GL_STATIC_READ);
+     mTFO = new InternalBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, GLES31.GL_STATIC_READ);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -189,7 +189,7 @@ public abstract class MeshBase
  */
    public void setShowNormals(boolean show)
      {
-     mShowNormals = (Distorted.GLSL >= 300 && show);
+     mShowNormals = (DistortedLibrary.GLSL >= 300 && show);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/mesh/MeshCubes.java b/src/main/java/org/distorted/library/mesh/MeshCubes.java
index 7d66168..36497ba 100644
--- a/src/main/java/org/distorted/library/mesh/MeshCubes.java
+++ b/src/main/java/org/distorted/library/mesh/MeshCubes.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.mesh;
diff --git a/src/main/java/org/distorted/library/mesh/MeshFlat.java b/src/main/java/org/distorted/library/mesh/MeshFlat.java
index 22b0e4a..3721bed 100644
--- a/src/main/java/org/distorted/library/mesh/MeshFlat.java
+++ b/src/main/java/org/distorted/library/mesh/MeshFlat.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.mesh;
diff --git a/src/main/java/org/distorted/library/mesh/MeshQuad.java b/src/main/java/org/distorted/library/mesh/MeshQuad.java
index 5353988..ff519e7 100644
--- a/src/main/java/org/distorted/library/mesh/MeshQuad.java
+++ b/src/main/java/org/distorted/library/mesh/MeshQuad.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.mesh;
diff --git a/src/main/java/org/distorted/library/mesh/MeshSphere.java b/src/main/java/org/distorted/library/mesh/MeshSphere.java
index c4c84b6..370bb6f 100644
--- a/src/main/java/org/distorted/library/mesh/MeshSphere.java
+++ b/src/main/java/org/distorted/library/mesh/MeshSphere.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.mesh;
diff --git a/src/main/java/org/distorted/library/message/EffectListener.java b/src/main/java/org/distorted/library/message/EffectListener.java
index fa54980..5a240da 100644
--- a/src/main/java/org/distorted/library/message/EffectListener.java
+++ b/src/main/java/org/distorted/library/message/EffectListener.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.message;
@@ -24,7 +24,7 @@ package org.distorted.library.message;
 import org.distorted.library.main.DistortedEffects;
 
 /**
- * This interface lets users of the Distorted library get notified when something happens to one of the effects.
+ * This interface lets users of the DistortedLibrary library get notified when something happens to one of the effects.
  * To receive the notifications, we first have to register with a call to {@link DistortedEffects#registerForMessages(EffectListener)}.
  * List of all possible events that can happen is defined in {@link EffectMessage}
  */
diff --git a/src/main/java/org/distorted/library/message/EffectMessage.java b/src/main/java/org/distorted/library/message/EffectMessage.java
index 5ccf38d..505584a 100644
--- a/src/main/java/org/distorted/library/message/EffectMessage.java
+++ b/src/main/java/org/distorted/library/message/EffectMessage.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.message;
diff --git a/src/main/java/org/distorted/library/message/EffectMessageSender.java b/src/main/java/org/distorted/library/message/EffectMessageSender.java
index 9dd9f02..75d73fc 100644
--- a/src/main/java/org/distorted/library/message/EffectMessageSender.java
+++ b/src/main/java/org/distorted/library/message/EffectMessageSender.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.message;
diff --git a/src/main/java/org/distorted/library/program/DistortedProgram.java b/src/main/java/org/distorted/library/program/DistortedProgram.java
index e876216..fa066e0 100644
--- a/src/main/java/org/distorted/library/program/DistortedProgram.java
+++ b/src/main/java/org/distorted/library/program/DistortedProgram.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
diff --git a/src/main/java/org/distorted/library/program/FragmentCompilationException.java b/src/main/java/org/distorted/library/program/FragmentCompilationException.java
index adbba4d..af23d1a 100644
--- a/src/main/java/org/distorted/library/program/FragmentCompilationException.java
+++ b/src/main/java/org/distorted/library/program/FragmentCompilationException.java
@@ -1,30 +1,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 
 /**
- *  Thrown by {@link Distorted#onCreate(android.content.Context)}
+ *  Thrown by {@link DistortedLibrary#onCreate(android.content.Context)}
  *  if compilation of the fragment shader fails for some other reason than too many uniforms.
  *  <p>
  *  This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in the shaders.
diff --git a/src/main/java/org/distorted/library/program/FragmentUniformsException.java b/src/main/java/org/distorted/library/program/FragmentUniformsException.java
index b78fc70..43df4ab 100644
--- a/src/main/java/org/distorted/library/program/FragmentUniformsException.java
+++ b/src/main/java/org/distorted/library/program/FragmentUniformsException.java
@@ -1,30 +1,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 
 /**
- *  Thrown by {@link Distorted#onCreate(android.content.Context)}
+ *  Thrown by {@link DistortedLibrary#onCreate(android.content.Context)}
  *  if compilation of the fragment shader fails because of too many uniforms there, i.e. because
  *  we have set {@link DistortedEffects#setMax(org.distorted.library.effect.EffectType.FRAGMENT, int)}
  *  to too high value.
diff --git a/src/main/java/org/distorted/library/program/LinkingException.java b/src/main/java/org/distorted/library/program/LinkingException.java
index 8a0c2a6..14f995d 100644
--- a/src/main/java/org/distorted/library/program/LinkingException.java
+++ b/src/main/java/org/distorted/library/program/LinkingException.java
@@ -1,30 +1,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 
 /**
- *  Thrown by {@link Distorted#onCreate(android.content.Context)}
+ *  Thrown by {@link DistortedLibrary#onCreate(android.content.Context)}
  *  if linking of the Shaders fails.
  *  <p>
  *  Theoretically this should never happen.
diff --git a/src/main/java/org/distorted/library/program/VertexCompilationException.java b/src/main/java/org/distorted/library/program/VertexCompilationException.java
index ed0d286..e0f30b9 100644
--- a/src/main/java/org/distorted/library/program/VertexCompilationException.java
+++ b/src/main/java/org/distorted/library/program/VertexCompilationException.java
@@ -1,30 +1,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 
 /**
- *  Thrown by {@link Distorted#onCreate(android.content.Context)}
+ *  Thrown by {@link DistortedLibrary#onCreate(android.content.Context)}
  *  if compilation of the vertex shader fails for some other reason than too many uniforms.
  *  <p>
  *  This can happen on older OpenGL ES 2.0 devices if they, say, do not support variable loops in the shaders.
diff --git a/src/main/java/org/distorted/library/program/VertexUniformsException.java b/src/main/java/org/distorted/library/program/VertexUniformsException.java
index 67db105..23eb73e 100644
--- a/src/main/java/org/distorted/library/program/VertexUniformsException.java
+++ b/src/main/java/org/distorted/library/program/VertexUniformsException.java
@@ -1,30 +1,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.program;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.Distorted;
+import org.distorted.library.main.DistortedLibrary;
 
 /**
- *  Thrown by {@link Distorted#onCreate(android.content.Context)}
+ *  Thrown by {@link DistortedLibrary#onCreate(android.content.Context)}
  *  if compilation of the Vertex Shader fails because of too many uniforms there, i.e. because
  *  we have set {@link DistortedEffects#setMax(org.distorted.library.effect.EffectType.VERTEX, int)}
  *  to too high value.
diff --git a/src/main/java/org/distorted/library/type/Data1D.java b/src/main/java/org/distorted/library/type/Data1D.java
index 2ea7db1..2f324ab 100644
--- a/src/main/java/org/distorted/library/type/Data1D.java
+++ b/src/main/java/org/distorted/library/type/Data1D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Data2D.java b/src/main/java/org/distorted/library/type/Data2D.java
index 8bfbb88..46480af 100644
--- a/src/main/java/org/distorted/library/type/Data2D.java
+++ b/src/main/java/org/distorted/library/type/Data2D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Data3D.java b/src/main/java/org/distorted/library/type/Data3D.java
index 5895823..d193d1e 100644
--- a/src/main/java/org/distorted/library/type/Data3D.java
+++ b/src/main/java/org/distorted/library/type/Data3D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Data4D.java b/src/main/java/org/distorted/library/type/Data4D.java
index 2609a76..60eeac5 100644
--- a/src/main/java/org/distorted/library/type/Data4D.java
+++ b/src/main/java/org/distorted/library/type/Data4D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Data5D.java b/src/main/java/org/distorted/library/type/Data5D.java
index 526f3b8..740489c 100644
--- a/src/main/java/org/distorted/library/type/Data5D.java
+++ b/src/main/java/org/distorted/library/type/Data5D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic.java b/src/main/java/org/distorted/library/type/Dynamic.java
index 9139f7f..a03497a 100644
--- a/src/main/java/org/distorted/library/type/Dynamic.java
+++ b/src/main/java/org/distorted/library/type/Dynamic.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic1D.java b/src/main/java/org/distorted/library/type/Dynamic1D.java
index 64e719d..c5fe862 100644
--- a/src/main/java/org/distorted/library/type/Dynamic1D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic1D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic2D.java b/src/main/java/org/distorted/library/type/Dynamic2D.java
index 9ee1f57..3453918 100644
--- a/src/main/java/org/distorted/library/type/Dynamic2D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic2D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic3D.java b/src/main/java/org/distorted/library/type/Dynamic3D.java
index 1de10b1..3aa426a 100644
--- a/src/main/java/org/distorted/library/type/Dynamic3D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic3D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic4D.java b/src/main/java/org/distorted/library/type/Dynamic4D.java
index 148d766..3fda854 100644
--- a/src/main/java/org/distorted/library/type/Dynamic4D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic4D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Dynamic5D.java b/src/main/java/org/distorted/library/type/Dynamic5D.java
index 50a852e..ee96cd3 100644
--- a/src/main/java/org/distorted/library/type/Dynamic5D.java
+++ b/src/main/java/org/distorted/library/type/Dynamic5D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/DynamicQuat.java b/src/main/java/org/distorted/library/type/DynamicQuat.java
index 2be4329..417a0fd 100644
--- a/src/main/java/org/distorted/library/type/DynamicQuat.java
+++ b/src/main/java/org/distorted/library/type/DynamicQuat.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static.java b/src/main/java/org/distorted/library/type/Static.java
index abe1865..08cc222 100644
--- a/src/main/java/org/distorted/library/type/Static.java
+++ b/src/main/java/org/distorted/library/type/Static.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static1D.java b/src/main/java/org/distorted/library/type/Static1D.java
index b8345bc..4034328 100644
--- a/src/main/java/org/distorted/library/type/Static1D.java
+++ b/src/main/java/org/distorted/library/type/Static1D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static2D.java b/src/main/java/org/distorted/library/type/Static2D.java
index 70b7e22..87469c2 100644
--- a/src/main/java/org/distorted/library/type/Static2D.java
+++ b/src/main/java/org/distorted/library/type/Static2D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static3D.java b/src/main/java/org/distorted/library/type/Static3D.java
index da3b591..4284e80 100644
--- a/src/main/java/org/distorted/library/type/Static3D.java
+++ b/src/main/java/org/distorted/library/type/Static3D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static4D.java b/src/main/java/org/distorted/library/type/Static4D.java
index 78c5fc9..f944a2d 100644
--- a/src/main/java/org/distorted/library/type/Static4D.java
+++ b/src/main/java/org/distorted/library/type/Static4D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/java/org/distorted/library/type/Static5D.java b/src/main/java/org/distorted/library/type/Static5D.java
index 47f5a37..2c454b4 100644
--- a/src/main/java/org/distorted/library/type/Static5D.java
+++ b/src/main/java/org/distorted/library/type/Static5D.java
@@ -1,20 +1,20 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                               //
 //                                                                                               //
-// This file is part of Distorted.                                                               //
+// This file is part of DistortedLibrary.                                                               //
 //                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
+// DistortedLibrary is free software: you can redistribute it and/or modify                             //
 // it under the terms of the GNU General Public License as published by                          //
 // the Free Software Foundation, either version 2 of the License, or                             //
 // (at your option) any later version.                                                           //
 //                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
+// DistortedLibrary is distributed in the hope that it will be useful,                                  //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 // GNU General Public License for more details.                                                  //
 //                                                                                               //
 // You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 package org.distorted.library.type;
diff --git a/src/main/res/raw/blit_depth_fragment_shader.glsl b/src/main/res/raw/blit_depth_fragment_shader.glsl
index 889ccef..d297622 100644
--- a/src/main/res/raw/blit_depth_fragment_shader.glsl
+++ b/src/main/res/raw/blit_depth_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/blit_depth_vertex_shader.glsl b/src/main/res/raw/blit_depth_vertex_shader.glsl
index 4047179..9044de2 100644
--- a/src/main/res/raw/blit_depth_vertex_shader.glsl
+++ b/src/main/res/raw/blit_depth_vertex_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/blit_fragment_shader.glsl b/src/main/res/raw/blit_fragment_shader.glsl
index fa99194..3cf5948 100644
--- a/src/main/res/raw/blit_fragment_shader.glsl
+++ b/src/main/res/raw/blit_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision lowp float;
diff --git a/src/main/res/raw/blit_vertex_shader.glsl b/src/main/res/raw/blit_vertex_shader.glsl
index 88b64b1..ab6790b 100644
--- a/src/main/res/raw/blit_vertex_shader.glsl
+++ b/src/main/res/raw/blit_vertex_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision lowp float;
diff --git a/src/main/res/raw/main_fragment_shader.glsl b/src/main/res/raw/main_fragment_shader.glsl
index 4809b6e..95b7a65 100644
--- a/src/main/res/raw/main_fragment_shader.glsl
+++ b/src/main/res/raw/main_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index b3f3f91..24c0e49 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/normal_fragment_shader.glsl b/src/main/res/raw/normal_fragment_shader.glsl
index 963f0f3..f099810 100644
--- a/src/main/res/raw/normal_fragment_shader.glsl
+++ b/src/main/res/raw/normal_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision lowp float;
diff --git a/src/main/res/raw/normal_vertex_shader.glsl b/src/main/res/raw/normal_vertex_shader.glsl
index 83ab55b..f586cbf 100644
--- a/src/main/res/raw/normal_vertex_shader.glsl
+++ b/src/main/res/raw/normal_vertex_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision lowp float;
diff --git a/src/main/res/raw/oit_build_fragment_shader.glsl b/src/main/res/raw/oit_build_fragment_shader.glsl
index 3ad6b4d..484aefc 100644
--- a/src/main/res/raw/oit_build_fragment_shader.glsl
+++ b/src/main/res/raw/oit_build_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/oit_clear_fragment_shader.glsl b/src/main/res/raw/oit_clear_fragment_shader.glsl
index 18eceb1..a10ba08 100644
--- a/src/main/res/raw/oit_clear_fragment_shader.glsl
+++ b/src/main/res/raw/oit_clear_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/oit_collapse_fragment_shader.glsl b/src/main/res/raw/oit_collapse_fragment_shader.glsl
index 1077e92..2f62314 100644
--- a/src/main/res/raw/oit_collapse_fragment_shader.glsl
+++ b/src/main/res/raw/oit_collapse_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/oit_render_fragment_shader.glsl b/src/main/res/raw/oit_render_fragment_shader.glsl
index b9d5997..e55922e 100644
--- a/src/main/res/raw/oit_render_fragment_shader.glsl
+++ b/src/main/res/raw/oit_render_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2018 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/oit_vertex_shader.glsl b/src/main/res/raw/oit_vertex_shader.glsl
index 86dcf4c..0a80a30 100644
--- a/src/main/res/raw/oit_vertex_shader.glsl
+++ b/src/main/res/raw/oit_vertex_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
diff --git a/src/main/res/raw/preprocess_fragment_shader.glsl b/src/main/res/raw/preprocess_fragment_shader.glsl
index 6953a90..904c3a7 100644
--- a/src/main/res/raw/preprocess_fragment_shader.glsl
+++ b/src/main/res/raw/preprocess_fragment_shader.glsl
@@ -1,20 +1,20 @@
 //////////////////////////////////////////////////////////////////////////////////////////////
 // Copyright 2016 Leszek Koltunski                                                          //
 //                                                                                          //
-// This file is part of Distorted.                                                          //
+// This file is part of DistortedLibrary.                                                          //
 //                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
+// DistortedLibrary is free software: you can redistribute it and/or modify                        //
 // it under the terms of the GNU General Public License as published by                     //
 // the Free Software Foundation, either version 2 of the License, or                        //
 // (at your option) any later version.                                                      //
 //                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
+// DistortedLibrary is distributed in the hope that it will be useful,                             //
 // but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
 // GNU General Public License for more details.                                             //
 //                                                                                          //
 // You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                       //
 //////////////////////////////////////////////////////////////////////////////////////////////
 
 precision highp float;
