commit 88c7b603197e34a72ff4d579dba78ed49594b768
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Thu May 17 16:33:56 2018 +0100

    Reengineer DistortedScreen

diff --git a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
index b3a158f..16c7105 100644
--- a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
@@ -31,11 +31,6 @@ import android.opengl.GLES31;
 public class DistortedFramebuffer extends DistortedOutputSurface implements DistortedInputSurface
   {
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void prepareDebug(long time) {}
-  void renderDebug(long time)  {}
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Must be called from a thread holding OpenGL Context
 
diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
index 6de2cd8..b57e314 100644
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
@@ -34,13 +34,6 @@ import java.util.ArrayList;
  */
 public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedMaster.Slave
 {
-//////////// DEBUG FLAGS /////////////////////////////////////////////
-/**
- * When rendering a Screen, show FPS in the upper-left corner?
- */
-public static final int DEBUG_FPS = 1;
-//////////// END DEBUG FLAGS /////////////////////////////////////////
-
 /**
  * Do not create DEPTH or STENCIL attachment
  */
@@ -96,18 +89,11 @@ public static final int DEBUG_FPS = 1;
   private int mClear;
   float mMipmap;
 
-  private int mDebugLevel;
-
   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.
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  abstract void prepareDebug(long time);
-  abstract void renderDebug(long time);
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   DistortedOutputSurface(int width, int height, int createColor, int numcolors, int depthStencil, int fbo, int type)
@@ -129,7 +115,6 @@ public static final int DEBUG_FPS = 1;
     mDepthStencilH[0]= 0;
 
     mTime = 0;
-    mDebugLevel = 0;
 
     mClearR = 0.0f;
     mClearG = 0.0f;
@@ -371,7 +356,23 @@ public static final int DEBUG_FPS = 1;
 
     DistortedRenderState.enableStencil();
 
+    // we cannot compare DEPTH24_STENCIL8 format to DEPTH32 which oitRender's fragment shader expects. Remount!
+    if( mDepthStencil==BOTH_DEPTH_STENCIL )
+      {
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0);
+      }
+
     DistortedEffects.oitRender(this, buffer.getWidthCorrection(), buffer.getHeightCorrection() );
+
+    if( mDepthStencil==BOTH_DEPTH_STENCIL )
+      {
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0);
+      }
+
     GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
     GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
 
@@ -402,6 +403,18 @@ public static final int DEBUG_FPS = 1;
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void clear()
+    {
+    DistortedRenderState.colorDepthStencilOn();
+    GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
+    GLES31.glClearDepthf(mClearDepth);
+    GLES31.glClearStencil(mClearStencil);
+    GLES31.glClear(mClear);
+    DistortedRenderState.colorDepthStencilRestore();
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // 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
@@ -521,21 +534,6 @@ public static final int DEBUG_FPS = 1;
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Make the library show various debugging information.
- * <p>
- * Currently only DEBUG_FPS - show FPS in the upper-left corner of every Screen - is defined.
- *
- * @param bitmask 0, or a bitmask of DEBUG_** flags to enable (currently only DEBUG_FPS defined)
- */
-  public void setDebug(int bitmask)
-    {
-    if( this instanceof DistortedScreen )
-      mDebugLevel = bitmask;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 /**
  * Draws all the attached children to this OutputSurface.
  * <p>
@@ -546,8 +544,6 @@ public static final int DEBUG_FPS = 1;
  */
   public int render(long time)
     {
-    if( mDebugLevel!=0 ) prepareDebug(time);
-
     // change tree topology (attach and detach children)
 /*
     boolean changed1 =
@@ -592,8 +588,6 @@ public static final int DEBUG_FPS = 1;
     setAsOutput(time);
     numRenders += renderChildren(time,mNumChildren,mChildren);
 
-    if( mDebugLevel != 0 ) renderDebug(time);
-
     return numRenders;
     }
 
@@ -613,12 +607,7 @@ public static final int DEBUG_FPS = 1;
     if( mTime!=time )
       {
       mTime = time;
-      DistortedRenderState.colorDepthStencilOn();
-      GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
-      GLES31.glClearDepthf(mClearDepth);
-      GLES31.glClearStencil(mClearStencil);
-      GLES31.glClear(mClear);
-      DistortedRenderState.colorDepthStencilRestore();
+      clear();
       }
     }
 
diff --git a/src/main/java/org/distorted/library/main/DistortedScreen.java b/src/main/java/org/distorted/library/main/DistortedScreen.java
index e74025c..f7493a7 100644
--- a/src/main/java/org/distorted/library/main/DistortedScreen.java
+++ b/src/main/java/org/distorted/library/main/DistortedScreen.java
@@ -34,9 +34,11 @@ import org.distorted.library.type.Static3D;
  * <p>
  * User is able to render to it just like to a DistortedFramebuffer.
  */
-public class DistortedScreen extends DistortedOutputSurface
+public class DistortedScreen extends DistortedFramebuffer
   {
   ///// DEBUGGING ONLY /////////////////////////
+  private boolean mShowFPS;
+
   private static final int NUM_FRAMES  = 100;
 
   private MeshObject fpsMesh;
@@ -46,27 +48,90 @@ public class DistortedScreen extends DistortedOutputSurface
   private Bitmap fpsBitmap;
   private Paint mPaint;
   private int fpsH, fpsW;
-  private String fpsString = "";
+  private String fpsString;
   private long lastTime=0;
   private long[] durations;
   private int currDuration;
   private static MatrixEffectMove mMoveEffect = new MatrixEffectMove( new Static3D(5,5,0) );
-  private boolean mInitialized;
+  ///// END DEBUGGING //////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// here we don't manage underlying OpenGL assets ourselves
-
-  void create()   {}
-  void delete()   {}
-  void recreate() {}
+// PUBLIC API
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Create a new Screen. Initially 1x1 in size.
+ * <p>
+ * Has to be followed by a 'resize()' to set the size.
+ */
+  public DistortedScreen()
+    {
+    super(1,1,1,BOTH_DEPTH_STENCIL);
+    mShowFPS = false;
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * 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.
+ * @return Number of objects rendered.
+ */
+  public int render(long time)
+    {
+    if( mShowFPS )
+      {
+      if( lastTime==0 ) lastTime = time;
 
-  private void initialize()
+      currDuration++;
+      if (currDuration >= NUM_FRAMES) currDuration = 0;
+      durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
+      durations[currDuration] = time - lastTime;
+
+      fpsString = "" + ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
+
+      mPaint.setColor(0xffffffff);
+      fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
+      mPaint.setColor(0xff000000);
+      fpsCanvas.drawText(fpsString, fpsW/2, 0.75f*fpsH, mPaint);
+      fpsTexture.setTexture(fpsBitmap);
+
+      lastTime = time;
+      }
+
+    int numrender = super.render(time);
+
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
+    clear();
+    setAsInput();
+    GLES31.glColorMask(true,true,true,true);
+    GLES31.glDepthMask(false);
+    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+    GLES31.glDisable(GLES31.GL_DEPTH_TEST);
+    DistortedEffects.blitPriv(this);
+
+    if( mShowFPS && fpsTexture.setAsInput())
+      {
+      fpsEffects.drawPriv(fpsW / 2.0f, fpsH / 2.0f, fpsMesh, this, time, 0);
+      }
+
+    return numrender+1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Make the library show Frames Per Second in the upper-left corner.
+ * <p>
+ */
+  public void showFPS()
     {
+    mShowFPS = true;
+
     fpsW = 120;
     fpsH =  70;
 
+    fpsString = "";
     fpsBitmap = Bitmap.createBitmap(fpsW,fpsH, Bitmap.Config.ARGB_8888);
     fpsMesh = new MeshFlat(1,1);
     fpsTexture = new DistortedTexture(fpsW,fpsH);
@@ -85,61 +150,5 @@ public class DistortedScreen extends DistortedOutputSurface
 
     for(int i=0; i<NUM_FRAMES+1; i++) durations[i]=16;  // Assume FPS will be
     durations[NUM_FRAMES] = NUM_FRAMES*16;              // close to 1000/16 ~ 60
-    mInitialized=true;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void prepareDebug(long time)
-    {
-    if( !mInitialized ) initialize();
-
-    if( lastTime==0 ) lastTime = time;
-
-    currDuration++;
-    if (currDuration >= NUM_FRAMES) currDuration = 0;
-    durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
-    durations[currDuration] = time - lastTime;
-
-    fpsString = "" + ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
-
-    mPaint.setColor(0xffffffff);
-    fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
-    mPaint.setColor(0xff000000);
-    fpsCanvas.drawText(fpsString, fpsW/2, 0.75f*fpsH, mPaint);
-    fpsTexture.setTexture(fpsBitmap);
-
-    lastTime = time;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void renderDebug(long time)
-    {
-    if (fpsTexture.setAsInput())
-      {
-      setAsOutput(time);
-      GLES31.glColorMask(true,true,true,true);
-      GLES31.glDepthMask(false);
-      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
-      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
-      fpsEffects.drawPriv(fpsW/2.0f, fpsH/2.0f, fpsMesh, this, time, 0);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// PUBLIC API
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Create a new Screen.
- * <p>
- * Has to be followed by a 'resize()' to set the size.
- */
-  public DistortedScreen()
-    {
-    // Screen also has to be created (3rd arg 'NOT_CREATED_YET') because of the SSBO inside OutputSurface.
-    super(0,0,NOT_CREATED_YET,1,DEPTH_NO_STENCIL,0,TYPE_USER);
-
-    mInitialized = false;
     }
   }
