commit e6cf7d5079b4648c8a888abfe100103c3ef4a122
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Fri Dec 9 01:10:27 2016 +0000

    1. (hopefully) finish the 'Save' app (now we can adjust the size of the resulting file)
    2. Fix one long-standing bug in almost every single app.

diff --git a/src/main/java/org/distorted/library/DistortedFramebuffer.java b/src/main/java/org/distorted/library/DistortedFramebuffer.java
index a0a4eb7..6f6f1b4 100644
--- a/src/main/java/org/distorted/library/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/DistortedFramebuffer.java
@@ -56,23 +56,24 @@ public class DistortedFramebuffer
 
   private boolean mMarked;
 
-  int mWidth,mHeight,mDepth,mDistance;
+  int mWidth,mHeight,mDepth;
+  float mDistance;
   float[] mProjectionMatrix;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private void createProjection()
     {
-    if( mWidth>0 && mHeight>0 )
+    if( mWidth>0 && mHeight>1 )
       {
       if( mFOV>0.0f )  // perspective projection
         {
-        float left   = (-mX-mWidth/2 )/mHeight;
-        float right  = (-mX+mWidth/2 )/mHeight;
-        float bottom = (-mY-mHeight/2)/mHeight;
-        float top    = (-mY+mHeight/2)/mHeight;
-        float near   = (float)( (top-bottom) / (2*Math.tan(mFOV*Math.PI/360)) );
-        mDistance    = (int)(mHeight*near/(top-bottom));
+        float left   = (-mX-mWidth /2.0f)/mHeight;
+        float right  = (-mX+mWidth /2.0f)/mHeight;
+        float bottom = (-mY-mHeight/2.0f)/mHeight;
+        float top    = (-mY+mHeight/2.0f)/mHeight;
+        float near   = (top-bottom) / (2.0f*(float)Math.tan(mFOV*Math.PI/360));
+        mDistance    = mHeight*near/(top-bottom);
         float far    = 2*mDistance-near;
         mDepth       = (int)((far-near)/2);
 
@@ -80,12 +81,12 @@ public class DistortedFramebuffer
         }
       else             // parallel projection
         {
-        float left   = -mX-mWidth/2;
-        float right  = -mX+mWidth/2;
-        float bottom = -mY-mHeight/2;
-        float top    = -mY+mHeight/2;
-        float near   = (float)( (top-bottom) / (2*Math.tan(Math.PI/360)) );
-        mDistance    = (int)(mHeight*near/(top-bottom));
+        float left   = -mX-mWidth /2.0f;
+        float right  = -mX+mWidth /2.0f;
+        float bottom = -mY-mHeight/2.0f;
+        float top    = -mY+mHeight/2.0f;
+        float near   = (top-bottom) / (2.0f*(float)Math.tan(Math.PI/360));
+        mDistance    = mHeight*near/(top-bottom);
         float far    = 2*mDistance-near;
         mDepth       = (int)((far-near)/2);
 
@@ -130,27 +131,21 @@ public class DistortedFramebuffer
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called form a thread holding OpenGL Context
+// must be called from a thread holding OpenGL Context
 
   private void deleteFBO()
     {
-    android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]);
-
-    GLES20.glDeleteTextures(1, texIds, 0);
-    GLES20.glDeleteFramebuffers(1, fboIds, 0);
-
-    fboIds[0] = 0;
-    texIds[0] = TEXTURE_NOT_CREATED_YET;
-    }
+    if( texIds[0]>=0 )
+      {
+      android.util.Log.e("FBO", "deleting ("+mWidth+","+mHeight+") "+fboIds[0]);
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
+      GLES20.glDeleteTextures(1, texIds, 0);
+      GLES20.glDeleteFramebuffers(1, fboIds, 0);
 
-  private void delete()
-    {
-    if( texIds[0]>=0 ) deleteFBO();
+      fboIds[0] = 0;
+      texIds[0] = TEXTURE_NOT_CREATED_YET;
+      }
 
-    mProjectionMatrix = null;
     mMarked = false;
     }
 
@@ -185,7 +180,7 @@ public class DistortedFramebuffer
 
         if( tmp.mMarked )
           {
-          tmp.delete();
+          tmp.deleteFBO();
           iterator.remove();
           }
         }
