2

I'm trying to use FBO to render to texture and then display the texture, but all I get is a black rectangle. My code is:

Initialization:

#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <assert.h>

// ...
GLuint fbo_, rbo_, tex_;

glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);

glGenRenderbuffers(1, &rbo_);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width_, height_);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_);

glGenTextures(1, &tex_);
glBindTexture(GL_TEXTURE_2D, tex_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenerateMipmap(GL_TEXTURE_2D);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_, 0);

assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

Render to the FBO:

glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width_, height_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
//draw stuff
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Use the texture (the problem is probably in the code above, because if I just use some static texture, the code below works):

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_);

glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(x_, y_, 0);
glTexCoord2f(width_, 0);
glVertex3f(x_ + width_, y_, 0);
glTexCoord2f(width_, height_);
glVertex3f(x_ + width_, y_ + height_, 0);
glTexCoord2f(0, height_);
glVertex3f(x_, y_ + height_, 0);
glEnd();

Could you help me spot the problem?

Dan Nestor
  • 2,441
  • 1
  • 24
  • 45
  • I think I also had a bug in my last snippet of code (texture coordinates relative to x_,y_ instead of 0,0). I will update the code to reflect my changes. – Dan Nestor Oct 27 '11 at 18:19

2 Answers2

4

Make sure the texture you attach is complete if you're going to rely on the default texture environment.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • Thanks for the tip, I added the mipmap generation code. Unfortunately, now instead of a white rectangle, I get a black one. Any ideas? – Dan Nestor Oct 27 '11 at 18:14
  • 1
    You don't need mipmaps, since you use bilinear filtering. And `glGenerateMipmap` on the still empty (or undefined) texture image is rubbish, anyway. Remove the `glGenerateMipmap` (or if you really need trialinear filtering, do it after rendering into the texture), but keep the other `glTexParameteri` calls. – Christian Rau Oct 27 '11 at 18:43
1

I had the same problem and used genpfault's advice to create a complete texture. Unfortunately, I do not have enough reputation to add a comment so I just added this answer here. Still, the code below may save you some time:

// generate full viewport texture
    glGenTextures(1, &fb_tex);
    glBindTexture(GL_TEXTURE_2D, fb_tex);
    // IMPORTANT: texture must be COMPLETE (mipmaps must be specified..
    // or the following parameters can be used if there are none)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_RGBA,
        width,
        height,
        0,
        GL_RGBA,
        GL_UNSIGNED_BYTE,
        NULL
        );

The only thing I changed in my original code was two add the two lines with glTexParameteri. The parameters can be changed depending on the amount of mipmaps you want/have.

Avrdan
  • 343
  • 2
  • 13