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