49 |
49 |
private static final int NUM_CACHE = 0;
|
50 |
50 |
private static final int INDEX = EffectTypes.POSTPROCESS.ordinal();
|
51 |
51 |
|
52 |
|
private static final FloatBuffer mQuadPositions, mQuadTexture;
|
|
52 |
private static final FloatBuffer mQuadPositions, mQuadTexture, mQuadTextureInv;
|
53 |
53 |
|
54 |
54 |
static
|
55 |
55 |
{
|
... | ... | |
58 |
58 |
|
59 |
59 |
float[] position = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f,-0.5f, 0.5f, 0.5f };
|
60 |
60 |
float[] textureNor= { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
|
|
61 |
float[] textureInv= { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f };
|
61 |
62 |
|
62 |
63 |
mQuadPositions = ByteBuffer.allocateDirect(POS_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
63 |
64 |
mQuadPositions.put(position).position(0);
|
64 |
65 |
mQuadTexture= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
65 |
66 |
mQuadTexture.put(textureNor).position(0);
|
|
67 |
mQuadTextureInv= ByteBuffer.allocateDirect(TEX_DATA_SIZE*dataLength*bytes_per_float).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
68 |
mQuadTextureInv.put(textureInv).position(0);
|
66 |
69 |
}
|
67 |
70 |
|
68 |
71 |
// BLUR effect
|
... | ... | |
267 |
270 |
|
268 |
271 |
int postprocess(long time, DistortedOutputSurface surface)
|
269 |
272 |
{
|
|
273 |
int numRenders = 0;
|
|
274 |
|
270 |
275 |
if( mNumEffects>0 )
|
271 |
276 |
{
|
272 |
277 |
compute(time);
|
273 |
278 |
|
274 |
|
DistortedFramebuffer buffer = surface.mBuffer[mQualityLevel];
|
275 |
|
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, buffer.mFBOH[0]);
|
276 |
|
|
277 |
|
float w1 = buffer.mWidth;
|
278 |
|
float h1 = buffer.mHeight;
|
279 |
|
float w2 = surface.mWidth;
|
280 |
|
float h2 = surface.mHeight;
|
281 |
|
|
282 |
|
int radius = (int)(mUniforms[0]*mQualityScale);
|
283 |
|
if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
|
284 |
|
computeGaussianKernel(radius);
|
285 |
|
|
286 |
|
int offset = radius + radius*radius/4;
|
287 |
|
radius = (radius+1)/2;
|
288 |
|
|
289 |
|
// horizontal blur
|
290 |
|
GLES30.glViewport(0, 0, (int)w1, (int)h1);
|
291 |
|
mBlur1Program.useProgram();
|
292 |
|
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
|
293 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
294 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
|
295 |
|
|
296 |
|
GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset);
|
297 |
|
GLES30.glUniform1i( mRadius1H, radius);
|
298 |
|
GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear);
|
299 |
|
GLES30.glUniform1i( mColorTexture1H , 0 );
|
300 |
|
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h1;
|
301 |
|
GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0);
|
302 |
|
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
|
303 |
|
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
|
304 |
|
|
305 |
|
DistortedRenderState.useStencilMark();
|
306 |
|
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
|
307 |
|
DistortedRenderState.unuseStencilMark();
|
308 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
309 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
310 |
|
|
311 |
|
// vertical blur
|
312 |
|
mBlur2Program.useProgram();
|
313 |
|
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
|
314 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
315 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[1]);
|
316 |
|
|
317 |
|
GLES30.glColorMask(true,true,true,true);
|
318 |
|
GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
|
319 |
|
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
|
320 |
|
|
321 |
|
GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
|
322 |
|
GLES30.glUniform1i( mRadius2H, radius);
|
323 |
|
GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
|
324 |
|
GLES30.glUniform1i( mColorTexture2H , 0 );
|
325 |
|
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w1;
|
326 |
|
GLES30.glUniform1fv( mOffsets2H ,radius+1, mOffsets,0);
|
327 |
|
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
|
328 |
|
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
|
329 |
|
|
330 |
|
DistortedRenderState.useStencilMark();
|
331 |
|
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
|
332 |
|
DistortedRenderState.unuseStencilMark();
|
333 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
334 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
335 |
|
|
336 |
|
// blit the results with DEPTH to surface.
|
337 |
|
GLES30.glViewport(0, 0, (int)w2, (int)h2);
|
338 |
|
surface.setAsOutput(time);
|
339 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
340 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
|
341 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
|
342 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
|
343 |
|
|
344 |
|
GLES30.glDisable(GLES30.GL_STENCIL_TEST);
|
345 |
|
GLES30.glStencilMask(0x00);
|
346 |
|
|
347 |
|
DistortedEffects.blitDepthPriv(surface);
|
348 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
349 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
350 |
|
GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
|
351 |
|
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
352 |
|
|
353 |
|
// after each postprocess, clear buffers
|
354 |
|
GLES30.glStencilMask(0xff);
|
355 |
|
GLES30.glDepthMask(true);
|
356 |
|
GLES30.glColorMask(true,true,true,true);
|
357 |
|
GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
|
358 |
|
GLES30.glClearDepthf(1.0f);
|
359 |
|
GLES30.glClearStencil(0);
|
360 |
|
|
361 |
|
buffer.setAsOutput();
|
362 |
|
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
|
363 |
|
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
|
364 |
|
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
|
365 |
|
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
|
|
279 |
for(int i=0; i<mNumEffects; i++)
|
|
280 |
{
|
|
281 |
if (mName[i] == EffectNames.BLUR.ordinal() )
|
|
282 |
{
|
|
283 |
blur(mUniforms[i],surface);
|
|
284 |
numRenders += 2;
|
|
285 |
}
|
|
286 |
}
|
366 |
287 |
}
|
367 |
288 |
|
368 |
|
return mNumEffects;
|
|
289 |
return numRenders;
|
|
290 |
}
|
|
291 |
|
|
292 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
293 |
|
|
294 |
private void blur(float degree, DistortedOutputSurface surface)
|
|
295 |
{
|
|
296 |
DistortedFramebuffer buffer = surface.mBuffer[mQualityLevel];
|
|
297 |
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, buffer.mFBOH[0]);
|
|
298 |
|
|
299 |
float w1 = buffer.mWidth;
|
|
300 |
float h1 = buffer.mHeight;
|
|
301 |
|
|
302 |
int radius = (int)(degree*mQualityScale);
|
|
303 |
if( radius>=MAX_BLUR ) radius = MAX_BLUR-1;
|
|
304 |
computeGaussianKernel(radius);
|
|
305 |
|
|
306 |
int offset = radius + radius*radius/4;
|
|
307 |
radius = (radius+1)/2;
|
|
308 |
|
|
309 |
// horizontal blur
|
|
310 |
GLES30.glViewport(0, 0, (int)w1, (int)h1);
|
|
311 |
mBlur1Program.useProgram();
|
|
312 |
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
|
|
313 |
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
|
314 |
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
|
|
315 |
|
|
316 |
GLES30.glUniform1fv( mWeights1H, radius+1, weightsCache,offset);
|
|
317 |
GLES30.glUniform1i( mRadius1H, radius);
|
|
318 |
GLES30.glUniform1f( mDepth1H , 1.0f-surface.mNear);
|
|
319 |
GLES30.glUniform1i( mColorTexture1H , 0 );
|
|
320 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h1;
|
|
321 |
GLES30.glUniform1fv( mOffsets1H ,radius+1, mOffsets,0);
|
|
322 |
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
|
|
323 |
GLES30.glVertexAttribPointer(mBlur1Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
|
|
324 |
|
|
325 |
DistortedRenderState.useStencilMark();
|
|
326 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
|
|
327 |
DistortedRenderState.unuseStencilMark();
|
|
328 |
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
|
329 |
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
|
330 |
|
|
331 |
// vertical blur
|
|
332 |
mBlur2Program.useProgram();
|
|
333 |
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
|
|
334 |
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
|
335 |
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[1]);
|
|
336 |
|
|
337 |
GLES30.glColorMask(true,true,true,true);
|
|
338 |
GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
|
|
339 |
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
|
|
340 |
|
|
341 |
GLES30.glUniform1fv( mWeights2H, radius+1, weightsCache,offset);
|
|
342 |
GLES30.glUniform1i( mRadius2H, radius);
|
|
343 |
GLES30.glUniform1f( mDepth2H , 1.0f-surface.mNear);
|
|
344 |
GLES30.glUniform1i( mColorTexture2H , 0 );
|
|
345 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w1;
|
|
346 |
GLES30.glUniform1fv( mOffsets2H ,radius+1, mOffsets,0);
|
|
347 |
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
|
|
348 |
GLES30.glVertexAttribPointer(mBlur2Program.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
|
|
349 |
|
|
350 |
DistortedRenderState.useStencilMark();
|
|
351 |
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
|
|
352 |
DistortedRenderState.unuseStencilMark();
|
|
353 |
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
|
|
354 |
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
|
369 |
355 |
}
|
370 |
356 |
|
371 |
357 |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
Split up postprocessing into queue of effects + blit with depth.