FBO to separate textures - c++

How do I set FBO so it renders depth and color buffer in two separate textures, in one rendering pass ?

Just attach a suitable texture to the FBOs depth attachment point:
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, textureId, 0);
.. and another texture to the color attachment point. See this for more information.

Related

Render to a layer of a texture array in OpenGL

I use OpenGL 3.2 to render shadow maps. For this, I construct a framebuffer that renders to a depth texture.
To attach the texture to the framebuffer, I use:
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shdw_texture, 0 );
This works great. After rendering the light view, my GLSL shader can sample the depth texture to solve visibility of light.
The problem I am trying to solve now, is to have many more shadow maps, let's say 50 of them. In my main render pass I don't want to be sampling from 50 different textures. I could use an atlas, but I wondered: could I pass all these shadow maps as slices from a 2D texture array?
So, somehow create a GL_TEXTURE_2D_ARRAY with a DEPTH format, and bind one layer of the array to the framebuffer?
Can framebuffers be backed for DEPTH by a texture array layer, instead of just a depth texture?
In general, you need to distinguish whether you want to create a layered framebuffer (see Layered Images) or whether you want to attach a single layer of a multilayered texture to a framebuffer.
Use glFramebufferTexture3D to attach a layer of a 3D texture (TEXTURE_3D) or array texture to a framebuffer or use glFramebufferTextureLayer to attach a layer of a three-dimensional or array texture to the framebuffer. In either case the last argument specifies the layer of the texture.
Layered attachments can be attached with glFramebufferTexture. See Layered rendering.

OpenGL glDrawBuffer and glBindTexture

I'm still new on opengl3 and I'm trying to create a multipass rendering.
In order to do that, I created FBO, generated several textures and attached them to it with
unsigned index_col = 0;
for (index_col = 0; index_col < nbr_textures; ++index_col)
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index_col, texture_colors[index_col], 0);
It works well (I try to believe that I'm doing good here!).
My comprehension problem occurs after, when I try to render in the first texture offscreen, then in the second texture, then render on the screen.
To render to a particular texture, I'm using :
FBO.bind();
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBindTexture(GL_TEXTURE_2D, FBO.getColorTextures(0)); //getColorTextures(0) is texture_colors[0]
Then I draw, using my shader, and after I would like to do :
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBindTexture(GL_TEXTURE_2D, FBO.getColorTextures(1));
and after all
glBindFramebuffer(GL_FRAMEBUFFER, 0);
RenderToScreen(); // assuming this function render to screen with a quad
My question is :
What is the difference between glDrawBuffer and glBindTexture? Is it necessary to call both? Aren't textures attached to buffer? (I can't test it actually, because I'm trying to make it works...)
Thanks!
glBindTexture is connecting a texture with a texture sampler unit for reading. glDrawBuffer selects the destination for drawing writes. If you want to select a texture as rendering target use glDrawBuffer on the color attachment the texture is attached to; and make sure that none of the texture sampler units it is currently bound to is used as a shader input! The result of creating a feedback loop is undefined.
glDrawBuffer selects the color buffer (in this case of the framebuffer object) that you will write to:
When colors are written to the frame buffer, they are written into the color buffers specified by glDrawBuffer
If you wanted to draw to multiple color buffers you would have written
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, attachments);
while glBindTexture binds a texture to a texture unit.
They serve different purposes - remember that OpenGL and its current rendering context behave as a state machine.

How to draw the off-screen data in the framebuffer object to the QGLWidget?

I use glGenFramebuffer, glBindFramebuffer and other related functions to create the Framebuffer Object(FBO) and I use the FBO to draw the off-screen data. Now my question is that I finish the mentioned steps inside QGLWidget and how can I draw the data in FBO back to QGLWidget? Thank you very much!
Assuming you attached a color buffer to your framebuffer using
glFramebufferTexture2D( myfboID, GL_FRAMEBUFFER, GL_TEXTURE_2D, mytexID, 0);
Change the framebuffer to the widget by
glBindFrameBuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
Simply render a QUAD textured with the previous texture. You can simply render a quad from [-1,-1] to [1,1] and with the above texture bound, and texture coordinates would be [0.0,0.0] - [1.0,1.0].

Attaching particular layer in GL_2D_ARRAY_TEXTURE to framebuffer

I have a texture with target GL_TEXTURE_2D_ARRAY. I want to render to each layer separately as FBO attachment. how do i bind particular layer to framebuffer as attachment?
Use the glFramebufferTextureLayer function to attach the texture layer to the FBO.
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, someTexture, mipmapLevel, layer);
Alternatively, use the gl_Layer variable in a geometry shader to select at render time which layer to render to.

GL_TEXTURE_3D color and stencil FBO attachments

I am doing a layered rendering to an offscreen FBO using OpenGL 4.3.I used GL_TEXTURE_3D with several layers as COLOR attachment.Then I use geometry shader to index into different layers when writing the output.It works ok.Now I need also stencil attachment for stencil test I am performing during the rendering.First I tried just to attach a render buffer as in the case with 2D attachments.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, _stencilBuffer)
In this case,when checking FBO for completeness I am getting frame buffer error:
GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB
Then I assumed that if the color attachment is 3D so the stencil attachment also must be 3D.And because there is no 3D render buffer I tried to attach a 3D texture for depth stencil slot of the FBO.
glTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH24_STENCIL8, width, height, depth,
0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
Where width - texture width,height-texture height,depth-number of layers inside texture 3D.
//Attach to FBO:
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, texId, 0));
Doing it this way I am getting:
GL_FRAMEBUFFER_INCOMPLETE
INVALID_OPERATION
I have searched any possible example to find how such a setup should be done,but found nothing.I also tried to use GL_TEXTURE_2D_ARRAY instead,but same problem. (for some reason this actually fixed the problem which persisted in my earlier tests)
UPDATE
My fault as got confused with some of my findings during the debug.Basically half of what I wrote above can be discarded.But because other people may get into the same issues I will explain what happened.
At first,when I attached a 3d texture to COLOR attachment of FBO I created a render buffer for GL_DEPTH_STENCIL attachment.And yes,on completeness check I got:
GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB
Next,I tried instead:
glTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH24_STENCIL8, width, height, depth,
0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
which thrown:
INVALID_OPERATION
Now,instead of GL_TEXTURE_3D target I tried GL_TEXTURE_2D_ARRAY which finally caused the FBO to be complete.So,while I would still like to understand why GL_TEXTURE_3D causes INVALID_OPERATION(feel free to post an answer),this change has solved the problem.
Based on the spec, GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS means (quoted from OpenGL 4.5 spec):
If any framebuffer attachment is layered, all populated attachments must be layered. Additionally, all populated color attachments must be from textures of the same target (three-dimensional, one- or two-dimensional array, cube map, or cube map array textures).
Based on the first part of this, your initial attempt of using a single layer stencil attachment with a layered 3D texture color attachment was clearly illegal.
The second part sounds somewhat unclear to me. Since it only talks about "color attachments", it suggests that using a GL_TEXTURE_3D color attachment and a GL_TEXTURE_2D_ARRAY stencil attachment would be legal. But I'm not convinced that this is actually the intention. Unfortunately I couldn't find additional confirmation of this in the rest of the spec.
Using GL_TEXTURE_3D for a stencil or depth/stencil texture is a non-starter. There's no such thing as a 3D stencil texture. From the 4.5 spec, pages 191-192 in section "8.5 Texture Image Specification"
Textures with a base internal format of DEPTH_COMPONENT, DEPTH_STENCIL, or STENCIL_INDEX are supported by texture image speciļ¬cation commands only if target is TEXTURE_1D, TEXTURE_2D, TEXTURE_2D_MULTISAMPLE, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D_MULTISAMPLE_ARRAY, TEXTURE_RECTANGLE, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D, PROXY_TEXTURE_2D_MULTISAMPLE, PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY, PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, PROXY_TEXTURE_RECTANGLE, PROXY_TEXTURE_CUBE_MAP, or PROXY_TEXTURE_CUBE_MAP_ARRAY.
That's a long list, but TEXTURE_3D is not in it.
Based on this, I believe that what you found to be working is the only option. You need to use textures with target GL_TEXTURE_2D_ARRAY for both the color and stencil attachment.