FBO glClear not clearing the entire texture

I’m having this trouble and I’ve spent several days trying to figure it out.

I have a Framebuffer Object, and I have extensively tested it for a wide variety of issues, however I cannot find any information on my issue and so I am posting here.

In advance, yes the FBOs are tested as “complete”, the textures are RGBA8 (though I tested them with RGBA16 for a while, not sure how widely supported it is), and I used http://www.opengl.org/wiki/GL_EXT_framebuffer_object among others to figure all of that out, including reading the specs.

Facts about this situation:

  1. I have successfully created 2 FBOs using the same exact class, with no sub-classes or modifications to the parameters.

  2. FBO 1 and 2 are both attached to a pair of mutually exclusive attachments, a) RBO Depth b) ColorMap Texture (0)

  3. Both are built at the requested size of 1024x1024

  4. When I use glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) after setting the color to orange, it does write to them without any glErrors, but in one case (FBO 1) it writes only to a 512x384 subsection, always in the same place, and in the other case (FBO 2) it only clears a region that is 1/4th the size, anchored at the middle of the texture (in fact, both are…)

Here is the code I use to put a “Test pattern” on the FBO:

[b]

 // Renders a test pattern on the fBO
 void RenderTestSceneOnFBO() {
  glDisable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() Pre" );
  glReportError( glGetError() );
  glViewport(0, 0, (GLsizei) w, (GLsizei) h);
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() glViewport" );
  glReportError( glGetError() );
  glClearColor((GLclampf) 1.0f,(GLclampf) 0.6f,(GLclampf) 0.4f,(GLclampf) 1.0f);
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() glClearColor" );
  glReportError( glGetError() );
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() glClear" );
  glReportError( glGetError() );
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
 }

[/b]

  1. See this image from gDebugger:

Any help would be greatly appreciated.

Dev Platform: NVIDIA 570 1280GB GDDR3, Windows 7 Ultimate, Microsoft Visual C++ 2010 Express, 3.3GHZ Intel Sandybridge

The issue:

(FBO 1 Color Attachment 0 above)

(FBO 2 Color Attachment 1 above)

Code used to create the attachments follows the tutorial above. We are attempting “render to texture”


Output from the program start:

GL_ARB_framebuffer_object is present, and:
GL_ARB_framebuffer_blit is not supported.
Multisampling disabled.
NPOT textures are supported.
GL_ARB_texture_rectangle is supported.
FBOs are supported with 0 samples and 8 attachments
Multiple render targets are supported.
GL_EXT_framebuffer_object is present, and:
GL_EXT_framebuffer_multisample is not supported.
Multisampling disabled.
NPOT textures are supported.
GL_ARB_texture_rectangle is supported.
FBOs are supported with 0 samples and 8 attachments
Multiple render targets are supported.
Video card supports GL_ARB_vertex_buffer_object.
GLSL is supported, proceeding
Deferred shading supported.
Per-pixel lighting supported.
Point sprites are supported.
NVIDIA graphics card detected.
NVIDIA Corporation GeForce GTX 570/PCI/SSE2 4.1.0
Renderbuffer #1:
rgba=0,0,0,0,GL_FRAMEBUFFER_COMPLETE OK, using FBO id=1
FBO 1 is a 1024x1024 texture with id 2
FBO 1 is an RBO depth attachment:
Renderbuffer #1:
rgba=0,0,0,0,FBO is `complete`.
Renderbuffer #2:
rgba=0,0,0,0,GL_FRAMEBUFFER_COMPLETE OK, using FBO id=2
FBO 2 is a 1024x1024 texture with id 3
FBO 2 is an RBO depth attachment:
Renderbuffer #2:
rgba=0,0,0,0,FBO is `complete`.
2 windows.

Note, in the first provided image, I am demonstrating what happens when you build a 512x512 image, and glClear with a color of “red”

Other tutorials I have read:

[ul][]http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node51.html[]http://www.opengl.org/registry/specs/ARB/framebuffer_object.txt[]http://nehe.gamedev.net/tutorial/radial_blur__rendering_to_a_texture/18004/ (not fbo)[]http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node51.html[]http://www.opengl.org/wiki/Framebuffer_Object[]http://pyopengl.sourceforge.net/documentation/manual/glPushClientAttrib.3G.html (to see if it interacts and how it can be used with an FBO)[]http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=234319[]http://www.songho.ca/opengl/gl_pbo.html[]http://www.gamedev.net/topic/509632-slow-glclearing-large-fbos/[]http://www.opentk.com/doc/graphics/frame-buffer-objects[]http://www.opengl.org/sdk/docs/man4/xhtml/glTexImage2D.xml[]http://www.songho.ca/opengl/gl_projectionmatrix.html[]http://www.flashbang.se/archives/48[]http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=234319[*] And I think several others[/ul]

Another couple notes:

  1. framebuffer calls with EXT have been removed from my code
  2. here is how i create/init the RBO depth buffer:

 //Create a renderbuffer object to store depth info
 void CreateForDepth( int width, int height ) {
  w=width;
  h=height;
  GL_Assert("CreateForDepth() glReportError
");
  glReportError( glGetError() );
  glGenRenderbuffers(1, &id);
  GL_Assert_Param("CreateForDepth() on RBO id %d
", id);
  glReportError( glGetError() );
  glBindRenderbuffer(GL_RENDERBUFFER, id);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,w, h);
  glBindRenderbuffer(GL_RENDERBUFFER, 0);
  RenderBufferInfo();
 }

  1. another view from gdebugger

Have you got scissor testing enabled? - which could limit the area being cleared.

This was a scissor issue

I fixed part of it by doing:

// Renders a test pattern on the fBO
void RenderTestSceneOnFBO() {
// bool scissorState=scissors.enabled;
// if ( scissorState ) scissors.Disable();
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GL_Assert(“Framebuffer::RenderTestSceneOnFBO() Pre” );
glReportError( glGetError() );
glOrtho(0,w,h,0,0.0,1.0);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
scissors.Push(0,0,w,h);
glClearColor((GLclampf) 1.0f,(GLclampf) 0.6f,(GLclampf) 0.4f,(GLclampf) 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
scissors.Pop();
GL_Assert(“Framebuffer::RenderTestSceneOnFBO() Post” );
glReportError( glGetError() );
// if ( scissorState ) scissors.Enable();
}

Now, however, it only fills the bottom 75% of the texture. I have tried moving glOrtho and glViewport around, to no avail, and I when I disable scissoring, it does clear the entire texture, but the above problem remains.

Note that the 1024x1024 is correctly compensated for. The above is what happens when I attempt to use this code:
[b]


 FBOColorDepth a1,b2,c3,d4,e5,f6,g7,h8,i9,j0;
 void OnLoad() {
  a1.Create(32,32);
  b2.Create(64,64);
  c3.Create(128,128);
  d4.Create(256,256);
  e5.Create(512,512);
  f6.Create(1024,1024);
  g7.Create(2048,2048);
  h8.Create(4096,4096);
  i9.Create(302,203);
  j0.Create(606,606);
 }


 /*
  * When an FBO is larger than the front or back buffers (screen size), you must
  * use a special scissor test to properly anchor the screen.  The Y value becomes
  * negative.  This may impact other gl* (Ortho,Viewport,Scissor,Matrixf) calls
  */
 void ScissorThis() {
  // Calculate the starting X.
  int sx= ( w > display.w ? -(w-display.w) : 0);
  int sy= ( h > display.h ? -(h-display.h) : 0);
  scissors.Push((GLint) sx, (GLint) sy, w,h);
 }
 void ViewportThis() {
  // Calculate the starting X.
  int sx= ( w > display.w ? -(w-display.w) : 0);
  int sy= ( h > display.h ? -(h-display.h) : 0);
  glViewport((GLint) sx, (GLint) sy, (GLsizei) w, (GLsizei) h);
 }

 // Renders a test pattern on the fBO
 void RenderTestSceneOnFBO() {
//  bool scissorState=scissors.enabled;  <= this works
//  if ( scissorState ) scissors.Disable();
  glDisable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() Pre" );
  glReportError( glGetError() );
  glOrtho(0,w,h,0,0.0,1.0);
  ScissorThis();//
  ViewportThis();
  glClearColor((GLclampf) 1.0f,(GLclampf) 0.6f,(GLclampf) 0.4f,(GLclampf) 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  scissors.Pop();//
  GL_Assert("Framebuffer::RenderTestSceneOnFBO() Post" );
  glReportError( glGetError() );
//  if ( scissorState ) scissors.Enable();
 }

[/b]

Output from the program start:

you have an nVidia 570 right?
If so there is no way it does not support arb_Framebuffer_Blit ( my Geforce 8 does)
Yet that’s what your start up reported.

Looks like you have more fundamental issues to sort out first.

BionicBytes: one problem is I am making FBOs bigger than the screen, is that an issue?

Other problem is I could move them around but the glOrtho and glViewport settings don’t make sense like in the demos.

Here is my detection code, I see nothing wrong:
[b]



 void InitFBO() {  
  if ( ARB_FBO=hasExtension("GL_ARB_framebuffer_object") ) {
  //glGenFramebuffersARB         = (PFNGLGENFRAMEBUFFERSPROC)         wglGetProcAddress("glGenFramebuffersARB");
  //glBindFramebufferARB         = (PFNGLBINDFRAMEBUFFERPROC)         wglGetProcAddress("glBindFramebufferARB");
  //glGenRenderbuffersARB        = (PFNGLGENFRAMEBUFFERSPROC)         wglGetProcAddress("glGenRenderbuffersARB");
  //glBindRenderbufferARB        = (PFNGLBINDRENDERBUFFERPROC)        wglGetProcAddress("glBindRenderbufferARB");
  //glRenderbufferStorageARB     = (PFNGLRENDERBUFFERSTORAGEPROC)     wglGetProcAddress("glRenderbufferStorageARB");
  //glFramebufferRenderbufferARB = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbufferARB");
  //glFramebufferTexture1DARB    = (PFNGLFRAMEBUFFERTEXTURE1DPROC)    wglGetProcAddress("glFramebufferTexture1DARB");
  //glFramebufferTexture2DARB    = (PFNGLFRAMEBUFFERTEXTURE2DPROC)    wglGetProcAddress("glFramebufferTexture2DARB");
  //glFramebufferTexture3DARB    = (PFNGLFRAMEBUFFERTEXTURE3DPROC)    wglGetProcAddress("glFramebufferTexture3DARB");
  //glFramebufferTextureLayerARB = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) wglGetProcAddress("glFramebufferTextureLayerARB");
   OUTPUT("GL_ARB_framebuffer_object is present, and:
" );
   if ( ARB_FBO_multisample=hasExtension("GL_ARB_framebuffer_multisample") )
    OUTPUT("GL_ARB_framebuffer_multisample is not supported.
Multisampling disabled.
");
   else
   if ( ARB_FBO_blit=hasExtension("GL_ARB_framebuffer_blit") ) {
    glGetIntegerv(GL_MAX_SAMPLES, &fboMaxSamples);
   } else
    OUTPUT("GL_ARB_framebuffer_blit is not supported.
Multisampling disabled.
");
   if ( ARB_FBO_npot=hasExtension("GL_ARB_texture_non_power_of_two") ) OUTPUT( "NPOT textures are supported.
" );
   else OUTPUT("FBO must be square, POT.
");
   if ( ARB_packed_depth_stencil=hasExtension("ARB_packed_depth_stencil") ) OUTPUT( "GL_ARB_packed_depth_stencil is supported.
");
   if ( ARB_FBO_rect=hasExtension("GL_ARB_texture_rectangle") ) OUTPUT("GL_ARB_texture_rectangle is supported.
" );
   glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &fboMaxColorAttachments);
   OUTPUT( "FBOs are supported with %d samples and %d attachments
", fboMaxSamples, fboMaxColorAttachments );
   if ( ARB_draw_buffers=hasExtension("GL_ARB_draw_buffers") ) OUTPUT( "Multiple render targets are supported.
");
   if ( EXTX_mixed_framebuffer_formats=hasExtension("GL_EXTX_mixed_framebuffer_formats") ) OUTPUT("Mixed format FBOs are allowed (slow?).
");
  }

  if ( EXT_FBO=hasExtension("GL_EXT_framebuffer_object") ) {
  //glGenFramebuffersEXT         = (PFNGLGENFRAMEBUFFERSEXTPROC)         wglGetProcAddress("glGenFramebuffersEXT");
  //glBindFramebufferEXT         = (PFNGLBINDFRAMEBUFFEREXTPROC)         wglGetProcAddress("glBindFramebufferEXT");
  //glGenRenderbuffersEXT        = (PFNGLGENFRAMEBUFFERSEXTPROC)         wglGetProcAddress("glGenRenderbuffersEXT");
  //glBindRenderbufferEXT        = (PFNGLBINDRENDERBUFFEREXTPROC)        wglGetProcAddress("glBindRenderbufferEXT");
  //glRenderbufferStorageEXT     = (PFNGLRENDERBUFFERSTORAGEEXTPROC)     wglGetProcAddress("glRenderbufferStorageEXT");
  //glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT");
  //glFramebufferTexture1DEXT    = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)    wglGetProcAddress("glFramebufferTexture1DEXT");
  //glFramebufferTexture2DEXT    = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)    wglGetProcAddress("glFramebufferTexture2DEXT");
  //glFramebufferTexture3DEXT    = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)    wglGetProcAddress("glFramebufferTexture3DEXT");
  //glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) wglGetProcAddress("glFramebufferTextureLayerEXT");
   OUTPUT("GL_EXT_framebuffer_object is present, and:
" );
   if ( EXT_FBO_multisample=hasExtension("GL_EXT_framebuffer_multisample") )
    OUTPUT("GL_EXT_framebuffer_multisample is not supported.
Multisampling disabled.
");
   else
   if ( EXT_FBO_blit=hasExtension("GL_EXT_framebuffer_blit") ) {
    glGetIntegerv(GL_MAX_SAMPLES_EXT, &fboMaxSamples);
   } else
    OUTPUT("GL_EXT_framebuffer_blit is not supported.
Multisampling disabled.
");
   if ( EXT_FBO_npot=hasExtension("GL_ARB_texture_non_power_of_two") ) OUTPUT( "NPOT textures are supported.
" );
   else OUTPUT("FBO must be square, POT.
");
   if ( EXT_packed_depth_stencil=hasExtension("EXT_packed_depth_stencil") ) OUTPUT( "GL_EXT_packed_depth_stencil is supported.
");
   if ( EXT_FBO_rect=hasExtension("GL_ARB_texture_rectangle") ) OUTPUT("GL_ARB_texture_rectangle is supported.
" );
   glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &fboMaxColorAttachments);
   OUTPUT( "FBOs are supported with %d samples and %d attachments
", fboMaxSamples, fboMaxColorAttachments );
   if ( ARB_draw_buffers=hasExtension("GL_ARB_draw_buffers") ) OUTPUT( "Multiple render targets are supported.
");
   if ( EXTX_mixed_framebuffer_formats=hasExtension("GL_EXTX_mixed_framebuffer_formats") ) OUTPUT("Mixed format FBOs are allowed (slow?).
");
  }
 }

[/b]

Actually it does detect it, its just simply needs a !

That’s fixed but the other problems still persist.

FBO can be larger than the screen but is limited to an implementation size. Query the size with GL_MAX_VIEWPORT_DIMS

Why does glOrtho, glViewport etc called on the FBO not do what is expected?