| 142 | 142 |     //android.util.Log.e("Effects", "vertHeader= "+mainVertHeader);
 | 
  | 143 | 143 |     //android.util.Log.e("Effects", "fragHeader= "+mainFragHeader);
 | 
  | 144 | 144 | 
 | 
  | 145 |  |     String[] feedback = { "v_Position","v_Normal","v_TexCoordinate" };
 | 
  |  | 145 |     String[] feedback = { "v_Position", "v_Normal", "v_ndcPosition" };
 | 
  | 146 | 146 | 
 | 
  | 147 | 147 |     mMainProgram = new DistortedProgram(mainVertStream,mainFragStream, mainVertHeader, mainFragHeader, Distorted.GLSL, feedback);
 | 
  | 148 | 148 | 
 | 
  | ... | ... |  | 
  | 231 | 231 |     }
 | 
  | 232 | 232 | 
 | 
  | 233 | 233 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | 234 |  | // DEBUG ONLY
 | 
  | 235 | 234 | 
 | 
  | 236 | 235 |   @SuppressWarnings("unused")
 | 
  | 237 |  |   private void displayBoundingRect(float halfX, float halfY, float halfZ, DistortedOutputSurface surface, float[] mvp, float[] vertices, long currTime)
 | 
  |  | 236 |   private void displayBoundingRect(float halfW, float halfH, DistortedOutputSurface surface, MeshObject mesh)
 | 
  | 238 | 237 |     {
 | 
  | 239 |  |     int len  = vertices.length/3;
 | 
  | 240 |  |     int minx = Integer.MAX_VALUE;
 | 
  | 241 |  |     int maxx = Integer.MIN_VALUE;
 | 
  | 242 |  |     int miny = Integer.MAX_VALUE;
 | 
  | 243 |  |     int maxy = Integer.MIN_VALUE;
 | 
  | 244 |  |     int wx,wy;
 | 
  |  | 238 |     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
 | 
  |  | 239 |     GLES30.glBeginTransformFeedback( GLES30.GL_POINTS);
 | 
  |  | 240 | 
 | 
  |  | 241 |     DistortedRenderState.switchOffDrawing();
 | 
  |  | 242 |     GLES30.glDrawArrays( GLES30.GL_POINTS, 0, mesh.numVertices);
 | 
  |  | 243 |     DistortedRenderState.restoreDrawing();
 | 
  | 245 | 244 | 
 | 
  | 246 |  |     float x,y,z, X,Y,W, ndcX,ndcY;
 | 
  |  | 245 |     int error = GLES30.glGetError();
 | 
  | 247 | 246 | 
 | 
  | 248 |  |     for(int i=0; i<len; i++)
 | 
  |  | 247 |     if( error != GLES30.GL_NO_ERROR )
 | 
  | 249 | 248 |       {
 | 
  | 250 |  |       x = 2*halfX*vertices[3*i  ];
 | 
  | 251 |  |       y = 2*halfY*vertices[3*i+1];
 | 
  | 252 |  |       z = 2*halfZ*vertices[3*i+2];
 | 
  |  | 249 |       throw new RuntimeException("DrawArrays: glError 0x" + Integer.toHexString(error));
 | 
  |  | 250 |       }
 | 
  | 253 | 251 | 
 | 
  | 254 |  |       X = mvp[ 0]*x + mvp[ 4]*y + mvp[ 8]*z + mvp[12];
 | 
  | 255 |  |       Y = mvp[ 1]*x + mvp[ 5]*y + mvp[ 9]*z + mvp[13];
 | 
  | 256 |  |       W = mvp[ 3]*x + mvp[ 7]*y + mvp[11]*z + mvp[15];
 | 
  |  | 252 |     // mapping the buffer range slows down rendering /////////////////////////
 | 
  |  | 253 |     int size = (MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE+MeshObject.NDC_DATA_SIZE)*mesh.numVertices;
 | 
  | 257 | 254 | 
 | 
  | 258 |  |       ndcX = X/W;
 | 
  | 259 |  |       ndcY = Y/W;
 | 
  |  | 255 |     Buffer mappedBuffer =  GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 4*size, GLES30.GL_MAP_READ_BIT);
 | 
  |  | 256 |     FloatBuffer fb = ((ByteBuffer) mappedBuffer).order(ByteOrder.nativeOrder()).asFloatBuffer();
 | 
  |  | 257 |     GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
 | 
  |  | 258 |     // end of slowdown //////////////////////////////////////////////////////
 | 
  | 260 | 259 | 
 | 
  | 261 |  |       wx = (int)(surface.mWidth *(ndcX+1)/2);
 | 
  | 262 |  |       wy = (int)(surface.mHeight*(ndcY+1)/2);
 | 
  |  | 260 |     GLES30.glEndTransformFeedback();
 | 
  |  | 261 |     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
 | 
  |  | 262 | /*
 | 
  |  | 263 |     String msg = "";
 | 
  |  | 264 |     for(int i=0; i<size; i++) msg += (" "+fb.get(i));
 | 
  |  | 265 |     android.util.Log.d( "Feedback", msg);
 | 
  |  | 266 | */
 | 
  |  | 267 |     float minx = Integer.MAX_VALUE;
 | 
  |  | 268 |     float maxx = Integer.MIN_VALUE;
 | 
  |  | 269 |     float miny = Integer.MAX_VALUE;
 | 
  |  | 270 |     float maxy = Integer.MIN_VALUE;
 | 
  |  | 271 |     float ndcX,ndcY;
 | 
  |  | 272 | 
 | 
  |  | 273 |     for(int i=0; i<mesh.numVertices; i++)
 | 
  |  | 274 |       {
 | 
  |  | 275 |       ndcX = fb.get(8*i+6);
 | 
  |  | 276 |       ndcY = fb.get(8*i+7);
 | 
  | 263 | 277 | 
 | 
  | 264 |  |       if( wx<minx ) minx = wx;
 | 
  | 265 |  |       if( wx>maxx ) maxx = wx;
 | 
  | 266 |  |       if( wy<miny ) miny = wy;
 | 
  | 267 |  |       if( wy>maxy ) maxy = wy;
 | 
  |  | 278 |       if( ndcX<minx ) minx = ndcX;
 | 
  |  | 279 |       if( ndcX>maxx ) maxx = ndcX;
 | 
  |  | 280 |       if( ndcY<miny ) miny = ndcY;
 | 
  |  | 281 |       if( ndcY>maxy ) maxy = ndcY;
 | 
  | 268 | 282 |       }
 | 
  | 269 | 283 | 
 | 
  |  | 284 |     minx = surface.mWidth *(minx+1)/2;   //
 | 
  |  | 285 |     miny = surface.mHeight*(miny+1)/2;   // transform from NDC to
 | 
  |  | 286 |     maxx = surface.mWidth *(maxx+1)/2;   // window coordinates
 | 
  |  | 287 |     maxy = surface.mHeight*(maxy+1)/2;   //
 | 
  |  | 288 | 
 | 
  | 270 | 289 |     mDebugProgram.useProgram();
 | 
  | 271 |  |     surface.setAsOutput(currTime);
 | 
  | 272 | 290 | 
 | 
  | 273 | 291 |     Matrix.setIdentityM( mTmpMatrix, 0);
 | 
  | 274 | 292 |     Matrix.translateM  ( mTmpMatrix, 0, minx-surface.mWidth/2, maxy-surface.mHeight/2, -surface.mDistance);
 | 
  | 275 |  |     Matrix.scaleM      ( mTmpMatrix, 0, (float)(maxx-minx)/(2*halfX), (float)(maxy-miny)/(2*halfY), 1.0f);
 | 
  | 276 |  |     Matrix.translateM  ( mTmpMatrix, 0, halfX,-halfY, 0);
 | 
  |  | 293 |     Matrix.scaleM      ( mTmpMatrix, 0, (maxx-minx)/(2*halfW), (maxy-miny)/(2*halfH), 1.0f);
 | 
  |  | 294 |     Matrix.translateM  ( mTmpMatrix, 0, halfW,-halfH, 0);
 | 
  | 277 | 295 |     Matrix.multiplyMM  ( mMVPMatrix, 0, surface.mProjectionMatrix, 0, mTmpMatrix, 0);
 | 
  | 278 | 296 | 
 | 
  | 279 |  |     GLES30.glUniform2f(mDebugObjDH, 2*halfX, 2*halfY);
 | 
  |  | 297 |     GLES30.glUniform2f(mDebugObjDH, 2*halfW, 2*halfH);
 | 
  | 280 | 298 |     GLES30.glUniformMatrix4fv(mDebugMVPMatrixH, 1, false, mMVPMatrix , 0);
 | 
  | 281 | 299 | 
 | 
  | 282 | 300 |     GLES30.glVertexAttribPointer(mDebugProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
 | 
  | 283 | 301 |     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
 | 
  | 284 | 302 |     }
 | 
  | 285 | 303 | 
 | 
  | 286 |  | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | 287 |  | 
 | 
  | 288 |  |   private void displayTransformFeedback(MeshObject mesh)
 | 
  | 289 |  |     {
 | 
  | 290 |  |     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
 | 
  | 291 |  |     GLES30.glBeginTransformFeedback( GLES30.GL_POINTS);
 | 
  | 292 |  | 
 | 
  | 293 |  |     DistortedRenderState.switchOffDrawing();
 | 
  | 294 |  |     GLES30.glDrawArrays( GLES30.GL_POINTS, 0, mesh.numVertices);
 | 
  | 295 |  |     DistortedRenderState.restoreDrawing();
 | 
  | 296 |  | 
 | 
  | 297 |  |     int error = GLES30.glGetError();
 | 
  | 298 |  | 
 | 
  | 299 |  |       if( error != GLES30.GL_NO_ERROR )
 | 
  | 300 |  |         {
 | 
  | 301 |  |         throw new RuntimeException("DrawArrays: glError 0x" + Integer.toHexString(error));
 | 
  | 302 |  |         }
 | 
  | 303 |  | /*
 | 
  | 304 |  |     int size = (MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE+MeshObject.TEX_DATA_SIZE)*mesh.numVertices;
 | 
  | 305 |  | 
 | 
  | 306 |  |     Buffer mappedBuffer =  GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 4*size, GLES30.GL_MAP_READ_BIT);
 | 
  | 307 |  |     FloatBuffer fb = ((ByteBuffer) mappedBuffer).order(ByteOrder.nativeOrder()).asFloatBuffer();
 | 
  | 308 |  |     String msg = "";
 | 
  | 309 |  | 
 | 
  | 310 |  |     for(int i=0; i<size; i++) msg += (" "+fb.get(i));
 | 
  | 311 |  | 
 | 
  | 312 |  |     android.util.Log.d( "Feedback", msg);
 | 
  | 313 |  | 
 | 
  | 314 |  |     GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
 | 
  | 315 |  | */
 | 
  | 316 |  |     GLES30.glEndTransformFeedback();
 | 
  | 317 |  |     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
 | 
  | 318 |  |     }
 | 
  | 319 |  | 
 | 
  | 320 | 304 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
  | 321 | 305 | 
 | 
  | 322 | 306 |   void drawPriv(float halfW, float halfH, MeshObject mesh, DistortedOutputSurface surface, long currTime)
 | 
  | ... | ... |  | 
  | 341 | 325 | 
 | 
  | 342 | 326 |     mM.send(surface,halfW,halfH,halfZ);
 | 
  | 343 | 327 |     mV.send(halfW,halfH,halfZ);
 | 
  | 344 |  | 
 | 
  | 345 |  |     displayTransformFeedback(mesh);
 | 
  | 346 |  | 
 | 
  | 347 |  |     EffectQueueMatrix.sendZero();
 | 
  | 348 |  |     EffectQueueVertex.sendZero();
 | 
  | 349 |  | 
 | 
  | 350 | 328 |     mF.send(halfW,halfH);
 | 
  | 351 | 329 | 
 | 
  | 352 |  |     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
 | 
  | 353 |  |     GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
 | 
  | 354 |  |     GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
 | 
  | 355 |  |     GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
 | 
  | 356 |  |     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
 | 
  | 357 |  | 
 | 
  | 358 | 330 |     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.numVertices);
 | 
  | 359 | 331 | 
 | 
  | 360 |  |     /// DEBUG ONLY //////
 | 
  | 361 |  |     // displayBoundingRect(halfW, halfH, halfZ, surface, mM.getMVP(), mesh.getBoundingVertices() );
 | 
  | 362 |  |     /// END DEBUG ///////
 | 
  |  | 332 |     displayBoundingRect(halfW,halfH,surface,mesh);
 | 
  | 363 | 333 |     }
 | 
  | 364 | 334 | 
 | 
  | 365 | 335 | ///////////////////////////////////////////////////////////////////////////////////////////////////
 | 
 
Dynamic display of bounding rectangles (with coords computed by Vertex Shader and gotten with Transform Feedback) works now.
Major problem: the glMapBufferRange() slows doewn rendering in a major way. Multiblur's FPS:
Nexus5X : 35.4 before -> 12.6 after
Nexus4 26.5 before -> ~12 after