PDA

View Full Version : How to draw to FBO?



PP2005
11-24-2009, 01:31 PM
I'm trying to get a FBO to work for my program. I think I understand how to set up and use it, but I've got a problem with drawing to it. Here's the relevant code (Pascal):

Setting up the FBO and attaching a texture:


glGenTextures(1, @TextureID[FBOMap]);
TextureDimX[FBOMap] := 512;
TextureDimY[FBOMap] := 512;
glBindTexture(GL_TEXTURE_2D, TextureID[FBOMap]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureDimX[FBOMap], TextureDimY[FBOMap], 0, GL_RGBA, GL_UNSIGNED_BYTE, NIL);
glGenFramebuffersEXT(1, @FBO);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBOMap, 0);


Drawing to the FBO's texture:


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, 512, 512);

DrawToScreen(ShipsMap, 0, 0, 512, 512, 0, 0, 1, 1, 1, 1, 100, F, F); // This is just my screen drawing routine.

glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


Drawing the texture to the screen buffer in the main loop:


DrawToScreenAtCenter(FBOMap, 0, 0, 512, 512, 300, 300, 1, 1, 1, 1, 100, F, F, 0);


Now, if I attach a picture to the FBOMap texture when setting it up instead of giving NIL pixels, that picture shows up fine when rendering the texture to the screen, which makes me believe that I'm simply doing something wrong when setting the FBO as the draw buffer and drawing to it.

Can anybody see anything obviously wrong?

Graham Sellers
11-24-2009, 02:54 PM
You haven't bound your FBO before attaching the texture to it. Try this:


<snip>
glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureDimX[FBOMap], TextureDimY[FBOMap], 0, GL_RGBA, GL_UNSIGNED_BYTE, NIL);
glGenFramebuffersEXT(1, @FBO);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO); <<< Here
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, FBOMap, 0);

Cheers,

Graham

PP2005
11-25-2009, 02:46 AM
I had a feeling it was some stupid mistake... Thanks! :)

PP2005
11-25-2009, 11:41 AM
I've run into another problem now. When the FBO's texture is rendered to the screen buffer, the image is upside down and resized. It seems to be resized to about 3/4 height and less than half width. I think this has something to do with the size of the FBO texture in relation to the screen size, as the screen is 1280x800 and the FBO texture is 512x512.

This is my OpenGL screen setup code:


glEnable(GL_TEXTURE_2D);
glClearColor(0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, ResolutionWidth, ResolutionHeight);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, ResolutionWidth, ResolutionHeight, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


And this is the render to texture code (as previously posted):


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, 512, 512);

DrawToScreen(ShipsMap, 0, 0, 512, 512, 0, 0, 1, 1, 1, 1, 100, F, F);

glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

AdrianPi
11-25-2009, 12:35 PM
You are not doing


glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

after binding the framebuffer and before drawing to it.

How can it work?

PP2005
11-25-2009, 01:05 PM
I was going by the tutorial here:

http://www.gamedev.net/reference/articles/article2331.asp

I doesn't seem to mention glDrawBuffer. Odd. I'll give it a shot. :)

EDIT: That didn't change anything. And I must be drawing to the FBO's texture, since the image does show up, just upside down and resized.

PP2005
11-26-2009, 07:32 AM
Help?

I tried setting the screen size to 512x512 (same as the FBO's texture) and that results in the texture being drawn correctly, so it's definitely some issue with the FBO's size versus the screen size...

PP2005
11-27-2009, 12:32 PM
I've figured it out. The problem was that I had to bind the FBO *before* setting the projection for the FBO and unbind it *after* having reset the screen projection. Don't know why, though.