libGDX Framebuffer Alpha问题

时间:2016-06-02 03:25:54

标签: libgdx alpha framebuffer

我遇到了libGDX FrameBuffer和Alpha的问题。以下是预期结果和实际结果的两个图像。有人可以告诉我我做错了什么,我怎么能纠正它。这是代码:

FrameBuffer buffer;
Sprite sprite;

SpriteBatch batch;
Texture texture1;
Texture texture2;
Texture texture3;
Sprite texture2Sprite;

@Override
public void create () {
    batch = new SpriteBatch();

    texture1 = new Texture("1.png");
    texture2 = new Texture("2.png");
    texture3 = new Texture("3.png");

    texture2Sprite = new Sprite(texture2);
    texture2Sprite.setAlpha(0.5f);
    texture2Sprite.setPosition(100, 100);

    buffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
    sprite = new Sprite(buffer.getColorBufferTexture());
    sprite.flip(false, true);
}

public void createFBO()
{
    buffer.begin();

    Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.begin();
    batch.draw(texture1, 0f, 0f);

    texture2Sprite.draw(batch);

    batch.end();
    buffer.end();
}

@Override
public void render () {

    createFBO();

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

    batch.begin();
    batch.enableBlending();
    batch.draw(texture3, 200, 200);
    sprite.draw(batch);

    batch.end();
}

Expected Result 预期结果

Actual Result 实际结果

1 个答案:

答案 0 :(得分:1)

FrameBuffer中的半透明颜色几乎存在同样的问题,您可以在我的badlogic论坛主题here找到问题和解决方案。

基本上,您需要以预乘的alpha状态绘制到FrameBuffer。您可以通过创建自定义片段着色器来完成此操作(我的完整代码就是主题)。然后设置混合模式以匹配(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)。

然后使用相同的混合函数但默认着色器绘制您的精灵。你应该得到这样的东西;

public void createFBO(){
    buffer.begin();
    batch.begin();

    Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.setShader(pmaShaderProgram); //pre-multiplied alpha ShaderProgram
    batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
    batch.draw(texture1, 0f, 0f);
    texture2Sprite.draw(batch);
    batch.setShader(null); //default ShaderProgram
    batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); //default blend mode

    batch.end();
    buffer.end();
}

@Override
public void render () {
    createFBO();

    batch.begin();
    batch.enableBlending();

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

    batch.draw(texture3, 200, 200);

    batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
    sprite.draw(batch);
    batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

    batch.end();
}