Search code examples
javaopengllibgdxblending

What blending mode do I need to make images more transparent by drawing transparent images over them?


This picture explains what I am aiming for:

blending

Basically, I have a framebuffer and I want to make the contents of it more transparent by drawing a fullscreen shape over it. The color of this shape will play no role. I have tried this by using the following code:

// sr is ShapeRenderer
// fbo is FrameBufferObject

fbo.begin();

Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_BLEND);

sr.begin(ShapeRenderer.ShapeType.Filled);

Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
sr.setColor(1, 1, 1, 1);
sr.circle(0, 0, 1);

Gdx.gl.glBlendFuncSeparate(GL20.GL_ZERO, GL20.GL_ONE, GL20.GL_ZERO, GL20.GL_ONE_MINUS_SRC_ALPHA);
sr.setColor(0, 0, 0, .5f);
sr.rect(0, 0, width, height);

sr.end();
fbo.end();

Instead of it working, I get a transparent black circle that keeps getting more transparent even though the buffer doesn't get refreshed. What I expected was a transparent white circle.

I expected this blending to take place:

R = Rsrc * 0 + Rdst * 1
G = Gsrc * 0 + Gdst * 1
B = Bsrc * 0 + Bdst * 1
A = Asrc * 0 + Adst * (1 - 0.5)

Does anyone know how to make this work properly?


Solution

  • ShapeRenderer doesn't know you're changing the blendfunc, so you're drawing both the circle and the square with the second blendfunc that you set. You need to flush it in between.