0
votes

I'm using libgdx but this is pretty much vanilla opengl es 2.0 stuff. Just try and ignore the Gdx.gl prefix everywhere ^^ I'm testing it on my desktop as well as android device and it's the same story in both cases.

I have the following code in my window resize event. It is supposed to delete the frame buffer and associated textures if they already were created, and then make some new ones the right size. I'm not sure if this is even correct to delete the textures and framebuffer like i am doing.

    if (depthTexture >= 0)
    {
        Gdx.gl.glDeleteTexture(depthTexture);
        depthTexture = -1;
    }
    if (colorTexture >= 0)
    {
        Gdx.gl.glDeleteTexture(colorTexture);
        colorTexture = -1;
    }
    if (depthBuffer >= 0)
    {
        Gdx.gl.glDeleteFramebuffer(depthBuffer);
        depthBuffer = -1;
    }

    IntBuffer intBuffer = BufferUtils.newIntBuffer(16); // See http://lwjgl.org/forum/index.php?topic=1314.0;wap2
    intBuffer.clear();
    Gdx.gl.glGenFramebuffers(1, intBuffer);
    frameBuffer = intBuffer.get(0);


    intBuffer.clear();
    Gdx.gl.glGenTextures(1, intBuffer);
    colorTexture = intBuffer.get(0);
    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
    Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, width, height
            , 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, null);

    Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
    Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);

    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);

    intBuffer.clear();
    Gdx.gl.glGenTextures(1, intBuffer);
    depthTexture = intBuffer.get(0);
    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
    Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_DEPTH_COMPONENT, width, height
            , 0, GL20.GL_DEPTH_COMPONENT, GL20.GL_UNSIGNED_SHORT, null);

    Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
    Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);

    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);


    Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);

    Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0
            , GL20.GL_TEXTURE_2D, colorTexture, 0);

    Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_DEPTH_ATTACHMENT
            , GL20.GL_TEXTURE_2D, depthTexture, 0);


    int status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
    if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
    {
        System.out.println("frame buffer not complete. status " + Integer.toHexString(status));
        System.exit(0);
    }


    Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);

    status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
    if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
    {
        System.out.println("default buffer not complete. status " + Integer.toHexString(status));
        System.exit(0);
    }

I am not sure at all if i have made mistakes in setting up the render buffer or either the color texture or depth texture attachments. Anyway, on to the rendering loop

            // update cameras and things


    // setup rendering to off screen framebuffer
    Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);    
    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

    // draw things

    // setup rendering to default framebuffer

    Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);
    Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

    shader.begin();

    // setup shader stuff 

    Gdx.gl.glActiveTexture(0);
    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
    shader.setUniformi("u_fbDepth", 0);

    Gdx.gl.glActiveTexture(1);
    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
    shader.setUniformi("u_fbColor", 1);

    // draw things with shader 

    shader.end();

Again i am not sure i am setting things up the right way. The idea here is hopefully pretty clear. Render to the off screen frame buffer then use the depth and color textures from that frame buffer as textures to sample in the final shader that renders to the default framebuffer.

The depth and color textures that end up in my fragment shader are just empty however. Black screen. I know the fragment shader is not the problem - if i sample a different texture i see the texture as expected. I know that the drawing its self is not the problem - if i render what i would want to render to the off screen frame buffer directly to the default frame buffer i see what i expect.

1

1 Answers

0
votes

I got it. There's a bit of a gotcha with setting active textures. The function glActiveTexture expects one of the GL_TEXTURE0 type constants, but the shader uniform just wants to be the integer in the constant name.

basically

Gdx.gl.glActiveTexture(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);

Gdx.gl.glActiveTexture(1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);

needed to be

Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);

Gdx.gl.glActiveTexture(GL20.GL_TEXTURE1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);