0

I've been attempting to implement deferred shading/rendering into my engine for a while now, however I haven't been able to actually see the final product of it.

To test where the issue may lie, I've devised an experiment to see if my target FBO was actually being read from and into my default FBO, via the glBlitFramebuffer() command.

I've made it so that before my default FBO clears itself, the clear color was set to black, and before my target FBO clears itself the clear color was set to red.

The result is that when I render my scene, all I see is black.

My question is this:

If one fbo is set to a read_framebuffer, and the default is set to a draw_framebuffer, would the "clear colored" pixels also get copied during the "glBlitFramebuffer" operation?

If no, then there is no telling whether or not my target FBO is actually being rendered, as that color wouldn't copy anyways.

If yes, then I should be seeing the color red, and I have no idea what is wrong with my FBO set up...


As I've previously stated, I've been trying to work on a deferred shading system. That system required me to perform all my operations in an FBO, and then render its entirety back onto the default FBO.

Since it wasn't working, I've simplified its procedure to either render a basic scene straight to the default FBO (which works), or render it onto a target FBO and follow the procedure to copy that FBO back onto the default FBO (which doesn't work).

The frame buffer set up I'm trying to use is the same as the tutorial I've been following:

glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glGenTextures(1, &m_finalTexture);
glBindTexture(GL_TEXTURE_2D, m_finalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, m_finalTexture, 0);

And I render my scene like this (simplified):

//Flush content out of fbo at color attachment 4
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glClear(GL_COLOR_BUFFER_BIT);

//Render scene to m_fbo 
RenderPass();

//Swap default FBO back ("0"), read from target fbo (m_fbo)
//Draw target fbo onto default fbo
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glReadBuffer(GL_COLOR_ATTACHMENT4);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);

I've checked my frame buffer status every step of the way and I get no errors.


I've found the actual problem, I will update this here post with more information when I fully understand it.

Community
  • 1
  • 1
Yattabyte
  • 1,280
  • 14
  • 28
  • `m_dfbo` is also an FBO? How do you actually verify that the whole thing worked? Are you copying to the default framebuffer at some point? – Reto Koradi Sep 08 '15 at 01:35
  • Yes. I used the variable m_dfbo as the "default fbo", it equaled 0 anyways. I updated the opening post and changed m_dfbo to "0" to be more concise. – Yattabyte Sep 08 '15 at 01:37

2 Answers2

2

This call sequence is invalid:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
...
glDrawBuffer(GL_COLOR_ATTACHMENT4);

GL_COLOR_ATTACHMENT4 is not a valid draw buffer for the default framebuffer. It is only valid if the current draw framebuffer is an FBO. For the default framebuffer, you need to use:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
...
glDrawBuffer(GL_BACK);

This will allow glBlitFramebuffer() to copy into the back buffer of your default framebuffer.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • I've tried that to no avail, even GL_BACK_LEFT as the wiki page suggests doesn't seem to make any difference. Framebuffers in general store whatever its last configuration of buffers were, correct? If that's the case, then even never specifying a draw buffer (and using the default configuration) for the default FBO won't work when copying from the target FBO into the default FBO – Yattabyte Sep 08 '15 at 01:50
  • Hmm, not sure what else is wrong. The arguments to `glTexImage2D()` look slightly odd, but I think they should still work. I would use `GL_RGBA` and `GL_UNSIGNED_BYTE` for the format and type arguments. – Reto Koradi Sep 08 '15 at 01:56
  • Thanks for still bearing with me. I've made those changes too, but to no avail. – Yattabyte Sep 08 '15 at 01:58
  • @Yattabyte You don't show the `glClearColor()` calls in the original code. Is the call that sets it to red immediately before the `glClear()` call for the FBO? – Reto Koradi Sep 08 '15 at 02:04
  • It was, yes. I've since removed all but one (in the renderer's initialization). I've done that test again with the changes you've suggested, however the result is the same. – Yattabyte Sep 08 '15 at 02:05
  • If you have any other ideas for troubleshooting this problem, I'm all ears. – Yattabyte Sep 08 '15 at 02:28
  • Alright I figured out what the problem is, however I don't know how to solve it really. I've opened a different question and will solve this one once the other is solved. For some reason the operations I'm doing with the frame buffers doesn't do anything when its in a separate class like the GBuffer, but if I move those functions directly into my rendering class and use them instead, it works fine. – Yattabyte Sep 08 '15 at 03:56
  • @Yattabyte Might be the common problem when wrapping OpenGL objects in C++ classes where OpenGL objects are wiped out during unintentional assignment or copy construction. See for example: http://stackoverflow.com/questions/28929452/mesh-class-called-with-default-constructor-not-working-opengl-c. – Reto Koradi Sep 08 '15 at 04:09
0

The problem all along was that my call to bind the default frame buffer just wouldn't work if done outside of the main rendering class. So I moved that line out of my GBuffer and into my main rendering class and performed that before calling GBuffer.FinalPass();

Yattabyte
  • 1,280
  • 14
  • 28