2016-06-02 16 views
1

Ich habe Probleme mit dem libGDX FrameBuffer und Alpha. Unten sind zwei Bilder des erwarteten Ergebnisses und des tatsächlichen Ergebnisses. Kann mir bitte jemand sagen, was ich falsch mache und wie kann ich das korrigieren? Hier ist der Code:libGDX Framebuffer Alpha Probleme

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 Erwartetes Ergebnis

Actual Result Tatsächliches Ergebnis

Antwort

1

ich so ziemlich das gleiche Problem hatte mit halbtransparenten Farben im FrameBuffer, das Problem und die Lösung möglich finde auf meinem badlogic forum topic here.

Grundsätzlich müssen Sie zu Ihrem FrameBuffer in einem vor-multiplizierten Alpha-Zustand zeichnen. Dazu erstellen Sie einen benutzerdefinierten Fragment-Shader (mein vollständiger Code steht zum Thema). Dann stellen Sie Ihren Mischmodus so ein, dass er übereinstimmt (GL_ONE, GL_ONE_MINUS_SRC_ALPHA).

Zeichnen Sie dann Ihr Sprite mit der gleichen Blend-Funktion, aber Standard-Shader. Du solltest mit so etwas enden;

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(); 
} 
+0

Hey, danke, es hat perfekt funktioniert ... Allerdings habe ich noch eine Folge. Angenommen, ich möchte etwas zum FrameBuffer zeichnen, der eine Alpha-Komponente hat, aber auch ein anderes Shader-Programm verwendet. Wie würde ich darüber gehen? – user5207217

+0

Froh, dass es für dich funktioniert hat. Ich denke, der einzige Weg, um das nächste Problem zu lösen, besteht darin, eine andere Version Ihres anderen benutzerdefinierten Shaders zu erstellen und sie so zu modifizieren, dass sie vorvervielfachtes Alpha zeichnet. Ich stelle mir vor, die Mehrheit der Shader können Sie einfach die erforderliche Zeile am Ende hinzufügen; 'gl_FragColor.rgb * = gl_FragColor.a;' – hamham