commit 95c441a2a11be7844896878e5dfe23cd6b985951
Author: leszek <leszek@koltunski.pl>
Date:   Tue Mar 14 23:49:28 2017 +0000

    Progress with Multiblur.
    
    This introduces some regressions with transparency (see: 'Different Bitmaps' and 'Around the world' )

diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index afd5b1d..9371884 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -230,7 +230,7 @@ public class DistortedEffects
 // DEBUG ONLY
 
   @SuppressWarnings("unused")
-  private void displayBoundingRect(float halfX, float halfY, float halfZ, DistortedOutputSurface surface, float[] mvp, float[] vertices)
+  private void displayBoundingRect(float halfX, float halfY, float halfZ, DistortedOutputSurface surface, float[] mvp, float[] vertices, long currTime)
     {
     int len  = vertices.length/3;
     int minx = Integer.MAX_VALUE;
@@ -264,7 +264,7 @@ public class DistortedEffects
       }
 
     mDebugProgram.useProgram();
-    surface.setAsOutput();
+    surface.setAsOutput(currTime);
 
     Matrix.setIdentityM( mTmpMatrix, 0);
     Matrix.translateM  ( mTmpMatrix, 0, minx-surface.mWidth/2, maxy-surface.mHeight/2, -surface.mDistance);
@@ -286,6 +286,13 @@ public class DistortedEffects
     return mP.mNumEffects==0 ? null : mP.mMainBuffer;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int postprocessPriv(long currTime, DistortedOutputSurface surface)
+    {
+    return mP.postprocess(currTime,surface);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void drawPriv(float halfW, float halfH, MeshObject mesh, DistortedOutputSurface surface, long currTime)
@@ -293,14 +300,13 @@ public class DistortedEffects
     mM.compute(currTime);
     mV.compute(currTime);
     mF.compute(currTime);
-    mP.compute(currTime);
 
     float halfZ = halfW*mesh.zFactor;
     GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight);
 
     mMainProgram.useProgram();
     GLES30.glUniform1i(mMainTextureH, 0);
-    surface.setAsOutput();
+    surface.setAsOutput(currTime);
     mM.send(surface,halfW,halfH,halfZ);
     mV.send(halfW,halfH,halfZ);
     mF.send(halfW,halfH);
diff --git a/src/main/java/org/distorted/library/DistortedNode.java b/src/main/java/org/distorted/library/DistortedNode.java
index 1d9d0f9..02e7426 100644
--- a/src/main/java/org/distorted/library/DistortedNode.java
+++ b/src/main/java/org/distorted/library/DistortedNode.java
@@ -211,6 +211,13 @@ public class DistortedNode implements DistortedAttacheable
     return 0;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int postprocess(long currTime, DistortedOutputSurface surface)
+    {
+    return mEffects.postprocessPriv(currTime,surface);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   DistortedFramebuffer getPostprocessingBuffer()
@@ -234,12 +241,7 @@ public class DistortedNode implements DistortedAttacheable
         numRenders += mChildren.get(i).renderRecursive(currTime);
         }
 
-      mData.mFBO.setAsOutput();
-
-      DistortedRenderState.colorDepthOn();
-
-      GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-      GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
+      mData.mFBO.setAsOutput(currTime);
 
       if( mSurface.setAsInput() )
         {
diff --git a/src/main/java/org/distorted/library/DistortedOutputSurface.java b/src/main/java/org/distorted/library/DistortedOutputSurface.java
index d9db081..c155731 100644
--- a/src/main/java/org/distorted/library/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/DistortedOutputSurface.java
@@ -30,6 +30,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
   private ArrayList<DistortedNode> mChildren;
   private int mNumChildren;   // ==mChildren.length(), but we only create mChildren if the first one gets added
 
+  private long mTime;
   private float mFOV;
   int mWidth,mHeight,mDepth;
   float mDistance, mNear;
@@ -61,6 +62,8 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     mFBOH[0]     = fbo;
     mDepthH[0]   = 0;
 
+    mTime = 0;
+
     createProjection();
     }
 
@@ -111,7 +114,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     int numRenders = 0;
     DistortedNode child;
     DistortedFramebuffer fbo;
-    DistortedOutputSurface buffer;
+    DistortedOutputSurface surface;
 
     // 1. Render all children that have postprocessing effects to their own buffer FBOs
 
@@ -130,7 +133,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     // 2. If we have rendered anything so far, and we are a Screen, then render to an
     //    intermediate FBO instead.
 
-    buffer = numRenders>0 ? getBuffer() : this;
+    surface = this;//numRenders>0 ? getBuffer() : this;
 
     // 3. Render all children without postprocessing effects to buffer
 
@@ -141,7 +144,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
 
       if( fbo==null )
         {
-        numRenders += child.draw(time,buffer);
+        numRenders += child.draw(time,surface);
         }
       }
 
@@ -149,11 +152,14 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
     //       postprocess fbo
     //       merge to buffer
 
-    // TODO
+    for(int i=0; i<num; i++)
+      {
+      numRenders += children.get(i).postprocess(time,surface);
+      }
 
     // 5. finally blit to this if we have to
 
-    if( buffer!=this && ((DistortedFramebuffer)buffer).setAsInput() )
+    if( surface!=this && ((DistortedFramebuffer)surface).setAsInput() )
       {
       numRenders++;
       DistortedEffects.blitPriv(this);
@@ -215,7 +221,7 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
       numRenders += mChildren.get(i).renderRecursive(time);
       }
 
-    setAsOutput();
+    setAsOutput(time);
     numRenders += renderChildren(time,mNumChildren,mChildren);
 
     return numRenders;
@@ -225,9 +231,17 @@ abstract class DistortedOutputSurface extends DistortedSurface implements Distor
 /**
  * Bind this Surface as a Framebuffer we can render to.
  */
-  public void setAsOutput()
+  public void setAsOutput(long time)
     {
     GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
+
+    if( mTime!=time )
+      {
+      mTime = time;
+      DistortedRenderState.colorDepthOn();
+      GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+      GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
index aed0bdd..2074bdf 100644
--- a/src/main/java/org/distorted/library/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/EffectQueuePostprocess.java
@@ -137,9 +137,9 @@ class EffectQueuePostprocess extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
   
-  synchronized void compute(long currTime) 
+  synchronized boolean compute(long currTime)
     {
-    if( currTime==mTime ) return;
+    if( currTime==mTime ) return false;
     if( mTime==0 ) mTime = currTime;
     long step = (currTime-mTime);
    
@@ -166,7 +166,9 @@ class EffectQueuePostprocess extends EffectQueue
         }
       }
      
-    mTime = currTime;  
+    mTime = currTime;
+
+    return true;
     }  
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -227,55 +229,58 @@ class EffectQueuePostprocess extends EffectQueue
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// w,h - width and height of the input texture. MVP - Model-View-Projection matrix to apply to the
-// texture; df - output FBO.
 
-  synchronized void render(float w, float h, float[] mvp, DistortedOutputSurface surface)
+  int postprocess(long time, DistortedOutputSurface surface)
     {
-    mBlurProgram.useProgram();
-
-    int radius = (int)mUniforms[0];
-    if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
-    computeGaussianKernel(radius);
+    if( mNumEffects>0 && compute(time) )
+      {
+      mMainBuffer.setAsInput();
+
+      Matrix.setIdentityM(mTmpMatrix, 0);
+      Matrix.translateM(mTmpMatrix, 0, 0, 0, -surface.mDistance);
+      Matrix.multiplyMM(mMVPMatrix, 0, surface.mProjectionMatrix, 0, mTmpMatrix, 0);
+
+      float w = surface.mWidth;
+      float h = surface.mHeight;
+
+      mBlurProgram.useProgram();
+
+      int radius = (int)mUniforms[0];
+      if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
+      computeGaussianKernel(radius);
+
+      int offset = radius + radius*radius/4;
+      radius = (radius+1)/2;
+      for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h;
+
+      GLES30.glUniform1fv( mWeightsH, radius+1, weightsCache,offset);
+      GLES30.glUniform1i( mRadiusH, radius);
+      GLES30.glUniform2f( mObjDH , w, h );
+
+      mPostBuffer.resizeFast( (int)w, (int)h);
+      mPostBuffer.setAsOutput(time);
+      GLES30.glViewport(0, 0, (int)w, (int)h);
+
+      Matrix.setIdentityM(mTmpMatrix, 0);
+      Matrix.translateM(mTmpMatrix, 0, 0, 0, -mPostBuffer.mDistance);
+      Matrix.multiplyMM(mMVPMatrix, 0, mPostBuffer.mProjectionMatrix, 0, mTmpMatrix, 0);
+
+      // horizontal blur
+      GLES30.glUniform1fv( mOffsetsH ,radius+1, mOffsets,0);
+      GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
+      GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
+      GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTextureInv);
+      GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+
+      // vertical blur
+      mPostBuffer.setAsInput();
+      surface.setAsOutput(time);
+      for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
+      GLES30.glUniform1fv( mOffsetsH ,radius+1, mOffsets,0);
+      GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+      }
 
-    int offset = radius + radius*radius/4;
-    radius = (radius+1)/2;
-    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h;
-
-    GLES30.glUniform1fv( mWeightsH, radius+1, weightsCache,offset);
-    GLES30.glUniform1i( mRadiusH, radius);
-    GLES30.glUniform2f( mObjDH , w, h );
-
-    mPostBuffer.resizeFast( (int)w, (int)h);
-    mPostBuffer.setAsOutput();
-    GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-    GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    GLES30.glViewport(0, 0, (int)w, (int)h);
-
-    Matrix.setIdentityM(mTmpMatrix, 0);
-    Matrix.translateM(mTmpMatrix, 0, 0, 0, -mPostBuffer.mDistance);
-    Matrix.multiplyMM(mMVPMatrix, 0, mPostBuffer.mProjectionMatrix, 0, mTmpMatrix, 0);
-
-    // horizontal blur
-    GLES30.glUniform1fv( mOffsetsH ,radius+1, mOffsets,0);
-    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
-    GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTextureInv);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
-
-    mPostBuffer.setAsInput();
-    surface.setAsOutput();
-
-    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight);
-
-    for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
-
-    // vertical blur
-    GLES30.glUniform1fv( mOffsetsH ,radius+1, mOffsets,0);
-    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mvp , 0);
-    GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mBlurProgram.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTextureInv);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    return mNumEffects;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
