Jump to content
• Advertisement

# OpenGL OpenGL: Depth Attachment breaks Framebuffer

This topic is 565 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

I need a fresh pair of eyes. While working on rewriting my engine, I stumbled upon this issue while writing the Deferred Rendering path. The framebuffer displays only if I don't use a depth attachment, which means that the rendering is faulty, but if I do, all the outputs are blank. I wrote a lot of graphics handling classes but I broke down the code here:

Initialization:

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glClearColor(0, 0, 0, 1);
glViewport(0, 0, 1024, 768);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderPreparation();

numBuffer = 3;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
numBuffers = numBuffer;
targetBuffer = 0;
textures = new unsigned int[numBuffers];
glGenTextures(numBuffers, textures);

This is done three times:

glBindTexture(GL_TEXTURE_2D, textures[targetBuffer]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, colorType, width, height, 0, colorFormat, colorDataType, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + targetBuffer, GL_TEXTURE_2D, textures[targetBuffer], 0);
targetBuffer++;

Then I create the Depth Attachment:

glGenTextures(1, &renderBuffer);
glBindTexture(GL_TEXTURE_2D, renderBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderBuffer, 0);

Forgot the last bit of the FBO:

GLenum *DrawBuffers = new GLenum[numBuffers];
for (size_t i = 0; i < numBuffers; i++)
DrawBuffers = GL_COLOR_ATTACHMENT0 + i;

glDrawBuffers(numBuffers, DrawBuffers);

// Report errors
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "Framebuffer Error. Status 0x%x\n", status);
}

// Unbind
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

Finally, my drawing (all calculations for geometry shader happens before this):

geometryShader->Use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
graphicsWrapper->render(Geometry);

int val[3] = { 0,1,2 };
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
deferredShader->Use();

glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, textures[2]);

// I use this system so it's compatible with Uniform Buffer
// Objects and the rendering code of other graphics languages
deferredShader->PassData(&val);
deferredShader->SetInteger();
deferredShader->SetInteger();
deferredShader->SetInteger();

glClear(GL_COLOR_BUFFER_BIT);

vaoQuad->Bind();
graphicsWrapper->DrawVertexArray(4);
vaoQuad->Unbind();

Note that my code is much more object oriented than this, and I had to take a lot of this code out of context. My question is, why does attaching the depth attachment to the framebuffer cause the framebuffer to blank, while removing it works, and how do I fix it?

I know that it's not a renderbuffer, I just called the depth texture that because it USED to be a renderbuffer, and I forgot to change the name.

#### Share this post

##### Share on other sites
Advertisement

no no no baby you dont attach depthbuffer to fbo like that: first of all after creating fbo you create RBO (render buffer object), you attach depthbuff tex to rbo, and then you define that glFramebufferTexture2D thing, also remember that your framebuffer doesn't have depth testing and depth equation defined, so you do (base gl setting)

glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);

glDepthFunc(GL_LEQUAL);

glEnable(GL_DEPTH_TEST);

//draw

glDisable(GL_DEPTH_TEST);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

also you can set depth testing only once (while fbo binded) and you wont have to call depthfunc and glenable every frame.

int w = 512;
int h = 512;

unsigned int FBO_TEX;
unsigned int FBO_DEPTH;
unsigned int FBO_ID;
unsigned int RBO_ID;

glGenTextures(1, &FBO_TEX);
glBindTexture(GL_TEXTURE_2D, FBO_TEX);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenTextures(1, &FBO_DEPTH);
glBindTexture(GL_TEXTURE_2D, FBO_DEPTH);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenFramebuffers(1, &FBO_ID);
glGenRenderbuffers(1, &RBO_ID);
glBindRenderbuffer(GL_RENDERBUFFER, RBO_ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);
glBindTexture(GL_TEXTURE_2D, FBO_TEX);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
RBO_ID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBO_TEX, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, FBO_DEPTH, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);



just be sure to set GL_DEPTH_COMPONENT correct i mean use only one that your device is using for your app

the code is a part of OGL ES 2.0 so i use GL_RGBA and GL_DEPTH_COMPONENT16 for texture

Edited by WiredCat

#### Share this post

##### Share on other sites

no no no baby you dont attach depthbuffer to fbo like that: first of all after creating fbo you create RBO (render buffer object), you attach depthbuff tex to rbo, and then you define that glFramebufferTexture2D thing, also remember that your framebuffer doesn't have depth testing and depth equation defined, so you do (base gl setting)

glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);

glDepthFunc(GL_LEQUAL);

glEnable(GL_DEPTH_TEST);

//draw

glDisable(GL_DEPTH_TEST);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

also you can set depth testing only once (while fbo binded) and you wont have to call depthfunc and glenable every frame.

int w = 512;
int h = 512;

unsigned int FBO_TEX;
unsigned int FBO_DEPTH;
unsigned int FBO_ID;
unsigned int RBO_ID;

glGenTextures(1, &FBO_TEX);
glBindTexture(GL_TEXTURE_2D, FBO_TEX);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenTextures(1, &FBO_DEPTH);
glBindTexture(GL_TEXTURE_2D, FBO_DEPTH);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGenFramebuffers(1, &FBO_ID);
glGenRenderbuffers(1, &RBO_ID);
glBindRenderbuffer(GL_RENDERBUFFER, RBO_ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);
glBindTexture(GL_TEXTURE_2D, FBO_TEX);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,
RBO_ID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FBO_TEX, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, FBO_DEPTH, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);



just be sure to set GL_DEPTH_COMPONENT correct i mean use only one that your device is using for your app

the code is a part of OGL ES 2.0 so i use GL_RGBA and GL_DEPTH_COMPONENT16 for texture

But aren't renderbuffers simply framebuffer textures that are never displayed and instead used for calculations? So hypothetically the depth buffer could be in either a GL_TEXTURE_2D OR a RenderBuffer?

Also I did enable GL_DEPTH_TEST albeit outside FBOs, as well as set the DepthFunc to GL_LESS. http://stackoverflow.com/questions/2213030/whats-the-concept-of-and-differences-between-framebuffer-and-renderbuffer-in

EDIT: I simply added the depth testing within the FBO Binds and it appears to work. I did not have to modify the FBO Buffer Creation, but can't figure out how to make the depth testing automatically bound, as you said before.

Edited by KarimIO

#### Share this post

##### Share on other sites

Render Buffers do NOT have texture attachments. Render Buffer are offscreen buffers managed by OpenGL that can be used as framebuffer attachment points ( if one could say that ). Just wanted to add that clarification, as per the question, the posted code is somewhat confusing ( had a hard time following the layout ), so can't give a firm answer. Are you checking to make sure all FBO are complete prior to using them ?

#### Share this post

##### Share on other sites

EDIT: I simply added the depth testing within the FBO Binds and it appears to work. I did not have to modify the FBO Buffer Creation, but can't figure out how to make the depth testing automatically bound, as you said before.

after creating framebuffer object you just

glDepthFunc(GL_LEQUAL);

glEnable(GL_DEPTH_TEST

and you disable framebuff

glBindFrameBuffer(GL_FRAMEBUFFER, 0);

now whenever you call

glBindFrameBuffer(GL_FRAMEBUFFER, dat_framebuff_with_depth_enabled);

you should have depth working

#### Share this post

##### Share on other sites

no no no baby you dont attach depthbuffer to fbo like that: first of all after creating fbo you create RBO (render buffer object), you attach depthbuff tex to rbo

Aren't you mistaken here?

You either bind depth texture to fbo, or renderbuffer with depth format storage. You go with texture if later you'll need to sample rendered depth surface, and you go with renderbuffer if you don't need actual result.

In your example you create depth texture, but it's not used anywhere. You set renderbuffer as depth attachment, allocating new storage for that buffer with glRenderbufferStorage. Created earlier depth texture (FBO_DEPTH object) is left unused.

#### Share this post

##### Share on other sites

i dont know i found that working on android devices so i assume that is correct :P

#### Share this post

##### Share on other sites

Aren't you mistaken here?

Yes he is.

As per the question, since you are only binding a depth buffer and not a depth-stencil buffer, ensure that stencil operations are disabled.
Check the framebuffer status after creation always.
Use RenderDoc or gDEBugger to debug your OpenGL state.

L. Spiro

#### Share this post

##### Share on other sites

Render Buffers do NOT have texture attachments. Render Buffer are offscreen buffers managed by OpenGL that can be used as framebuffer attachment points ( if one could say that ). Just wanted to add that clarification, as per the question, the posted code is somewhat confusing ( had a hard time following the layout ), so can't give a firm answer. Are you checking to make sure all FBO are complete prior to using them ?

Yeah that's what I understood, which is why WireCat's code confused me a bit! As I said, the two things that fixed my code was when I cleared (after binding), and enabling depth after binding as opposed to for the default (unbound) framebuffer, so he did help me there.

L. Spiro, I had already solved the issue (there was no error report when checking the status though, as I think it was technically legal). I usually only use gDEBugger when I need to, and try to rely on internal error checking instead.

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
2. 2
Rutin
21
3. 3
JoeJ
18
4. 4
5. 5
• Advertisement

• 14
• 39
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631717
• Total Posts
3001880
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!