1
votes

I'm having some problems rendering the post-processed stage to the screen. I wrote some code that was rendering OK to the screen, then decided I needed some postprocessing (sepia an bloom effect, but that comes afterwards) so I decided to render everything to a FrameBuffer object, and then use its color texture to render a textured, full screen quad. The problem is, even using some trivial shaders, I either get a black screen (or whatever the color I use to clear the color buffer) having the depth test disabled, or some garbage pixels occupying the lower left quarter of the screen, when enabling the depth test (that was just blind testing, I'm not sure if I need the depth test in a 2D game, but my OpenGL understading is poor).

So, what am I doing wrong? Here's the code:

TRIVIAL VERTEX SHADER:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

varying vec4 vColor;
varying vec2 vTexCoord;

void main() {
    vColor = a_color;
    vTexCoord = a_texCoord0;
    gl_Position = a_position;
}

TRIVIAL FRAGMENT SHADER:

#ifdef GL_ES
precision mediump float;
#endif

varying vec4 vColor;
varying vec2 vTexCoord;

uniform sampler2D u_texture;

void main() {
    vec4 texColor = texture2D(u_texture, vTexCoord);
    gl_FragColor = vColor.rgba * vec4(texColor.rgb, 1.0);
}

INITIALIZATION:

FrambeBuffer fbo;
ShaderProgram focusShader;
Mesh focusQuad;

@Override
public void show() {

    camera1 = new OrthographicCamera();
    camera1.setToOrtho(false);
    camera1.zoom = 0.8f;
    viewport = new ExtendViewport(Globals.VIEWPORT_WIDTH, Globals.VIEWPORT_HEIGHT, camera1);
    batch = new SpriteBatch();
    moveCamera(camera1, player.getX(), player.getY());
    fbo = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
    ShaderProgram.pedantic = false;
    focusShader = new ShaderProgram(Gdx.files.internal("shaders/trivial_vshader"), Gdx.files.internal("shaders/trivial_fshader"));
    focusQuad = createFullScreenQuad(); //TAKEN FROM https://github.com/manuelbua/libgdx-contribs/blob/master/postprocessing/src/main/java/com/bitfire/postprocessing/utils/FullscreenQuad.java
    // Other game initialization...
}

RENDER LOOP:

@Override
public void render(float delta) {
    // (UPDATE PHYSICS)...
    fbo.begin();
    {
    /* DRAW THE PLAYER */
        batch.setProjectionMatrix(camera1.combined);
        batch.begin();
        player.drawTrail(batch, delta);
        player.draw(batch, delta);
        batch.end();

        Gdx.gl.glEnable(GL20.GL_BLEND);
        Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
        shapeRenderer.setProjectionMatrix(camera1.combined);
        shapeRenderer.begin(ShapeType.Filled);
        map.drawEffects(camera1, shapeRenderer);
        //(OTHER GAME STUFF AND EFFECTS...)
        shapeRenderer.end();
        Gdx.gl.glDisable(GL20.GL_BLEND);
    }
    fbo.end();

    //NOW THE PROBLEM
    Gdx.gl.glClearColor(0, 0.4f, 0.3f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    //Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
    Gdx.gl.glEnable(GL20.GL_BLEND);
    Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
    fbo.getColorBufferTexture().bind();
    focusShader.begin();
    focusShader.setUniformi("u_texture", 0);
    focusQuad.render(focusShader, GL20.GL_TRIANGLE_FAN, 0, 4);
    focusShader.end();
}
1
Have checked what is in your framebuffer? Try geting the fbo color texture before fbo.end(). That might help. If everything else is ok.Veljko
Thanks for the reply. I think the FBO has the right contents since before I was drawing to the FBO, I was drawing to the screen (and it worked), AND, more importantly, I can draw the fbo color texture using a SpriteBatch (no shaders) and I can see it's kind of OK (I didn't try this much and I still got problems with the zoom or viewport -everything was too big-, but I could see the game working).Azurlake
I looked up that "createFullScreenQuad" code, and it creates a mesh without color attributes, but you're using vertex color. Have you modified createFullScreenQuad to use color attributes? Depth test should not be used for a pure 2D scene unless you have opaque sprites that you want to be sorted for you. Also, is this problem on Desktop or Android only? RGBA8888 is not supported on all Android devices.Tenfour04
Thanks, Tenfour04. That was the point. I didn't modify it. I can now see the scene; it has some unexpected problems though because without touching anything inside the render loop (the original one, now between the fbo.begin() and the fbo.end()) now I cannot see the lights being rendered (I'm using Box2D lights; now everything is like when I had no lights -all is bright, original colour-), and the color buffer is not being cleared properly. I'll elaborate more on the answer when I'm at home, and please feel free to post this as an answer so I can upvote it.Azurlake

1 Answers

0
votes

Have you tried getting reference to color texture before fbo.end. Im not sure if fbo end automatically disposes it.