Accessing bytes in an FBO - opengl

I have rendered a texture to an FBO in the hope that I can now apply effects to that texture before displaying it. I cant work out how to access the FBO array to change it. Any idea? Thanks for your time

Could you specify what you mean by adding effects? The basic idea of a fbo is to render everything to that fbo and then apply that fbo to a texture. If you wish to know how to bind that framebuffer to a texture, simple create and setup a texture with an empty data set for glTexImage2D. Then, call glFramebufferTexture2D with your framebuffer object bound and pass in your texture as one of the arguments. To render to your framebuffer, call glBindFramebuffer. To bind your framebuffer texture, simply call glBindTexture, like any other texture.

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.

How to render color and depth in multisample texture?

In order to implement "depth-peeling", I render my OpenGL scene in to a series of framebuffers each equipped with a rgba color texture and depth texture. This works fine if I don't care about anti-aliasing. If I do, then it seems the correct thing to do is enable GL_MULTISAMPLING and use a GL_TEXTURE_2D_MULTISAMPLE instead of GL_TEXTURE_2D. But I'm confused about which other calls need to be replaced.
In particular, how should I adapt my framebuffer construction to use glTexImage2DMultisample instead of glTexImage2D?
Do I need to change the calls to glFramebufferTexture2D beyond using GL_TEXTURE_2D_MULTISAMPLE instead of GL_TEXTURE_2D?
If I'm rendering both color and depth into textures, do I need to make a call to glRenderbufferStorageMultisample?
Finally, is there some glBlit* that I need to do in addition to setting up textures for the framebuffer to render into?
There are many related questions on this topic, but none of the solutions I found seem to point to a canonical tutorial or clear example putting all these together.
While I have only used multisampled FBO rendering with renderbuffers, not textures, the following is my understanding.
Do I need to change the calls to glFramebufferTexture2D beyond using GL_TEXTURE_2D_MULTISAMPLE instead of GL_TEXTURE_2D?
No, that's all you need. You create the texture with glTexImage2DMultisample(), and then attach it using GL_TEXTURE_2D_MULTISAMPLE as the 3rd argument to glFramebufferTexture2D(). The only constraint is that the level (5th argument) has to be 0.
If I'm rendering both color and depth into textures, do I need to make a call to glRenderbufferStorageMultisample?
Yes. If you attach a depth buffer to the same FBO, you need to use a multisampled renderbuffer, with the same number of samples as the color buffer. So you create your depth renderbuffer with glRenderbufferStorageMultisample(), passing in the same sample count you used for the color buffer.
Finally, is there some glBlit* that I need to do in addition to setting up textures for the framebuffer to render into?
Not for rendering into the framebuffer. Once you're done rendering, you have a couple of options:
You can downsample (resolve) the multisample texture to a regular texture, and then use the regular texture for your subsequent rendering. For resolving the multisample texture, you can use glBlitFramebuffer(), where the multisample texture is attached to the GL_READ_FRAMEBUFFER, and the regular texture to the GL_DRAW_FRAMEBUFFER.
You can use the multisample texture for your subsequent rendering. You will need to use the sampler2DMS type for the samplers in your shader code, with the corresponding sampling functions.
For option 1, I don't really see a good reason to use a multisample texture. You might just as well use a multisample renderbuffer, which is slightly easier to use, and should be at least as efficient. For this, you create a renderbuffer for the color attachment, and allocate it with glRenderbufferStorageMultisample(), very much like what you need for the depth buffer.

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

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.

How to post-process image with shaders in OpenGL?

Shaders can not read data from framebuffer, they can pass data only forward by rendering pipeline. But for post-processing it is needed to read rendered image.
I'm going to resolve this as following: 1) create a texture with size of viewport; 2) render image to the texture normally; 3) render the texture to framebuffer passing it through post-processing shader.
Am I doing right? Are there more effective ways to do post-processing?
That is indeed the usual way to do post-processing ! Render to texture by binding an FBO for your first pass, then use that texture as the input of your post-process shader after unbinding your FBO (i.e. returning to the default frame buffer).

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.