james_lohr's picture

Issue with GL.Clear() on FBOs

I've encountered an issue when calling: GL.Clear(ClearBufferMask.ColorBufferBit); when I've got an FBO bound. Instead of clearing the whole FBO as I would expect, it appears to clear a rectangle of the FBO that is the size of the previous FBO I had bound.

I'm using FBOs as overlays, and I use the code below to Begin and End rendering to an overlay. All rendering works fine, and I can (as a work around) simply render a rectangle instead of clearing. However, I'm pretty sure I'm doing something wrong so it would be nice to get to the bottom of it.

So, suppose I create two overlays (one that is 256x256, and another that is 512x512), if I Begin()/End() on the first overlay, then I Begin(), GL.Clear(), then End() on the second overlay, it will only clear a 256x256 area of the FBO.

Any ideas?

 
public virtual void Begin()
        {
 
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, FboHandle);
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, ColorTexture, 0);
            GL.DrawBuffer((DrawBufferMode)FramebufferAttachment.ColorAttachment0Ext);
 
            GL.PushAttrib(AttribMask.ViewportBit); // stores GL.Viewport() parameters
            GL.Viewport(0, 0, FboWidth, FboHeight);
 
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix(); //push projection matrix
            GL.LoadIdentity();
 
            GL.Ortho(projLeft, projRight, projBottom, projTop,-1,100);
 
            GL.MatrixMode(MatrixMode.Modelview);
 
            GL.PushMatrix();  //push modelview matrix
            GL.LoadIdentity();
 
            GL.Disable(EnableCap.DepthTest); //perhaps shouldn't be in base class
 
        }
 
        /// <summary>
        /// End overlay rendering
        /// </summary>
        public virtual void End()
        {
            GL.MatrixMode(MatrixMode.Modelview);
            GL.PopMatrix(); //pop modelview matrix
 
            //back to ordinary blending
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
 
            GL.PopAttrib(); // restores GL.Viewport() parameters
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // return to visible framebuffer
            GL.DrawBuffer(DrawBufferMode.Back);
 
            GL.MatrixMode(MatrixMode.Projection);
            GL.PopMatrix();  //pop projection matrix
            GL.MatrixMode(MatrixMode.Modelview);
 
        }

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tksuoran's picture

Do you use scissoring anywhere?

james_lohr's picture

>>Do you use scissoring anywhere?
Nope.

Interestingly: if I do not call GL.Clear() on the smaller FBO, then GL.Clear() appears to work fine on the larger FBO.

It's almost as if it has cached the size of the smaller FBO upon the first call to GL.Clear()

mOfl's picture

This looks like a viewport issue to me. I'm actually not quite familiar with the deprecated OpenGL calls as I was "forced" from the beginning to use OpenGL 3.2 core profile calls only and thus I don't know if PushAttrib() and PopAttrib() really work as you think. The first thing I would recommend you to test is if the behavior stays the same if you do not use these Push-/PopAttrib calls, but use GL.Viewport(0, 0, 256, 256) and GL.Viewport(0, 0, 512, 512) explicitly where you need it.

james_lohr's picture

>>The first thing I would recommend you to test is if the behavior stays the same if you do not use these Push-/PopAttrib calls

The issue is not related to Push-/PopAttrib calls. I have removed them from my application. I've written a little minimal application which demonstrates the issue: http://www.opentk.com/node/2817 . It would probably be more useful to continue the discussion in that thread. :)

>>PushAttrib() and PopAttrib() really work as you think
Havethey been officially deprecated? What is the alternative - are we now supposed to read the current viewport via GL.GetInteger(GetPName.Viewport,..) ?