PDA

View Full Version : MRT with FBO not working



mobeen
08-22-2011, 03:20 AM
Hi all,
I am trying to do a basic multiple render to texture with render to vertex buffer but it does not work. This is how I have setup my vertex buffer.


const int size = texture_size*texture_size*4*sizeof(float);
glGenBuffers(2, vbo);
for(int i=0;i<2;i++) {
glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
glBufferData(GL_ARRAY_BUFFER, size, &amp;X[0].x, GL_DYNAMIC_DRAW);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);

This is how my FBO is setup


glGenTextures(4, attachID);
glGenFramebuffers(2, fboID);

for(int j=0;j<2;j++) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID[j]);
for(int i=0;i<2;i++) {
glBindTexture(GL_TEXTURE_2D, attachID[i+2*j]);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texture_size, texture_size, 0, GL_RGBA, GL_FLOAT, data[i]); // NULL = Empty texture

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, mrt[i], GL_TEXTURE_2D, attachID[i+2*j], 0);
}
}

GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE ) {
printf("FBO setup succeeded.");
} else {
printf("Problem with FBO setup.");
}

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
CHECK_GL_ERRORS
This is how my MRT i setup


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID[writeID]);
glDrawBuffers(2, mrt);
glClear(GL_COLOR_BUFFER_BIT);
SetOrthographicProjection();
glViewport(0,0,texture_size, texture_size);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, attachID[2*readID]);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, attachID[2*readID+1]);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
shader.Use();
DrawFullScreenQuad();
shader.UnUse();
glFlush();

CHECK_GL_ERRORS

//read back the results into the VBO
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID[readID]);
glReadBuffer(GL_COLOR_ATTACHMENT0); glBindBuffer(GL_PIXEL_PACK_BUFFER, vbo[0]); glReadPixels(0, 0, texture_size, texture_size, GL_RGBA, GL_FLOAT, 0);

glReadBuffer(GL_COLOR_ATTACHMENT1);
glBindBuffer(GL_PIXEL_PACK_BUFFER, vbo[1]);
glReadPixels(0, 0, texture_size, texture_size, GL_RGBA, GL_FLOAT, 0);

glReadBuffer(GL_NONE);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glViewport(0,0,width, height);
ResetPerspectiveProjection();

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
And finally this is how I am rendering the buffer.


glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexPointer(4, GL_FLOAT, 0,0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS,0, total_points);
glDisableClientState(GL_VERTEX_ARRAY);

But it does not work. I tried removing the MRT completely to see whether the buffer object is setup fine and indeed it is; I get my mesh. However, with MRT it does not work. Maybe I am missing something obvious for reading my data from the FBO but I cannot find it.

BionicBytes
08-22-2011, 05:11 AM
To me it looks like you have bound the sames textures which you are attempting to draw to:


glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboID[writeID]);
glDrawBuffers(2, mrt);
.......
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, attachID[2*readID]);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, attachID[2*readID+1]);


In your shader you should be writing output with glFragData[0] and glFragData[1] (assuming you are using GL 3.x or lower with compatibility profile). I'm unsure about how to do the same in core profile since glFragData has been depreciated.

mobeen
08-22-2011, 09:25 AM
Hi BionicBytes,
THanks for the reponse. Well I m trying to write to an FBO while I read from the attachment of another FBO. Assuming writeID =0 and readID =1, you can see that fbo0 has attachIDs 0 and 1 while fbo1 has attachID 2 and 3. So when I am setting the fbo0 as current render target, I am reading from attachID 2 and 3 which are linked to the currently unbound fbo1. I think this should be perfectly valid right?
As for the shader, my shader is outputting to gl_FragData[0] and [1]. If i set constant value from shader, it comes out fine. If i read from the texture sampler (attachIDs), the output is wrong.

mobeen
08-22-2011, 10:50 PM
OK I think I have got something working. In gDebugger I can see my textures fine. I am currently just outputting the read positions to fragdata and the result is correct as I can see the exact input values. To check whether my pipeline is fine,I am rendering points as i showed before by attaching the read value as an array buffer. However, I donot get points on screen. My output values contain the fourth comp (w=1). I think I am doing a very basic mistake here can anyone spot it?
EDIT: One strange thing that I have noticed is that even if I try to render anything after the mrt, nothing gets rendered. How do I restore the default framebuffer? I have already called

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK_LEFT);

mobeen
08-22-2011, 11:35 PM
Ok the problem was not in this code, it was in the code that was setting the ortho-projection matrix, it was resetting the modelview matrix to identity and that is why I did not get anything displayed. So now I think my problem is solved.

BionicBytes
08-23-2011, 02:20 AM
How do I restore the default framebuffer?

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK_LEFT);


In my code base I call:


glBindFramebuffer( GL_FRAMEBUFFER, 0 )
glReadBuffer(GL_BACK);
glDrawBuffer(GL_BACK);

The GL_READ_FRAMEBUFFER and GL_WRITE_FRAMEBUFFER can be switched off in one call.

mobeen
08-23-2011, 02:45 AM
Thanks.