commit 406e2f6bcfba07d699436876c4d7e6b80aa59ed5
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri Jun 29 13:22:57 2018 +0100

    Give users API to render OutputSerfaces and attached Nodes in either the 'normal' way of OIT way.

diff --git a/src/main/java/org/distorted/library/main/DistortedNode.java b/src/main/java/org/distorted/library/main/DistortedNode.java
index b1c80ea..a61e9af 100644
--- a/src/main/java/org/distorted/library/main/DistortedNode.java
+++ b/src/main/java/org/distorted/library/main/DistortedNode.java
@@ -63,6 +63,7 @@ public class DistortedNode implements DistortedMaster.Slave
   private static HashMap<ArrayList<Long>,NodeData> mMapNodeID = new HashMap<>();
   private static long mNextNodeID =0;
 
+  private boolean mRenderWayOIT;
   private DistortedNode mParent;
   private DistortedOutputSurface mSurfaceParent;
   private MeshObject mMesh;
@@ -340,7 +341,7 @@ public class DistortedNode implements DistortedMaster.Slave
         DistortedEffects.blitPriv(mData.mFBO);
         }
 
-      numRenders += mData.mFBO.renderChildren(currTime,mNumChildren[0],mChildren,0);
+      numRenders += mData.mFBO.renderChildren(currTime,mNumChildren[0],mChildren,0, mRenderWayOIT);
       }
 
     return numRenders;
@@ -403,6 +404,7 @@ public class DistortedNode implements DistortedMaster.Slave
     mNumChildren[0]= 0;
     mParent        = null;
     mSurfaceParent = null;
+    mRenderWayOIT  = false;
 
     mFboW            = 0;  // i.e. take this from
     mFboH            = 0;  // mSurface's dimensions
@@ -444,6 +446,7 @@ public class DistortedNode implements DistortedMaster.Slave
     mState        = new DistortedRenderState();
     mParent       = null;
     mSurfaceParent= null;
+    mRenderWayOIT = false;
 
     mFboW            = node.mFboW;
     mFboH            = node.mFboH;
@@ -509,6 +512,21 @@ public class DistortedNode implements DistortedMaster.Slave
     mEffects.newNode(this);
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+  /**
+   * 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;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Adds a new child to the last position in the list of our Node's children.
diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
index 2fe471f..8aea469 100644
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
@@ -54,6 +54,7 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
 
   private ArrayList<DistortedNode> mChildren;
   private int mNumChildren;   // ==mChildren.length(), but we only create mChildren if the first one gets added
+  private boolean mRenderWayOIT;
 
   private class Job
     {
@@ -99,6 +100,8 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
     {
     super(width,height,createColor,numfbos,numcolors,type);
 
+    mRenderWayOIT = false;
+
     mDepthStencilH = new int[numfbos];
     mFBOH          = new int[numfbos];
 
@@ -379,7 +382,7 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
 // 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).
 
-  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children, int fbo)
+  int renderChildren(long time, int numChildren, ArrayList<DistortedNode> children, int fbo, boolean oit)
     {
     int quality=0, internalQuality = 0, numRenders = 0, bucketChange = 0;
     DistortedNode child1, child2;
@@ -406,7 +409,11 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
           if( lastBucket==0 )
             {
             clonePostprocessingViewport(this);
-            oitClear(this);
+
+            if( oit )
+              {
+              oitClear(this);
+              }
             }
           else
             {
@@ -418,8 +425,16 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
               }
 
             numRenders += lastQueue.postprocess(mBuffer,fbo);
-            numRenders += oitBuild(time,mBuffer[quality],fbo);
-            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+
+            if( oit )
+              {
+              numRenders += oitBuild(time, mBuffer[quality], fbo);
+              GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+              }
+            else
+              {
+              numRenders += blitWithDepth(time, mBuffer[quality],fbo);
+              }
             mBuffer[quality].clearBuffer(fbo);
             }
 
@@ -441,10 +456,18 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
             }
 
           numRenders += currQueue.postprocess(mBuffer,fbo);
-          numRenders += oitBuild(time,mBuffer[quality],fbo);
-          GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT|GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
-          numRenders += oitRender(time,fbo);  // merge the OIT linked list
-          mBuffer[quality].clearBuffer(fbo);
+
+          if( oit )
+            {
+            numRenders += oitBuild(time, mBuffer[quality], fbo);
+            GLES31.glMemoryBarrier(GLES31.GL_SHADER_STORAGE_BARRIER_BIT | GLES31.GL_ATOMIC_COUNTER_BARRIER_BIT);
+            numRenders += oitRender(time, fbo);  // merge the OIT linked list
+            mBuffer[quality].clearBuffer(fbo);
+            }
+          else
+            {
+            numRenders += blitWithDepth(time, mBuffer[quality],fbo);
+            }
           }
         } // end else (postprocessed child)
 
@@ -610,7 +633,7 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
       numRenders += mChildren.get(i).renderRecursive(time);
       }
 
-    numRenders += renderChildren(time,mNumChildren,mChildren,fbo);
+    numRenders += renderChildren(time,mNumChildren,mChildren,fbo, mRenderWayOIT);
 
     return numRenders;
     }
@@ -824,6 +847,21 @@ public abstract class DistortedOutputSurface extends DistortedSurface implements
     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;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Adds a new child to the last position in the list of our Surface's children.
