PDA

View Full Version : FBO using Render Buffers



saber7
11-04-2010, 04:31 PM
Hi,

I currently am using a FBO with a render buffer for both the depth and color. I am using this to take screen shots of the 3D scene. My current implementation works just fine and I can create any sized (upto max) image by adjusting the viewport size.

My problem is this: The rendered image in the "real" OpenGL window looks great and has smoothing on. When I render to the FBO and save the image, the image looks like smoothing is off. Both examples call the same draw function that draws my scene (which includes setting up the smoothing). The only difference is one uses the internal OpenGL render buffers and the other uses my FBO render buffers.

Do I need to do anything special to setup smoothing (and other nice affects) for the FBO? Also, is the RBO rdendering done in hardware or software. If it's software, then this might explain why smoothing isn't working or isn't very good relative to if the rendering was done in hardware.

Thanks for any help.

Alfonse Reinheart
11-04-2010, 04:37 PM
The rendered image in the "real" OpenGL window looks great and has smoothing on. When I render to the FBO and save the image, the image looks like smoothing is off.

What is "smoothing?" If "smoothing" is antialiasing, then that's something that you have to replicate with the FBO.

Regardless of how you turned on multisampling, if you want multisampling in an FBO, you must do actual work. Multisampling is an effect of the framebuffer, so you will need to recreate it in your FBO. You must create multisampled renderbuffers, with the specific number of samples you want to use. Then, you must glEnable multisampling.

That being said:


I currently am using a FBO with a render buffer for both the depth and color. I am using this to take screen shots of the 3D scene.

If all you want to do is take screenshots, then an FBO is overkill. Just do a glReadPixels from the backbuffer. And don't swap buffers after doing the render if you don't want the scene displayed.

saber7
11-04-2010, 04:45 PM
Thanks for the quick reply.

By smoothing, I mean having all the edges look nice and smooth (no jagged edges). Our code for enabling smoothing is:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);

I originally setup my screen captures simply doing the glReadPixels with the backbuffer. However, I found out that blocking windows causes pixels to be undefined. I also wanted to change the resolution of the images to sizes different than the window size and I cannot change the size of the window for display purposes. So after hours of reading on-line, FBO seemed to be the best approach. The FBO does everything I need it to except my images are not as good as the original.

blink
11-04-2010, 05:02 PM
Hello, first a question.
You sure both of depth and color are renderbuffers? If so how do you access them after rendering? It should not happen.

For one to one copy of your scene, make sure your framebuffer and main/system framebuffer has the equal viewport and necessary filtering for textures attached to your framebuffer (Assuming you attached texture but not a renderbuffer for the color).

saber7
11-04-2010, 05:14 PM
blink,

Both depth and color are render buffers. I chose not to use a texture image because it wasn't neccessary for what I was doing.

I first bind my FBO: using glBindFramebufferEXT
I resize the ViewPort
I draw my scene
I call glReadPixels to get the image.
I set the ViewPort back to original size.
I unbind my FBO.

I tried using glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); before the call to glReadPixels and I get the same results if I don't do it.

My goal was to resize the ViewPort to the image size I need, do the FBO rendering and get the image, then set the ViewPort back to the window size for rendering to the system for the GUI. Again, this works rather well for me right now other then the jagged edges.

saber7
11-04-2010, 05:20 PM
blink,

On another note, I did try setting up a texture image as the color after realizing the render buffer for color wasn't giving me the smoothing I wanted. Using a texture image for color produced the same results.

I am not sure what you mean by "make sure the framebuffer and main/system framebuffer has the equal viewport". I simply call glViewPort to size my FBO to the image size I need when capturing an image and I call glViewPort to match the windows size of my OpenGL window when I am doing normal rendering to the screen.

blink
11-04-2010, 05:34 PM
Ahaa, indeed you can get it with glReadPixels but that invalidates the reasons using framebuffers, just change it to texture and you just saved an expensive glReadPixels.

If that is your goal, attach a filtered texture to the framebuffer and this is all you need, you can use that texture with any size you like.

For "make sure the framebuffer and main/system framebuffer has the equal viewport", i was thinking that you were rendering 2 times and all you want is a fullscreen copy of your scene, ignore that since you underlined your scheme.

saber7
11-04-2010, 05:37 PM
Here is an image of what I am seeing. The shot on the left is my GUI and how the scene should look (this was taken from a windows screen shot). The shot on the right is from the FBO and you can see how bad the jagged edges are.

http://members.cox.net/jsnow20/OpenGLSmoothing.bmp

I have to create some images for advertising for a show and when I make large images, the jagged lines get even worse.

Again, I just need to understand why the smoothing works in the normal rendering mode and not for the FBO?

saber7
11-04-2010, 05:51 PM
blink,

What exactly does the filtered texture do differently than a normal texture? I tried it with a normal texture? Is this the key part?

Would I then just do a glGetTexImage to get the image data?

Wouldn't the glGetTexImage and glReadPixels be somewhat equivalent in speed?

blink
11-04-2010, 05:51 PM
Again, I just need to understand why the smoothing works in the normal rendering mode and not for the FBO?

In that case, as Alfonse Reinheart said, you need to enable multisampling for FBO. (if your card supports framebuffer multisample that is)

blink
11-04-2010, 06:01 PM
blink,

What exactly does the filtered texture do differently than a normal texture? I tried it with a normal texture? Is this the key part?

Would I then just do a glGetTexImage to get the image data?

Wouldn't the glGetTexImage and glReadPixels be somewhat equivalent in speed?

Since you want to resize your output, yes you need filtering. (something better than GL_NEAREST)
IIRR glReadPixels is slower, but for just taking a screenshot nothing is slow :)

Alfonse Reinheart
11-04-2010, 06:30 PM
Ahaa, indeed you can get it with glReadPixels but that invalidates the reasons using framebuffers, just change it to texture and you just saved an expensive glReadPixels.

He needs the pixels on the CPU. He's either going to do a glReadPixels from a framebuffer, or he's going to do a glGetTexSubImage from a texture. Neither is faster than the other, so there's no need to render to a texture.


In that case, as Alfonse Reinheart said, you need to enable multisampling for FBO. (if your card supports framebuffer multisample that is)

He's not using multisampling. He's using polygon smoothing.

It's likely that this is just a driver bug. Does line smoothing work?

blink
11-04-2010, 06:39 PM
He's not using multisampling. He's using polygon smoothing.

It's likely that this is just a driver bug. Does line smoothing work?

We don't know yet if multisampling is enabled for main framebuffer.

saber7
11-04-2010, 06:40 PM
Alfonse,

In the image I posted showing what is happening, the magenta border on the white rectangle is drawn using gluCylinder and the rays passing through the white rectangle are drawn with triangle strips. Would this tell you if line smoothing is working or not?

Since I haven't used multisampling, can you elobrate on what it could do for me?

I am at home right now and cannot test any of the code. I will try and test the application on a different system with a different card tomorrow.

saber7
11-04-2010, 06:45 PM
blink,

How can I tell if multisampling is enabled for the main frame buffer? I can check the project and verify this. I know for sure we are not calling glEnable for multisampling like Alfonse said to do. Could it be enabled another way? What are the affects if it is or isn't relative to what I am doing?

Alfonse Reinheart
11-04-2010, 06:53 PM
Would this tell you if line smoothing is working or not?

No. I was asking specifically about line smoothing. As in when you draw GL_LINES, not GL_TRIANGLES.

Line smoothing is far more commonly used than polygon smoothing, so it's more likely to work. If it isn't working, then it shows how far the driver bug goes.

blink
11-04-2010, 06:57 PM
Enabling multisampling for main buffer is painful, you should read the extension. Framebuffer object multisample on the other hand relatively easy to do, again you should check the extension/docs/tutorials.
It is relative to what you are doing, after all you are drawing primitives and you need plausible images. Not sure smoothing hints would be enough for your needs.

saber7
11-04-2010, 10:01 PM
Ok, I will try the GL_LINES along with trying the app on another system with a different graphics card.

Is there a better way to handle what I need?

tksuoran
11-05-2010, 02:17 AM
Maybe the driver control panel has setting to enable multisample? This way you may get multisample even if application does not explicitly as for it.