GLSL multitexturing question with FBO

I am having difficulty performing the following tasks (highlights are what I have issues with):

  1. Creating three textures (we’ll say a,b, and c)
  2. Create a depth buffer
  3. Binding those three textures and the depth buffer to a fbo
  4. Loading data into the three textures (really only need to load into a and b)
  5. Rendering two textures (say ‘a’ and ‘b’) two the third texture c - for this I use a FS
  6. Now render texture c on screen

The following is my source (following the above outline):

1. Texture creation (texName is actually replaced by t1, t2,t3. data in “image” is a black and white checkerboard that is renderable - I have rendered a single texture with the standard pipeline and it displays as I expect it to):

    GLuint texName;
    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);
    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_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, 64,
        64, 0, GL_RGBA, GL_FLOAT, image);

2. Depth Buffer :

    glGenRenderbuffersEXT(1, &depthBuffer);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 64, 64);

3. Frame buffer creation and binding:

     glGenFramebuffersEXT(1,&fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
        GL_RENDERBUFFER_EXT, depthBuffer);

    // Bind the texture to the FBO
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,
        GL_TEXTURE_2D,t1,0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT1_EXT,
        GL_TEXTURE_2D,t2,0);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT2_EXT,
        GL_TEXTURE_2D,t3,0);

4. Specifying the ‘draw texture’ and binding the ‘source’ textures


    glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);

    glBindTexture(GL_TEXTURE_2D,t1);
    glBindTexture(GL_TEXTURE_2D,t2);
    //GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); returns no error here - the buffer is created correctly

5. Rendering t1 and t2 to t3 -this section does not work

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);

    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0,0,64, 64);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f,0.0f,0.0f,0.5f);

    glLoadIdentity();


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,t1);
    glEnable(GL_TEXTURE_2D);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D,t2);
    glEnable(GL_TEXTURE_2D);

    glUseProgram(program);


    glBegin(GL_QUADS);
    //lower left
    glTexCoord2f(0, 0);
    glVertex2f(-1.0, -1.0);
    //upper left
    glTexCoord2f(0, 1.0);
    glVertex2f(-1.0, 1.0);
    //upper right
    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 1.0);
    //lower right
    glTexCoord2f(1.0, 0);
    glVertex2f(1.0, -1.0);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glUseProgram(0);

    glPopAttrib();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


6. Rendering t3 (now that we have rendered t1 and t2 to it

     glClearColor(0.0f,0.0f,0.0f,0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    //glUseProgram(program);
    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, t3);

    glBegin(GL_QUADS);
    //lower left
    glTexCoord2f(0, 0);
    glVertex2f(-1.0, -1.0);
    //upper left
    glTexCoord2f(0, 1.0);
    glVertex2f(-1.0, 1.0);
    //upper right
    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 1.0);
    //lower right
    glTexCoord2f(1.0, 0);
    glVertex2f(1.0, -1.0);
    glEnd();

    glDisable(GL_TEXTURE_2D);

This is my FS:


uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
void main() {
vec4 s1 = texture2D(tex1, gl_TexCoord[0].st);
vec4 s2 = texture2D(tex2, gl_TexCoord[0].st + vec2(0.03125, 0.03125));
gl_FragColor =  mix(vec4(1, s1.g, s1.b, 0.5), vec4(s2.r, s2.g, 1, 0.5), 0.5);
}

and how I set the uniforms ( which I assume if they do not vary at any time during the lifetime, can be set once):


    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,t1);
    GLuint t1Location = glGetUniformLocation(program, "tex1");

    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,t2);
    GLuint t2Location = glGetUniformLocation(program, "tex2");

    glActiveTexture(GL_TEXTURE2);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,t3);
    GLuint t3Location = glGetUniformLocation(program, "tex3");

    glUniform1i(t1Location, 0);
    glUniform1i(t2Location, 1);
    glUniform1i(t3Location, 2);

This is the correct product if I ‘glUseProgram(program)’ on the rendering pass referenced in section 6 (instead of trying to render to t3 in one pass, and then render t3 directly in the second pass):

When I try to render to t3 and then render t3 to the screen I get a black screen.

Thank you for listening and hopefully someone can yell at me for using a glEnable() where I wasn’t and everything will work.

I have solved this problem by modifying sections 5 and 6 - I followed instructions found on this page and was able to render how I wanted. The only thing I need to fix is the positioning, but this is trivial compared to the other task.

Fixes:

Section 5:

    glViewport(0,0,64,64);

    glBindTexture(GL_TEXTURE_2D,0);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

    glClearColor(0.0f,0.0f,0.0f,0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    glUseProgram(program);


    glBegin(GL_QUADS);
    //lower left
    glTexCoord2f(0, 0);
    glVertex2f(-1.0, -1.0);
    //upper left
    glTexCoord2f(0, 1.0);
    glVertex2f(-1.0, 1.0);
    //upper right
    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 1.0);
    //lower right
    glTexCoord2f(1.0, 0);
    glVertex2f(1.0, -1.0);
    glEnd();

    glUseProgram(0);

    glEnable(GL_TEXTURE_2D);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

and…

Section 6 :



    glClearColor(0.0f,0.0f,0.0f,0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, t3);

    glViewport(0,0,width,height);

    glLoadIdentity();

    glBegin(GL_QUADS);
    //lower left
    glTexCoord2f(0, 0);
    glVertex2f(-1.0, -1.0);
    //upper left
    glTexCoord2f(0, 1.0);
    glVertex2f(-1.0, 1.0);
    //upper right
    glTexCoord2f(1.0, 1.0);
    glVertex2f(1.0, 1.0);
    //lower right
    glTexCoord2f(1.0, 0);
    glVertex2f(1.0, -1.0);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glutSwapBuffers();

So it did kind of come down to a bad glEnable placement! I hope this helps someone in the future.