commit 985ea9c58e76fff94a2d1153d8edd785abf10952
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Tue Aug 9 13:11:57 2016 +0100

    Finally fix the 'when rendering though an FBO, the other side of triangles is visible'

diff --git a/src/main/java/org/distorted/library/DistortedBitmapGrid.java b/src/main/java/org/distorted/library/DistortedBitmapGrid.java
index 45ba0f3..b2de13c 100644
--- a/src/main/java/org/distorted/library/DistortedBitmapGrid.java
+++ b/src/main/java/org/distorted/library/DistortedBitmapGrid.java
@@ -68,7 +68,7 @@ class DistortedBitmapGrid extends DistortedObjectGrid
      position[3*vertex+2] = 0;
 
      texture[2*vertex  ]  = x;
-     texture[2*vertex+1]  = y;
+     texture[2*vertex+1]  = 1.0f-y;
 
      normal[3*vertex  ]   = 0.0f;
      normal[3*vertex+1]   = 0.0f;
diff --git a/src/main/java/org/distorted/library/DistortedCubesGrid.java b/src/main/java/org/distorted/library/DistortedCubesGrid.java
index 4fe68bc..2a0c74e 100644
--- a/src/main/java/org/distorted/library/DistortedCubesGrid.java
+++ b/src/main/java/org/distorted/library/DistortedCubesGrid.java
@@ -36,11 +36,6 @@ class DistortedCubesGrid extends DistortedObjectGrid
    private static final int EAST  = 2;
    private static final int SOUTH = 3;
 
-   private static final int NW = 0;
-   private static final int NE = 1;
-   private static final int SW = 2;
-   private static final int SE = 3;
-
    private static final boolean BACK  = true;
    private static final boolean FRONT = false;
    private static final boolean UPPER = false;
@@ -427,7 +422,7 @@ class DistortedCubesGrid extends DistortedObjectGrid
      normal[3*vertex+1]   = mNormalY[index];
      normal[3*vertex+2]   = mNormalZ[index];
      texture[2*vertex  ]  = x;
-     texture[2*vertex+1]  = y;
+     texture[2*vertex+1]  = 1.0f-y;
 
      return vertex+1;
      }
@@ -655,35 +650,40 @@ class DistortedCubesGrid extends DistortedObjectGrid
 
      remainingVert--;
 
-     float centerX = curr.col-(mCols-1.0f)/2.0f;
-     float centerY = (mRows-1.0f)/2.0f-curr.row;
-  
+     float x, y;
+
      switch(curr.side)
        {
-       case NORTH: position[3*vertex  ] = (back ? (centerX-0.5f) : (centerX+0.5f))/mCols;
-                   position[3*vertex+1] = (centerY+0.5f)/mRows;
+       case NORTH: x = (float)(back ? (curr.col  ):(curr.col+1))/mCols;
+
+                   position[3*vertex  ] = x - 0.5f;
+                   position[3*vertex+1] = 0.5f - (float)curr.row/mRows;
                    position[3*vertex+2] = lower ? BACKZ : FRONTZ;
 
                    normal[3*vertex  ]   = side==NORTH ? 0.0f : (side==WEST?-R:R);
                    normal[3*vertex+1]   = 1.0f;
                    normal[3*vertex+2]   = lower ? -R:R;
 
-                   texture[2*vertex  ]  = (float)(back ? (curr.col  ):(curr.col+1))/mCols;
-                   texture[2*vertex+1]  = (float)(lower? (curr.row-1):(curr.row  ))/mRows;  
+                   texture[2*vertex  ]  = x;
+                   texture[2*vertex+1]  = 1.0f-(float)(lower? (curr.row-1):(curr.row  ))/mRows;
                    break;
-       case SOUTH: position[3*vertex  ] = (back ? (centerX+0.5f) : (centerX-0.5f))/mCols;
-                   position[3*vertex+1] = (centerY-0.5f)/mRows;
+       case SOUTH: x = (float)(back ? (curr.col+1):(curr.col  ))/mCols;
+
+                   position[3*vertex  ] = x - 0.5f;
+                   position[3*vertex+1] = 0.5f - (float)(curr.row+1)/mRows;
                    position[3*vertex+2] = lower ? BACKZ : FRONTZ;  
             
                    normal[3*vertex  ]   = side==SOUTH ? 0.0f: (side==EAST?-R:R);
                    normal[3*vertex+1]   =-1.0f;
                    normal[3*vertex+2]   = lower ? -R:R;
 
-                   texture[2*vertex  ]  = (float)(back ? (curr.col+1):(curr.col  ))/mCols;
-                   texture[2*vertex+1]  = (float)(lower? (curr.row+2):(curr.row+1))/mRows;
+                   texture[2*vertex  ]  = x;
+                   texture[2*vertex+1]  = 1.0f-(float)(lower? (curr.row+2):(curr.row+1))/mRows;
                    break;
-       case WEST : position[3*vertex  ] = (centerX-0.5f)/mCols;
-                   position[3*vertex+1] = (back ? (centerY-0.5f):(centerY+0.5f))/mRows;
+       case WEST : y = (float)(back  ? (curr.row+1):(curr.row))/mRows;
+
+                   position[3*vertex  ] = (float)curr.col/mCols -0.5f;
+                   position[3*vertex+1] = 0.5f - y;
                    position[3*vertex+2] = lower ? BACKZ : FRONTZ;
 
                    normal[3*vertex  ]   =-1.0f;
@@ -691,10 +691,12 @@ class DistortedCubesGrid extends DistortedObjectGrid
                    normal[3*vertex+2]   = lower ? -R:R;
  
                    texture[2*vertex  ]  = (float)(lower ? (curr.col-1):(curr.col  ))/mCols;
-                   texture[2*vertex+1]  = (float)(back  ? (curr.row+1):(curr.row  ))/mRows;
+                   texture[2*vertex+1]  = 1.0f - y;
                    break;
-       case EAST : position[3*vertex  ] = (centerX+0.5f)/mCols;
-                   position[3*vertex+1] = (back ? (centerY+0.5f):(centerY-0.5f))/mRows;
+       case EAST : y = (float)(back  ? (curr.row):(curr.row+1))/mRows;
+
+                   position[3*vertex  ] = (float)(curr.col+1)/mCols -0.5f;
+                   position[3*vertex+1] = 0.5f - y;
                    position[3*vertex+2] = lower ? BACKZ : FRONTZ;
 
                    normal[3*vertex  ]   = 1.0f;
@@ -702,7 +704,7 @@ class DistortedCubesGrid extends DistortedObjectGrid
                    normal[3*vertex+2]   = lower ? -R:R; 
 
                    texture[2*vertex  ]  = (float)(lower ? (curr.col+2):(curr.col+1))/mCols;
-                   texture[2*vertex+1]  = (float)(back  ? (curr.row  ):(curr.row+1))/mRows;
+                   texture[2*vertex+1]  = 1.0f - y;
                    break;
        }
      
diff --git a/src/main/java/org/distorted/library/DistortedObject.java b/src/main/java/org/distorted/library/DistortedObject.java
index 83d2c7f..1a0e33e 100644
--- a/src/main/java/org/distorted/library/DistortedObject.java
+++ b/src/main/java/org/distorted/library/DistortedObject.java
@@ -20,6 +20,7 @@
 package org.distorted.library;
 
 import android.graphics.Bitmap;
+import android.graphics.Matrix;
 import android.opengl.GLES20;
 import android.opengl.GLUtils;
 
@@ -52,6 +53,24 @@ public abstract class DistortedObject
   int[] mTextureDataH;           // have to be shared among all the cloned Objects
   boolean[] mBitmapSet;          //
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// We have to flip vertically every single Bitmap that we get fed with.
+//
+// Reason: textures read from files are the only objects in OpenGL which have their origins at the
+// upper-left corner. Everywhere else the origin is in the lower-left corner. Thus we have to flip.
+// The alternative solution, namely inverting the y-coordinate of the TexCoord does not really work-
+// i.e. it works only in case of rendering directly to the screen, but if we render to an FBO and
+// then take the FBO and render to screen, (DistortedNode does so!) things get inverted as textures
+// created from FBO have their origins in the lower-left... Mindfuck!
+
+  private static Bitmap flipBitmap(Bitmap src)
+    {
+    Matrix matrix = new Matrix();
+    matrix.preScale(1.0f,-1.0f);
+
+    return Bitmap.createBitmap(src,0,0,src.getWidth(),src.getHeight(), matrix,true);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   protected abstract DistortedObject deepCopy(int flags);
@@ -129,7 +148,7 @@ public abstract class DistortedObject
        
       if( mBmp!=null && mBmp[0]!=null)
         {
-        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mBmp[0], 0);
+        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(mBmp[0]), 0);
         mBmp[0] = null;
         }
       }
@@ -286,7 +305,7 @@ public abstract class DistortedObject
       {
       GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
       GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataH[0]);
-      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
+      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, flipBitmap(bmp), 0);
       }
     else
       {
