I want to draw a scene to a framebuffer object and later use the texture of that in another shader. For testing purposes I would just like to actually output the framebuffer object's textur. However, the corresponding part (a rectangle) is just completely black. So I'm wondering whether either the rendering to the fbo does not work or the access to that.
Here are the important code parts:
Called before rendering to the FBO:
void TextureRenderer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, mWidth, mHeight);
}
This is the plane on which the FBO should be displayed. The first texture "mTextureId" is another texture I've loaded from a TGA file and displaying that works just fine. However, the second "mReflectionTextureId" is the one from the VBO and this is the one which I cannot access (or it really is black because there was an error before).
void WaterPlane::render(const Transform& trans) {
mat4 projection = trans.projection;
mat4 view = trans.view;
mat4 model = mat4::identitiy();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
mShader->bind();
// lets activate the textures now
glEnable(GL_TEXTURE_2D);
// bumpmap texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTextureId);
// set the texture
mShader->seti("waterBumpTextureSampler", 0);
// rendered reflection texture (has been rendered previously with the help of Framebuffer object for reflection)
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mReflectionTextureId);
// set reflection texture
mShader->seti("renderedReflection", 1);
mShader->setMatrix("matProjection", projection, GL_TRUE);
mShader->setMatrix("matView", view, GL_TRUE);
mShader->setMatrix("matModel", model, GL_TRUE);
mShader->setf("vecTextureShift", mTextureShift);
mVboWaterPlane->render();
mShader->release();
glDisable(GL_TEXTURE_2D);
glPopClientAttrib();
glPopAttrib();
}
Finally, the water.fs shader:
#version 130
in vec4 VertPosition;
in vec4 VertNormal;
in vec4 VertColor;
in vec4 VertTexture;
uniform vec3 lightPos;
uniform sampler2D waterBumpTextureSampler;
uniform sampler2D renderedReflection; // reflection on the water
void main()
{
// completely black
gl_FragColor = texture( renderedReflection, VertTexture.xz);
// if this is actually commented in the bumpmap texture will be shown nicely
// gl_FragColor = texture( waterBumpTextureSampler, VertTexture.xz);
}
So in general displaying textures work, however displaying the texture from the framebuffer object does not (or the rendering to it previously to that did not work).
Screenshot:

EDIT:
The initialization code of the FBO:
void TextureRenderer::init() {
glGenFramebuffers(1, &mFramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// The texture we're going to render to
glGenTextures(1, &mRenderedTextureId);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, mRenderedTextureId);
cout << "TextureRenderer: creating with id " << mFramebufferName << " and tex id " << mRenderedTextureId << endl;
// Give an empty image to OpenGL ( the last "0" )
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mWidth, mHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
// Poor filtering. Needed !
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// The depth buffer
// TODO this is probably not needed?!?!?!
glGenRenderbuffers(1, &mDepthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, mWidth, mHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderBuffer);
// Set "renderedTexture" as our colour attachement #0
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRenderedTextureId, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
// Always check that our framebuffer is ok
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
cout << "Problem during creation of TextureRenderer" << endl;
throw std::runtime_error("Something Bad happened here");
}
unbind();
cout << "TextureRenderer: creating with id " << mFramebufferName << "...done" << endl;
}
The bind code (which is immediately called before rendering to the FBO):
void TextureRenderer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName);
// glPushAttrib(GL_VIEWPORT_BIT); // http://wiki.delphigl.com/index.php/Tutorial_Framebufferobject
glViewport(0, 0, mWidth, mHeight);
}