alfoks alfoks - 1 year ago 100
Android Question

LibGdx `ShapeRenderer` on Android does not honor alpha channel

I have a program where I am drawing some lines on each frame using

ShapeRenderer
. On each frame I want to draw on top the previous, faded by a amount, frame.
So what I am doing is first draw a black rectangle with an alpha less than 1 and then draw the current frame. On desktop it works well and the result is something like this

enter image description here

But on Android it does not work. It renders like this.

enter image description here

I tried enabling blending before drawing rectangle

Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);


Also tried seting the alpha channel to 8 bits in
AndroidApplicationConfiguration
(
config.a = 8
)
Nothing of these worked. What else can I try?
Also is there a better way to achieve what I want?

Screen code

package com.waterpaw.trochoids.screen;

import java.util.ArrayList;
import java.util.List;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.waterpaw.trochoids.Trochoid;
import com.waterpaw.trochoids.Trochoids;

public class GameScreen extends BaseScreen {
private ShapeRenderer sr;

private ScreenViewport viewport;

private List<Trochoid> trochoids = new ArrayList<Trochoid>();

public GameScreen(Trochoids game) {
super(game);

viewport = new ScreenViewport();
Gdx.input.setInputProcessor(this);
sr = new ShapeRenderer();
}

private int resized;

@Override
public void resize(int width, int height) {
viewport.update(width, height);

trochoids.clear();
trochoids.add(new Trochoid(viewport.getWorldWidth(), viewport.getWorldHeight()));
resized = 2;
}

@Override
public void render(float delta) {
if(resized-- > 0) {
Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
processInput();

if(!trochoids.get(0).isPaused()) {
updateTrochoids();
renderTrochoids();
}
}

private void processInput() {
if(Gdx.input.isKeyJustPressed(Keys.P)) {
if(trochoids.get(0).isPaused()) {
trochoids.get(0).unpause();
} else {
trochoids.get(0).pause();
}
} else if(Gdx.input.isKeyJustPressed(Keys.SPACE)) {
touchDown(0, 0, 0, 0);
}
}

@Override
public void dispose() {
sr.dispose();
}

@Override
public boolean touchDown(int x, int y, int pointer, int button) {
trochoids.get(0).initialize();
return true;
}

public void renderTrochoids() {
sr.setProjectionMatrix(viewport.getCamera().combined);

float w = viewport.getWorldWidth();
float h = viewport.getWorldHeight();
sr.setColor(0, 0, 0, 0.1f);
sr.begin(ShapeRenderer.ShapeType.Filled);
sr.rect(-w / 2, -h / 2, w, h);
sr.end();

sr.begin(ShapeRenderer.ShapeType.Line);
for(int i = 0; i < trochoids.size(); i++) {
trochoids.get(i).render(sr);
}
sr.end();
}

private void updateTrochoids() {
for(int i = 0; i < trochoids.size(); i++) {
trochoids.get(i).update();
}
}
}

Answer Source

LibGDX uses double buffering on Android, so your technique won't work. Draw to a FrameBuffer so you can ensure your previous drawing is not cleared every other frame. Then draw the FrameBuffer's color texture to the screen on every frame.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download