Is it possible to attach a texture to an FBO which has mipmaps?
I am currently trying to do this.I have a texture with several mipmap levels. I am attaching it to an FBO. When I clear the color for this buffer I still see the original texture in the output. Once I attach another texture with 1 mipmap level only the FBO draws the results correctly.
Though it's hard to say where your problem lies without any code, the fast and easy answer is just: Of course this is possible! Ever wondered what the level parameter of all those glFramebufferTexture functions is for?
But you can only write to a single mipmap level of the respective texture, all the other levels will be unchanged. The usual way is to write into mipmap level 0 (as you would do for a non-mipmapped texture) and generate the remaining levels by means of glGenerateMipmap. But you can also write to any other level or to each and every level individually.
Related
glFramebufferTexture allows one to bind an entire cubemap as a color attachment for layered rendering. In turn, glReadBuffer then allows one to bind said entire cubemap as a read buffer.
I want to render a scene to the non-zero mip levels of a cubemap texture. I'm using layered rendering to render not to one face, but to the entire thing in one go. However, the shader used for this uses the 0th mip level of that same texture. Since I don't think I can expose the texture to a shader and to a framebuffer attachment at the same time, I'm rendering to a different texture and copying the contents of that texture to my original texture's desired mip level.
Right now I'm doing this with a pass-through shader, which is pretty slow since it's layered rendering thus uses a geometry shader, and it would be better to use an API function. However, glCopyTexSubImage2D only allows cubemap faces, and neither it nor glCopyTexSubImage3D seem to accept cubemaps as input. Apart from 4.5-specific functions such as glCopyTextureSubImage3D, is there any way to retrieve an entire cubemap from the framebuffer into a cubemap texture ? I'm also aware that glCopyImageSubData exists, but something at the feature level of glFramebufferTexture is preferrable (so 3.2).
Can I have textures of different sizes attached to a single FBO, and then use those for multiple render targets? Will I need to do anything special with glViewport to make this happen? Suppose I have a 1024x1024 texture for COLOR_ATTACHMENT0 and a 512x512 texture for COLOR_ATTACHMENT1, and I call glDrawBuffers(2, {COLOR_ATTACHMENT0, COLOR_ATTACHMENT1}) (I realize that syntax is incorrect, but you get the idea...), will it render the full scene in both attachments? I'm chiefly thinking the utility of this would be the ability to render a scene at full quality and a down-sampled version at one go, perhaps with certain masks or whatever so it could be used in an effects compositor/post-processing. Many thanks!
Since GL3.0 you can actually attach textures of different sizes. But you must be aware that the rendered area will be the one of the smallest texture. Read here :
http://www.opengl.org/wiki/Framebuffer_Object
Can the same texture be bound to more than one framebuffer object?
I need to write on some texture in a multi target rendering pass with a certain fbo, and later to add some blending to just one of those texture, so I need a second framebuffer object with that texture bound to.
I have no idea why you would think that you can't attach a texture to multiple FBOs. So yes, you can.
However, you shouldn't need to for your purposes. You don't have to write to all of the images attached to an FBO. You control what images get written to with glDrawBuffers. You can even selectively enable and disable blending to certain draw buffers, if you need to write to multiple buffers but only blend with certain ones.
So yes you can, but you shouldn't bother. Just switch your draw buffers, unless you need a new depth buffer or something.
I want to determine the size (width, height) of a framebuffer object.
I created a framebuffer object via
// create the FBO.
glGenFramebuffers(1, &fboId);
How can I get the size of the first color attachment given only the framebuffer object id (fboId)?
Is this possible or do I have tor store the size of the color attachment in an external variable to know later the size of the FBO?
Your question is somewhat confused, as you ask for two different things.
Here's the easy question:
How can I get the size of the first color attachment given only the framebuffer object id (fboId)?
That's simple: get the texture/renderbuffer attached to that attachment, get what mipmap level and array layer is attached, then query the texture/renderbuffer for how big it is.
The first two steps are done with glGetFramebufferAttachmentParameter (note the key word "Attachment") for GL_COLOR_ATTACHMENT0. You query the GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE to get whether it's a renderbuffer or a texture. You can get the renderbuffer/texture name with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME.
If the object is a renderbuffer, you can then bind the renderbuffer and use glGetRenderbufferParameter to fetch the renderbuffer's GL_RENDERBUFFER_WIDTH and GL_RENDERBUFFER_HEIGHT.
If the object is a texture, you'll need to do more work. You need to query the attachment parameter GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL to get the mipmap level.
Of course, now you need to know how to bind it. If you're using OpenGL versions before 4.4 or without certain extensions, then this is complicated. See, you need to know which texture target type to use. Silly and annoying as this may seem, the only way to determine the target from just the texture object name is to... try everything. Go through each target and check glGetError. The one for which GL_INVALID_OPERATION isn't returned is the right one.
If you have GL 4.4 or ARB_multi_bind available, you can just use glBindTextures (note the "s"), which does not require that you specify the target. And if you have 4.5 or ARB_direct_state_access, you don't need to bind the texture at all. The DSA-style functions don't need the texture target, and it also provides glBindTextureUnit, which binds a texture to its natural internal target.
Once you have the texture bound and it's mipmap level, you use glGetTexLevelParameter to query the GL_TEXTURE_WIDTH and GL_TEXTURE_HEIGHT for that level.
Now, that's the easy problem. The hard problem is what your title asks:
I want to determine the size (width, height) of a framebuffer object.
The size of the renderable area of an FBO is not the same as the size of GL_COLOR_ATTACHMENT0. The renderable area of an FBO is the intersection of all of the sizes of all of the images attached to the FBO.
Unless you have special knowledge of this FBO, you can't assume that the FBO contains only one image or that all of the images have the same size (and if you have special knowledge of the FBO, then quite frankly you should also have special knowledge of how big it is). So you'll need to repeat the above procedure for every attachment (if the type is GL_NONE, then nothing is attached). Then take the intersection of the returned values (ie: the smallest width and height).
In general, you shouldn't have to ask an FBO that you created how big it is. Just as you don't have to ask textures how big they are. You made them; by definition, you know how big they are. You put them in the FBO, so again you know how big it is.
in each frame (as in frames per second) I render, I make a smaller version of it with just the objects that the user can select (and any selection-obstructing objects). In that buffer I render each object in a different color.
When the user has mouseX and mouseY, I then look into that buffer what color corresponds with that position, and find the corresponding objects.
I can't work with FBO so I just render this buffer to a texture, and rescale the texture orthogonally to the screen, and use glReadPixels to read a "hot area" around mouse cursor.. I know, not the most efficient but performance is ok for now.
Now I have the problem that this buffer with "colored objects" has some accuracy problems. Of course I disable all lighting and frame shaders, but somehow I still get artifacts. Obviously I really need clean sheets of color without any variances.
Note that here I put all the color information in an unsigned byte in GL_RED. (assumiong for now I maximally have 255 selectable objects).
Are these caused by rescaling the texture? (I could replace this by looking up scaled coordinates int he small texture.), or do I need to disable some other flag to really get the colors that I want.
Can this technique even be used reliably?
It looks like you're using GL_LINEAR for your GL_TEXTURE_MAG_FILTER. Use GL_NEAREST instead if you don't want interpolated colors.
I could replace this by looking up scaled coordinates int he small texture.
You should. Rescaling is more expensive than converting the coordinates for sure.
That said, scaling a uniform texture should not introduce artifacts if you keep an integer ratio (like upscale 2x), with no fancy filtering. It looks blurry on the polygon edges, so I'm assuming that's not what you use.
Also, the rescaling should introduce variations only at the polygon boundaries. Did you check that there are no variations in the un-scaled texture ? That would confirm whether it's the scaling that introduces your "artifacts".
What exactly do you mean by "variance"? Please explain in more detail.
Now some suggestion: In case your rendering doesn't depend on stencil buffer operations, you could put the object ID into the stencil buffer in the render pass to the window itself, don't use the detour over a separate texture. On current hardware you usually get 8 bits of stencil. Of course the best solution, if you want to use a index buffer approach, is using multiple render targets and render the object ID into an index buffer together with color and the other stuff in one pass. See http://www.opengl.org/registry/specs/ARB/draw_buffers.txt