Render to window framebuffer and FBO to save full scale texture image - opengl

I would like to save the output of my image processing OpenGL shader program to an image file and also display the result on the screen. I know how to save the window framebuffer using glReadPixels(). However, the resolution of the screen is smaller than the dimensions of the image.
If I render to an FBO, do I need to call glDrawArrays() again after saving and unbinding the FBO to see the results on the screen? Or is it possible to tell the window framebuffer to render from the FBO without having to run the shader program a second time?

To save the rendered image in the RBO, you can read the pixels directly by setting which buffer OpenGL will read the pixels from by calling glReadBuffer. In your particular case, setting the read buffer to GL_COLOR_ATTACHMENT<i> should do the trick. See the glDrawBuffer man page for details.
In order to display the image in the FBO: yes, you will need to make an additional rendering pass to copy the FBO's image into the default frame buffer. You an either bind the FBO as a texture, and render geometry, as you suggest, to get the image on the screen, or, you may be able to use glBlitFramebuffer to simplify the copying and image filtering.

If I render to an FBO, do I need to call glDrawArrays() again after saving and unbinding the FBO to see the results on the screen?
You should use glBlitFramebuffer (...), the purpose of this function is to copy one framebuffer (read buffer) to another (draw buffer). Provided you are not doing something unusual like drawing into an integer texture attachment then your FBO's draw buffer should be compatible with your default framebuffer (window).
There are some additional caveats related to the filter method and the type of image you are copying (e.g. depth buffers cannot use linearly interpolation), but since you are discussing "full scale" here, I imagine you are interested in GL_NEAREST anyway.

Related

Use default framebuffer depth buffer in a fbo

I want to achieve a post process outline effect on some actors in my game and I want the outline be occluded by other actors closer to the camera. To do so I planed to render the elements that should be outline in an FBO and an outline shader. To discard the pixel that are occluded I want to use the depth buffer of the default framebuffer.
I read and searched but I didn't find how to properly use the default framebuffer depth buffer in another framebuffer or how to copy or anyway to use the default depth buffer informations on an fbo.
How can I achieve it?
I read and searched but I didn't find how to properly use the default framebuffer depth buffer in another framebuffer
Unfortunately, there is no way in OpenGL to do that.
or how to copy or anyway to use the default depth buffer informations on an fbo.
That is quite easy. Just create an FBO with a appropriate depth attachment (no matter if texture or renderbuffer), and blit the default depth buffer to it:
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, your_target_fbo);
glBlitFramebuffer(0,0,width,height,0,0,width,height,GL_DEPTH_BUFFER_BIT, GL_NEAREST);
However, since you do some post-processing anyway, it might be a good option to render the intial scene into an FBO and re-use the same depth buffer in different FBOs.
Unfortunately, it is not possible to attach the default depth-buffer to a FBO or to read it from a shader.
You can copy the default framebuffer into a renderbuffer (or a framebuffer attached texturem, see glBlitFramebuffer), but this could be relatively slow.
Another option is to render the complete scene first to a FBO (color + depth), then use the outline shader to read from this FBO, combine the result with the outline calculation and write the final result to the default framebuffer.

giving preexisting texture to fbo to draw on it

I wanted to know if it's possible to give a non NULL texture to a frame buffer to render on it. I mean just drawing on it so it will become the background of the final texture.
From what I have tried it just keep the texture I give and render it directly, there's no drawing on it ( as if the drawing part have been useless).
If i give a NULL texture the drawing is done.
So i wanted to know if it's possible, am i just doing it wrongly?
all example of use of fbo i've seen only show NULL texture sent.
What you're trying to do is not as common as the use case where content in an FBO attachment is rendered from scratch. That's why you won't find as many examples.
It's still perfectly legal, though, and should work. The only difference should really be that you don't call glClear() after attaching the texture to the FBO, and starting to render.
One case where you'll have to be careful is if you use depth buffering for the rendering you want to do on top of the original texture content. In this case, you will of course need a depth buffer attachment (which is typically a renderbuffer) in your FBO, as usual. In this case, you will need to clear your depth buffer, but not the color buffer, before starting to render:
glClear(GL_DEPTH_BUFFER_BIT);

How to render Framebuffer Objects on multi-sampled textures?

I currently have a rendering engine using multiple passes in which various parts of the image are rendered on textures, and then combined using shaders. It works, and now I would like to activate multi-sampling.
I read here ( http://www.opengl.org/wiki/Framebuffer_Object_Examples#MSAA ) that, with OpenGL, you can't attach a GL_TEXTURE2D_MULTISAMPLE to a framebuffer object.
It seems one way to use multi-sampling and still have access to the result as texture is to use a multi-sampled render buffer, and then copy the result into a multisample texture.
My question is: what would be the best way to go forward?
Is it possible to render in a render buffer and use the output in my shader, without copying into a texture?
Should I indeed copy the content of the buffer into a texture, and then use it?
Is there another, better, solution?
Thanks.
I read here ( http://www.opengl.org/wiki/Framebuffer_Object_Examples#MSAA ) that, with OpenGL, you can't attach a GL_TEXTURE2D_MULTISAMPLE to a framebuffer object.
Read it again. It says nothing about GL_TEXTURE_2D_MULTISAMPLE textures. Actually, I take that back: don't read that page again. If you want good FBO info, read the page on Framebuffer Objects that explains 3.x behavior. The page you linked to is old.
Back in the EXT days, all you had were multisampled renderbuffers, because multisample textures didn't exist. You could create multisampled buffers, but you couldn't texture with them. You could only blit them.
In 3.3 OpenGL, you can create multisampled textures. And you can attach them just like any other texture to an FBO.

Normal back buffer + render to depth texture in OpenGL (FBOs)

Here's the situation: I have a texture containing some depth values. I want to render some geometry using that texture as the depth buffer, but I want the color to be written to the normal framebuffer (i.e., the window's framebuffer).
How do I do this? I tried creating an FBO and only binding a depth texture to it (GL_DEPTH_COMPONENT) but that didn't work; none of the colors showed up.
No you can't. The FBO you are rendering to may be either a main framebuffer or an off-screen one. You can't mix them in any way.
Instead, I would suggest you to render to a color renderbuffer and then do a simple blitting operation into the main framebuffer.
Edit-1.
Alternatively, if you already have depth in the main FB, you can first blit your depth and then render to a main FB, thus saving video memory on the additional color renderbuffer.
P.S. Blitting is done via glBlitFramebuffer. In order to make it work you should setup GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER and glDrawBuffer() for each of them.

Fragment shader rendering to off-screen frame buffer

In a Qt based application I want to execute a fragment shader on two textures (both 1000x1000 pixels).
I draw a rectangle and the fragment shader works fine.
But, now I want to renderer the output into GL_AUX0 frame buffer to let the result read back and save to a file.
Unfortunately if the window size is less than 1000x1000 pixels the output is not correct. Just the window size area is rendered onto the frame buffer.
How can I execute the frame buffer for the whole texture?
The recommended way to do off-screen processing is to use Framebuffer Objects (FBO). These buffers act similar the render buffers you already know, but are not constrained by the window resolution or color depths. You can use the GPGPU Framebuffer Object Class to hide low-level OpenGL commands and use the FBO right away. If you prefer doing this on your own, have a look at the extension specification.