PDA

View Full Version : Is it possible to bind a texture to an FBO and an image?



paulk124
02-05-2013, 12:16 PM
I've created a texture with glTexImage2D. I want to bind it to an image using glBindImageTexture and bind it to an FBO using glFramebufferTexture2D. Is it allowed to have the texture bound to the image and the FBO at the same time?

If not, can I swap between the two bindings? For example, on the first rendering stage I want to draw to the texture bound to an FBO. On the next rendering stage, I want to read from the texture in a shader using images. That is, unbind the texture from the FBO and then bind it to the shader. When I try this, the texture values read in the shader program are always zero.

Here's my code:



GLsizei imageWidth = ...;
GLsizei imageHeight = ...;
// generate depth texture
GLuint depthTexId;
glGenTextures(1, &depthTexId);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, imageWidth, imageHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
// generate color texture
GLuint colorTexId;
...
// generate FBO
GLuint fboId;
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexId, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexId, 0);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// draw stuff into the FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
...
// now we want to read from the texture in a shader program using images
// unbind the textures from the FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// bind the textures to images
glBindImageTexture (0, depthTexId, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
glBindImageTexture (1, colorTexId, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
// now draw to the back buffer
glDrawBuffer(GL_BACK);
...


In my drawing stage where the textures are bound to images, the texture values read by the shader program are all zero. To make sure the textures have non-zero values, I put in a check with glGetTexImage() and looked at the values returned. They are indeed non-zero. For some reason, when I bind the textures to images, the texture values read by the shader program are always zero.

I've put glGetError checks all throughout my code and no errors are reported. I also tried leaving the textures bound to the FBO at the same time they are bound to the images. No errors are generated but the texture values read in the shader program are still zero. My video card is an Nvidia Quadro 2000. I don't know if AMD cards have a similar behavior.

So based on my tests, it appears that once a texture has been bound to an FBO, you can in no way bind the textures to images, even if you first unbind the textures from the FBO. Is this correct or am I missing something?

aqnuep
02-05-2013, 12:46 PM
You should not bind the same texture as an image and as a framebuffer attachment at the same time. Accesses using different paths are non-coherent. Refer to the rendering feedback loops related chapters in the GL spec.

However, if you first use the texture as a framebuffer attachment and then you use it as an image (this time the framebuffer not having the texture bound as attachment), that should work. If not, then either your code is incorrect or you've found a driver bug.

paulk124
02-08-2013, 12:37 PM
aqnuep, thanks for your response.

I think I found the reason why I couldn't bind the texture to the image. The texture was created with the GL_DEPTH_COMPONENT format. glBindImageTexture() doesn't appear to handle textures created with that format. If I want to represent a depth in an image, then I have to use GL_R32F as the internal format and GL_RED for the format. However, if I do this, then glGetTexImage() with a format of GL_RED doesn't interpret the depth values correctly. As a work-around, I'll just keep textures for FBOs and images separate.