0
votes

I have a problem with glReadPixels/ScreenUtils.getFrameBufferPixmap() where semi-transparent sprites drawn on top of opaque ones seem to "overwrite" the transparency, resulting in a mess.

Black sprites with 10% transparency are drawn on top of the tiles to look like shadows.

Original (in-game) image:

Normal shadows.

Image obtained with glReadPixels in ScreenUtils.getFrameBufferPixmap(...):

(the shadows are white because they're slightly transparent)

How would I make alpha blending work properly in getFrameBufferPixmap()?

1
You need to drop the alpha-channel in your result (i.e. set alpha to 1.0f for all pixels), thats whats OpenGL does when presenting the image on the screen. Alpha is stored in the intermediate result because its needed for alpha-calculations when you draw on top of already-drawn pixels.tkausl
Ah, I hadn't thought of that. Changing each pixel alpha to 1 seems to do the trick.Anuken

1 Answers

0
votes

You need to use glBlendFuncSeparate instead of glBlendFunc, which is what SpriteBatch uses. SpriteBatch provides a back door (undocumented I think for some reason) for using glBlendFuncSeparate. Set it's blend function parameters to -1, and then you can manually set your own glBlendFuncSeparate that always leaves the alpha of your frame buffer as 1.0:

spriteBatch.setBlendFunction(-1, -1);
Gdx.gl.glBlendFuncSeparate(
    GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ZERO, GL20.GL_ONE);
//...
spriteBatch.begin();
//...
spriteBatch.end();

Also make sure the alpha of your glClearColor is 1.0f.