Revision 5f7e4f2c
Added by Leszek Koltunski over 7 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)