5
votes

I've been trying to get this to work for the last few days and I'm really starting to become desperate. I'd be really grateful for suggestions you might have.

What I've been trying to do:

  • render the scene to an FBO
  • blur the attached texture using glsl shaders
  • render the resulting texture to a screen aligned quad

Issue:

If I enable the fragment-shader (horizontal blur) i do get a blurred image rendered to my quad for the first frame or so, after that it's all black.

My suspicion is that there i something wrong with the way I'm passing the texture to my shader:

    horizontalBlurVertex.enable();

    horizontalBlurFragment.enable();

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, fboTexture);
    glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0);

EDIT: One more piece of Information: if i remove glUniform1i(glGetUniformLocation(horizontalBlurFragment.program, "RTScene"), 0); i get the exact same result. Which i guess indicates that my shader never gets any texture data whatsoever.

sources:

vertex-shader:

varying vec2 vTexCoord;

void main(void)
{
   gl_FrontColor = gl_Color;
   gl_Position = ftransform();

   vec2 Pos;
   Pos = sign(gl_Vertex.xy);

   gl_Position = vec4(Pos, 0.0, 1.0);

   vTexCoord = Pos * 0.5 + 0.5;
}

fragment-shader:

uniform sampler2D RTScene;
varying vec2 vTexCoord;

const float blurSize = 1.0/800.0;
const float weightSum = 70.0 + 2.0 * (1.0 + 8.0 + 28.0 + 56.0);

void main(void)
{
   vec4 sum = vec4(0.0);

   sum += texture2D(RTScene, vec2(vTexCoord.x - 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x - 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x - 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x - blurSize, vTexCoord.y)) * 56.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x, vTexCoord.y)) * 70.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x + blurSize, vTexCoord.y)) * 56.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x + 2.0*blurSize, vTexCoord.y)) * 28.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x + 3.0*blurSize, vTexCoord.y)) * 8.0 / weightSum;
   sum += texture2D(RTScene, vec2(vTexCoord.x + 4.0*blurSize, vTexCoord.y)) * 1.0 / weightSum;

   gl_FragColor = sum;
}

render to fbo:

//handels
    GLuint fbo, fboTexture, fboDepthbuffer;

    // generate namespace for the frame buffer, colorbuffer and depthbuffer
    glGenFramebuffersEXT(1, &fbo);
    glGenTextures(1, &fboTexture);
    glGenRenderbuffersEXT(1, &fboDepthbuffer);

    //switch to our fbo so we can bind stuff to it
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    //create the colorbuffer texture and attach it to the frame buffer
    glGenTextures(1, &fboTexture);
    glBindTexture(GL_TEXTURE_2D, fboTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);

    // create a render buffer as our depthbuffer and attach it
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);

    // Go back to regular frame buffer rendering
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
        glPushAttrib(GL_VIEWPORT_BIT);
            glViewport(0, 0, width, height);
            glPushMatrix();
                glBegin(GL_QUADS);
                    glNormal3f(0.0, 0.0, 1.0);

                    glColor3f(1.0f, 1.0f, 0.0f);
                    glVertex3f(-0.1, 0.1, -1.0);

                    glColor3f(1.0f, 0.0f, 0.0f);
                    glVertex3f(0.1, 0.1, -1.0);

                    glColor3f(0.0f, 1.0f, 0.0f);
                    glVertex3f(0.1, -0.1, -1.0);

                    glColor3f(0.0f, 0.0f, 1.0f);
                    glVertex3f(-0.1, -0.1, -1.0);
                glEnd();
            glPopMatrix();
        glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

(not posting my ShaderLoader source here since using simpler shaders (switching colors and whatnot) works perfectly fine)

If you think the error lies somewhere else I'll be happy to post some additional code.

1
I'm not familiar with OpenFrameworks, but you need to call glUseProgram before calling glUniform*. I don't know if enable() does this.pmr
Yes, that's exactly what it does. Like I said shaders w/o uniform parameters works just fine... Thanks though really appreciate you taking the time and reading all this stuff.Oradon
Which is kind of strange. Binding a shader requires a program which is the result of attaching compiled shader objects and linking it. I don't see how two seemingly unrelated enable() calls accomplish this.pmr
Well there is a load() function of course, compiling/linking/generating program object and so on... enable() just calls glUseProgramObjectARB(program);. But again the ShaderLoader itself seems to work just fine. I do get a blurred image (for the first frame) and I can use all kinds of shaders, I'm just struggling with passing the texture to my shader...Oradon
Ah, I think you are not using the right texture coordinates. Use glMultiTexCoord0 instead of the vertex coordinates.pmr

1 Answers

1
votes

Problem solved!

Turns out I foolishly created my fbo every frame... works perfectly fine now.