Revision 5f7e4f2c
Added by Leszek Koltunski over 6 years ago
src/main/java/org/distorted/library/effect/PostprocessEffect.java | ||
---|---|---|
139 | 139 |
* |
140 | 140 |
* @y.exclude |
141 | 141 |
*/ |
142 |
public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo);
|
|
142 |
public abstract int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers); |
|
143 | 143 |
|
144 | 144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
145 | 145 |
/** |
src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java | ||
---|---|---|
141 | 141 |
* |
142 | 142 |
* @y.exclude |
143 | 143 |
*/ |
144 |
public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo)
|
|
144 |
public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers) |
|
145 | 145 |
{ |
146 | 146 |
if( mProgram1 ==null) |
147 | 147 |
{ |
... | ... | |
160 | 160 |
|
161 | 161 |
DistortedFramebuffer buffer = (DistortedFramebuffer)buffers[mQualityLevel]; |
162 | 162 |
|
163 |
buffer.setAsOutputFBO(fbo);
|
|
163 |
buffer.setAsOutput();
|
|
164 | 164 |
|
165 | 165 |
float w= buffer.getWidth(); |
166 | 166 |
float h= buffer.getHeight(); |
... | ... | |
183 | 183 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrW; |
184 | 184 |
|
185 | 185 |
mProgram1.useProgram(); |
186 |
buffer.bindForOutput(2*fbo+1);
|
|
187 |
buffer.setAsInput(2*fbo);
|
|
186 |
buffer.bindForOutput(1); |
|
187 |
buffer.setAsInput(0);
|
|
188 | 188 |
|
189 | 189 |
GLES31.glColorMask(true,true,true,true); |
190 | 190 |
GLES31.glClearColor(1.0f,1.0f,1.0f,0.0f); |
... | ... | |
204 | 204 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrH; |
205 | 205 |
|
206 | 206 |
mProgram2.useProgram(); |
207 |
buffer.bindForOutput(2*fbo);
|
|
208 |
buffer.setAsInput(2*fbo+1);
|
|
207 |
buffer.bindForOutput(0);
|
|
208 |
buffer.setAsInput(1); |
|
209 | 209 |
|
210 | 210 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT); |
211 | 211 |
|
src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java | ||
---|---|---|
145 | 145 |
* |
146 | 146 |
* @y.exclude |
147 | 147 |
*/ |
148 |
public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers, int fbo)
|
|
148 |
public int apply(float[] uniforms, int index, DistortedOutputSurface[] buffers) |
|
149 | 149 |
{ |
150 | 150 |
if( mProgram1 ==null) |
151 | 151 |
{ |
... | ... | |
181 | 181 |
int offset = radius + radius*radius/4; |
182 | 182 |
radius = (radius+1)/2; |
183 | 183 |
|
184 |
outBuffer.setAsOutputFBO(fbo); |
|
185 | 184 |
GLES31.glViewport(0, 0, (int)w, (int)h); |
186 | 185 |
|
187 | 186 |
// horizontal glow |
188 | 187 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrW; |
189 | 188 |
|
190 | 189 |
mProgram1.useProgram(); |
191 |
outBuffer.bindForOutput(2*fbo+1); |
|
192 |
inBuffer.setAsInput(2*fbo); |
|
190 |
outBuffer.setAsOutput(); |
|
191 |
outBuffer.bindForOutput(1); |
|
192 |
inBuffer.setAsInput(0); |
|
193 | 193 |
|
194 | 194 |
GLES31.glColorMask(true,true,true,true); |
195 | 195 |
GLES31.glClearColor(1.0f,1.0f,1.0f,0.0f); |
... | ... | |
210 | 210 |
for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]*offsetCorrH; |
211 | 211 |
|
212 | 212 |
mProgram2.useProgram(); |
213 |
outBuffer.bindForOutput(2*fbo); |
|
214 |
outBuffer.setAsInput(2*fbo+1); |
|
213 |
outBuffer.bindForOutput(0); |
|
214 |
outBuffer.setAsInput(1); |
|
215 |
|
|
216 |
if( mQualityLevel==0 ) |
|
217 |
{ |
|
218 |
GLES31.glEnable(GLES31.GL_BLEND); |
|
219 |
} |
|
215 | 220 |
|
216 | 221 |
GLES31.glUniform1f ( mProgram2.mUniform[0] , n ); |
217 | 222 |
GLES31.glUniform2f ( mProgram2.mUniform[1] , corrW, corrH ); |
... | ... | |
224 | 229 |
GLES31.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture); |
225 | 230 |
GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4); |
226 | 231 |
|
232 |
if( mQualityLevel==0 ) |
|
233 |
{ |
|
234 |
GLES31.glDisable(GLES31.GL_BLEND); |
|
235 |
} |
|
236 |
|
|
227 | 237 |
DistortedRenderState.unuseStencilMark(); |
228 | 238 |
|
229 | 239 |
// blit back to inBuffer if we have to |
230 | 240 |
if( mQualityLevel>0 ) |
231 | 241 |
{ |
232 |
inBuffer.setAsOutputFBO(fbo);
|
|
233 |
inBuffer.bindForOutput(2*fbo);
|
|
234 |
outBuffer.setAsInput(2*fbo);
|
|
242 |
inBuffer.setAsOutput();
|
|
243 |
inBuffer.bindForOutput(0);
|
|
244 |
outBuffer.setAsInput(0);
|
|
235 | 245 |
GLES31.glEnable(GLES31.GL_BLEND); |
236 | 246 |
DistortedEffects.blitPriv(inBuffer); |
237 | 247 |
GLES31.glDisable(GLES31.GL_BLEND); |
src/main/java/org/distorted/library/main/DistortedFramebuffer.java | ||
---|---|---|
254 | 254 |
/** |
255 | 255 |
* Bind the underlying rectangle of pixels as a OpenGL Texture. |
256 | 256 |
* |
257 |
* @param texture The Texture number to bind (and thus read from). |
|
257 | 258 |
* @return <code>true</code> if successful. |
258 | 259 |
*/ |
259 | 260 |
public boolean setAsInput(int texture) |
260 | 261 |
{ |
261 |
if( texture>=0 && texture<mNumFBOs*mNumColors && mColorH[texture]>0 )
|
|
262 |
if( texture>=0 && texture<mNumColors && mColorH[texture]>0 ) |
|
262 | 263 |
{ |
263 | 264 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE0); |
264 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[texture]); |
|
265 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[2*mCurrFBO+texture]);
|
|
265 | 266 |
return true; |
266 | 267 |
} |
267 | 268 |
|
... | ... | |
269 | 270 |
} |
270 | 271 |
|
271 | 272 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
272 |
|
|
273 |
/** |
|
274 |
* Attach the texture'th Texture to COLOR0 attachment. |
|
275 |
* |
|
276 |
* @param texture The Texture number to attach (and subsequently use to render to) |
|
277 |
*/ |
|
273 | 278 |
public void bindForOutput(int texture) |
274 | 279 |
{ |
275 |
if( texture>=0 && texture<mNumFBOs*mNumColors && mColorH[texture]>0 )
|
|
280 |
if( texture>=0 && texture<mNumColors && mColorH[texture]>0 ) |
|
276 | 281 |
{ |
277 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[texture], 0); |
|
282 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[2*mCurrFBO+texture], 0);
|
|
278 | 283 |
} |
279 | 284 |
} |
280 | 285 |
|
src/main/java/org/distorted/library/main/DistortedOutputSurface.java | ||
---|---|---|
94 | 94 |
// mWidth,mHeight are the sizes of the Viewport, those - |
95 | 95 |
// sizes of the backing up texture. |
96 | 96 |
|
97 |
int mCurrFBO; // internal current FBO (see Distorted.FBO_QUEUE_SIZE) |
|
98 |
|
|
97 | 99 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
98 | 100 |
|
99 | 101 |
DistortedOutputSurface(int width, int height, int createColor, int numfbos, int numcolors, int depthStencil, int fbo, int type) |
... | ... | |
101 | 103 |
super(width,height,createColor,numfbos,numcolors,type); |
102 | 104 |
|
103 | 105 |
mRenderWayOIT = false; |
106 |
mCurrFBO = 0; |
|
104 | 107 |
|
105 | 108 |
mDepthStencilH = new int[numfbos]; |
106 | 109 |
mFBOH = new int[numfbos]; |
... | ... | |
275 | 278 |
private int blitWithDepth(long currTime, DistortedOutputSurface buffer,int fbo) |
276 | 279 |
{ |
277 | 280 |
GLES31.glViewport(0, 0, mWidth, mHeight); |
278 |
setAsOutputFBO(currTime,fbo);
|
|
281 |
setAsOutput(currTime);
|
|
279 | 282 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE0); |
280 | 283 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]); |
281 | 284 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE1); |
... | ... | |
298 | 301 |
GLES31.glClearDepthf(1.0f); |
299 | 302 |
GLES31.glClearStencil(0); |
300 | 303 |
|
301 |
buffer.setAsOutputFBO(fbo);
|
|
304 |
buffer.setAsOutput();
|
|
302 | 305 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo+1], 0); |
303 | 306 |
GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT); |
304 | 307 |
GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo ], 0); |
... | ... | |
321 | 324 |
private int oitBuild(long time, DistortedOutputSurface buffer, int fbo) |
322 | 325 |
{ |
323 | 326 |
GLES31.glViewport(0, 0, mWidth, mHeight); |
324 |
setAsOutputFBO(time,fbo);
|
|
327 |
setAsOutput(time);
|
|
325 | 328 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE0); |
326 | 329 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[2*fbo]); |
327 | 330 |
GLES31.glActiveTexture(GLES31.GL_TEXTURE1); |
... | ... | |
363 | 366 |
GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0); |
364 | 367 |
} |
365 | 368 |
|
366 |
setAsOutputFBO(currTime,fbo);
|
|
369 |
setAsOutput(currTime);
|
|
367 | 370 |
DistortedRenderState.switchColorDepthOnStencilOff(); |
368 | 371 |
DistortedEffects.oitRender(this, corrW, corrH); |
369 | 372 |
DistortedRenderState.restoreColorDepthStencil(); |
... | ... | |
383 | 386 |
DistortedRenderState.colorDepthStencilRestore(); |
384 | 387 |
} |
385 | 388 |
|
389 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
390 |
|
|
391 |
void setCurrFBO(int fbo) |
|
392 |
{ |
|
393 |
mCurrFBO = fbo; |
|
394 |
} |
|
395 |
|
|
386 | 396 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
387 | 397 |
// Render all children, one by one. If there are no postprocessing effects, just render to THIS. |
388 | 398 |
// Otherwise, render to a buffer and on each change of Postprocessing Bucket, apply the postprocessing |
... | ... | |
395 | 405 |
EffectQueuePostprocess lastQueue=null, currQueue; |
396 | 406 |
long lastBucket=0, currBucket; |
397 | 407 |
|
408 |
setCurrFBO(fbo); |
|
409 |
|
|
410 |
if( mBuffer!=null ) |
|
411 |
{ |
|
412 |
for (int i=0; i<EffectQuality.LENGTH; i++) |
|
413 |
{ |
|
414 |
mBuffer[i].setCurrFBO(fbo); |
|
415 |
} |
|
416 |
} |
|
417 |
|
|
398 | 418 |
if( oit && numChildren>0 ) |
399 | 419 |
{ |
400 | 420 |
oitClear(this); |
... | ... | |
408 | 428 |
|
409 | 429 |
if( currBucket==0 ) |
410 | 430 |
{ |
411 |
setAsOutputFBO(time,fbo);
|
|
431 |
setAsOutput(time);
|
|
412 | 432 |
|
413 | 433 |
if( oit ) |
414 | 434 |
{ |
... | ... | |
422 | 442 |
} |
423 | 443 |
else |
424 | 444 |
{ |
425 |
if( mBuffer==null ) createPostprocessingBuffers(mWidth,mHeight,mNear); |
|
445 |
if( mBuffer==null ) |
|
446 |
{ |
|
447 |
createPostprocessingBuffers(mWidth,mHeight,mNear); |
|
448 |
|
|
449 |
for (int j=0; j<EffectQuality.LENGTH; j++) |
|
450 |
{ |
|
451 |
mBuffer[j].setCurrFBO(fbo); |
|
452 |
} |
|
453 |
} |
|
426 | 454 |
|
427 | 455 |
if( lastBucket!=currBucket ) |
428 | 456 |
{ |
... | ... | |
435 | 463 |
for(int j=bucketChange; j<i; j++) |
436 | 464 |
{ |
437 | 465 |
child2 = children.get(j); |
438 |
mBuffer[internalQuality].setAsOutputFBO(fbo);
|
|
466 |
mBuffer[internalQuality].setAsOutput();
|
|
439 | 467 |
numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],lastQueue); |
440 | 468 |
} |
441 | 469 |
|
442 |
numRenders += lastQueue.postprocess(mBuffer,fbo);
|
|
470 |
numRenders += lastQueue.postprocess(mBuffer); |
|
443 | 471 |
|
444 | 472 |
if( oit ) |
445 | 473 |
{ |
... | ... | |
458 | 486 |
bucketChange = i; |
459 | 487 |
} |
460 | 488 |
|
461 |
mBuffer[quality].setAsOutputFBO(time,fbo);
|
|
489 |
mBuffer[quality].setAsOutput(time);
|
|
462 | 490 |
child1.drawNoBlend(time,mBuffer[quality]); |
463 | 491 |
|
464 | 492 |
if( i==numChildren-1 ) |
... | ... | |
466 | 494 |
for(int j=bucketChange; j<numChildren; j++) |
467 | 495 |
{ |
468 | 496 |
child2 = children.get(j); |
469 |
mBuffer[internalQuality].setAsOutputFBO(fbo);
|
|
497 |
mBuffer[internalQuality].setAsOutput();
|
|
470 | 498 |
numRenders += child2.markStencilAndDepth(time,mBuffer[internalQuality],currQueue); |
471 | 499 |
} |
472 | 500 |
|
473 |
numRenders += currQueue.postprocess(mBuffer,fbo);
|
|
501 |
numRenders += currQueue.postprocess(mBuffer); |
|
474 | 502 |
|
475 | 503 |
if( oit ) |
476 | 504 |
{ |
... | ... | |
545 | 573 |
DistortedRenderState.colorDepthStencilRestore(); |
546 | 574 |
} |
547 | 575 |
|
548 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
549 |
|
|
550 |
private void setAsOutputFBO(long time, int fbo) |
|
551 |
{ |
|
552 |
if( fbo>=0 && fbo<mNumFBOs ) |
|
553 |
{ |
|
554 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]); |
|
555 |
|
|
556 |
if (mTime[fbo] != time) |
|
557 |
{ |
|
558 |
mTime[fbo] = time; |
|
559 |
clear(); |
|
560 |
} |
|
561 |
} |
|
562 |
else |
|
563 |
{ |
|
564 |
android.util.Log.e("surface", "error in setAsOutput1, fbo="+fbo); |
|
565 |
} |
|
566 |
} |
|
567 |
|
|
568 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
569 |
/** |
|
570 |
* Not part of the Public API. |
|
571 |
* |
|
572 |
* @y.exclude |
|
573 |
*/ |
|
574 |
public void setAsOutputFBO(int fbo) |
|
575 |
{ |
|
576 |
if( fbo>=0 && fbo<mNumFBOs ) |
|
577 |
{ |
|
578 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[fbo]); |
|
579 |
} |
|
580 |
else |
|
581 |
{ |
|
582 |
android.util.Log.e("surface", "error in setAsOutput2, fbo="+fbo); |
|
583 |
} |
|
584 |
} |
|
585 |
|
|
586 | 576 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
587 | 577 |
// PUBLIC API |
588 | 578 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
... | ... | |
668 | 658 |
*/ |
669 | 659 |
public void setAsOutput(long time) |
670 | 660 |
{ |
671 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
|
|
661 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
|
|
672 | 662 |
|
673 |
if( mTime[0]!=time )
|
|
663 |
if( mTime[mCurrFBO]!=time )
|
|
674 | 664 |
{ |
675 |
mTime[0] = time;
|
|
665 |
mTime[mCurrFBO] = time;
|
|
676 | 666 |
clear(); |
677 | 667 |
} |
678 | 668 |
} |
... | ... | |
685 | 675 |
*/ |
686 | 676 |
public void setAsOutput() |
687 | 677 |
{ |
688 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
|
|
678 |
GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[mCurrFBO]);
|
|
689 | 679 |
} |
690 | 680 |
|
691 | 681 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
src/main/java/org/distorted/library/main/EffectQueuePostprocess.java | ||
---|---|---|
100 | 100 |
|
101 | 101 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
102 | 102 |
|
103 |
int postprocess(DistortedOutputSurface[] buffers, int fbo)
|
|
103 |
int postprocess(DistortedOutputSurface[] buffers) |
|
104 | 104 |
{ |
105 | 105 |
int numRenders = 0; |
106 | 106 |
|
... | ... | |
108 | 108 |
|
109 | 109 |
for(int i=0; i<mNumEffects; i++) |
110 | 110 |
{ |
111 |
numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i, buffers, fbo);
|
|
111 |
numRenders += ((PostprocessEffect)mEffects[i]).apply(mUniforms,NUM_UNIFORMS*i, buffers); |
|
112 | 112 |
} |
113 | 113 |
|
114 | 114 |
GLES31.glEnable(GLES31.GL_BLEND); |
src/main/res/raw/oit_render_fragment_shader.glsl | ||
---|---|---|
45 | 45 |
////////////////////////////////////////////////////////////////////////////////////////////// |
46 | 46 |
// A over B (https://en.wikipedia.org/wiki/Alpha_compositing) |
47 | 47 |
|
48 |
|
|
49 | 48 |
vec4 blend(vec4 A,vec4 B) |
50 | 49 |
{ |
51 | 50 |
float b = B.a * (1.0-A.a); |
Also available in: Unified diff
Hide the FBO_QUEUE thing inside the library. The queue is running internally now, without public setAsOutputFBO() thing (simplifies writing postprocess effects)