Skip to content

Instantly share code, notes, and snippets.

@mgsx-dev
Last active February 25, 2021 00:13
Show Gist options
  • Save mgsx-dev/9cab46e4c9583d1bbf9ea7db543c94bd to your computer and use it in GitHub Desktop.
Save mgsx-dev/9cab46e4c9583d1bbf9ea7db543c94bd to your computer and use it in GitHub Desktop.
How to draw into a FBO with proper blending function and save it to a PNG file
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.ScreenUtils;
public class BlendingExportDemo extends Game{
public static int w = 1024;
public static int h = 1024;
public static void main (String[] arg) {
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.width = w;
config.height = h;
new LwjglApplication(new BlendingExportDemo(), config);
}
@Override
public void create() {
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Texture texture = new Texture(Gdx.files.internal("tiled3d/tileset.png"));
Batch batch = new SpriteBatch();
batch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE);
batch.begin();
batch.draw(texture, 0, 0);
batch.setColor(1, 1, 1, .5f);
batch.draw(texture, 10, 10);
batch.end();
Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(0, 0, w, h);
PixmapIO.writePNG(Gdx.files.local("test.png"), pixmap);
pixmap.dispose();
texture.dispose();
Gdx.app.exit();
}
}
@mgsx-dev
Copy link
Author

note that there is some cases where this technic doesn't properly work. when painting several layers with half transparency, the first layer get mixed with framebuffer background color (black color in this case) which makes the result tinted (darker in this case).
In order to fix it, it's needed to clear the frame buffer with the first layer RGB (Alpha still at zero). This can be done like this :

batch.setBlendFunctionSeparate(GL20.GL_ONE, GL20.GL_ZERO, GL20.GL_ZERO, GL20.GL_ZERO);
// draw the first layer (background)
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE);
// draw all layers (including background layer)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment