OpenGL problem with FBO integer texture and color attachment

Posted by Grieverheart on Game Development See other posts from Game Development or by Grieverheart
Published on 2012-12-03T14:40:56Z Indexed on 2012/12/03 23:25 UTC
Read the original article Hit count: 305

In my simple renderer, I have 2 FBOs one that contains diffuse, normals, instance ID and depth in that order and one that I use store the ssao result. The textures I use for the first FBO are RGB8, RGBA16F, R32I and GL_DEPTH_COMPONENT32F for the depth. For the second FBO I use an R16F texture. My rendering process is to first render to everything I mentioned in the first FBO, then bind depth and normals textures for reading for the ssao pass and write to the second FBO. After that I bind the second FBO's texture for reading in my blur shader and bind the first FBO for writing. What I intend to do is to write the blurred ssao value to the alpha component of the Normals texture.

Here are where the problems start. First of all, I use shading language 3.3, which my graphics card does support. I manage ouputs in my shaders using layout(location = #). Now, the normals texture should be bound to color attachment 1, but when I use 1, it seems to write to my diffuse texture which should be in color attachment 0. When I instead use layout(location = 0), it gets correctly written to my normals texture. Besides this, my instance ID texture also gets resets after running the blur shader which is weird because if I use a float texture and write to it instanceID / nInstances, the texture doesn't get reset after the blur shader has ran.

Here is how I prepare my first FBO:




bool CGBuffer::Init(unsigned int WindowWidth, unsigned int WindowHeight){
    //Create FBO
    glGenFramebuffers(1, &m_fbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);

    //Create gbuffer and Depth Buffer Textures
    glGenTextures(GBUFF_NUM_TEXTURES, &m_textures[0]);
    glGenTextures(1, &m_depthTexture);
    //prepare gbuffer
    for(unsigned int i = 0; i < GBUFF_NUM_TEXTURES; i++){
        glBindTexture(GL_TEXTURE_2D, m_textures[i]);
        if(i == GBUFF_TEXTURE_TYPE_NORMAL) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WindowWidth, WindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
        else if(i == GBUFF_TEXTURE_TYPE_DIFFUSE) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
        else if(i == GBUFF_TEXTURE_TYPE_ID) glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, WindowWidth, WindowHeight, 0, GL_RED_INTEGER, GL_INT, NULL);
        else{
            std::cout << "Error in FBO initialization" << std::endl;
            return false;
        }
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    }

    //prepare depth buffer
    glBindTexture(GL_TEXTURE_2D, m_depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
    glDrawBuffers(GBUFF_NUM_TEXTURES, DrawBuffers);

    GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

    if(Status != GL_FRAMEBUFFER_COMPLETE){
        std::cout << "FB error, status 0x" << std::hex << Status << std::endl;
        return false;
    }

    //Restore default framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    return true;
}


where I use an enum defined as,


enum GBUFF_TEXTURE_TYPE{
    GBUFF_TEXTURE_TYPE_DIFFUSE,
    GBUFF_TEXTURE_TYPE_NORMAL,
    GBUFF_TEXTURE_TYPE_ID,
    GBUFF_NUM_TEXTURES
};

Am I missing some kind of restriction? Does the color attachment of the FBO's textures somehow gets reset i.e. I'm using a re-size function which re-sizes the textures of the FBO but should I perhaps call glFramebufferTexture2D again too?

EDIT: Here is the shader in question:



#version 330 core

uniform sampler2D aoSampler;
uniform vec2 TEXEL_SIZE; // x = 1/res x, y = 1/res y
uniform bool use_blur;

noperspective in vec2 TexCoord;

layout(location = 0) out vec4 out_AO;

void main(void){
    if(use_blur){
        float result = 0.0;
        for(int i = -1; i < 2; i++){
            for(int j = -1; j < 2; j++){
                vec2 offset = vec2(TEXEL_SIZE.x * i, TEXEL_SIZE.y * j);
                result += texture(aoSampler, TexCoord + offset).r; // -0.004 because the texture seems to be a bit displaced
            }
        }

        out_AO = vec4(vec3(0.0), result / 9);
    }
    else out_AO = vec4(vec3(0.0), texture(aoSampler, TexCoord).r);
}


© Game Development or respective owner

Related posts about opengl

Related posts about glsl