ofSetBackgroundAuto() and isNewFrame() in 00573 Windows

I just wanted to point out a couple issues in the 00573 version of codeblocks download for windows.

  1. isNewFrame always reports true still. I posted about this bug before and fixed it. It needs a bIsFrameNew = false under the ifdef OF_VIDEO_CAPTURE_DIRECTSHOW in ofVideoGrabber.cpp.

Also, for some reason I’m having weird issues with auto background. For example, if I tell it to only draw when there’s a new frame, it still clears and draws on every frame.

I opened up ofAppGlutGlee and see that it auto clears:

  
if((bClearAuto == true) || windowMode == OF_WINDOW) || nFrameCount < 3)   

I changed this to:

  
if(( bClearAuto == true && windowMode == OF_WINDOW) || nFrameCount < 3){  
glClear(.....................);  
}  
   

This seem to fix the issue and I could toggle between auto and manual drawing with this change. I think the problem is due to the || between windowMode and bClearAuto so that even if you set it to not auto clear, it’ll still clear because it’s in OF_WINDOW.

hey thanks – good catches !

I’m currently on 0.0573 (actually, svn trunk) on vs 2008 right now and I’ll work them in, and back to the svn shortly.

if you see other issues, please let us know

take care!
zach

edit – good call theo !

  
if((bClearAuto == true) || windowMode == OF_WINDOW) || nFrameCount < 3)  

Although it looks strange that is actually there for a reason.

This is because we were having problems with setting auto clear to false on fullscreen windows apps.

Instead of behaving like the windowed app the screen would flicker and you would get a strange mix of the front and back buffers.

The code you changed it to basically says:
If ( we have set auto clear and we are also windowed ) clear the screen - otherwise don’t clear the screen. This is a mistake as it won’t clear the screen when in fullscreen now - even if you have set auto clear to true.

Ideally the line should read

  
if(bClearAuto == true || nFrameCount < 3)  

but we haven’t solved the fullscreen issue with disabling auto clear.

Theo

hmmm ok Theo, but that makes manual clearing not work for me in both in window mode either. Is there a solution for that?

If the problem is only in fullscreen, couldn’t we check if we’re in fullscreen and if we are, then set auto to true.

Right now, i have an app that does ofSetBackgroundAuto to true in fullscreen and false in window and it seemed to work with the code change.

Actually there is a mistake in the code -
It should be disabling the non auto clearing for fullscreen mode. Currently it is disabling it for window mode.

So it should actually read:

  
if( bClearAuto == true || windowMode != OF_WINDOW || nFrameCount < 3 )  

If you want to recreate the problem we are having you can change it to:

  
if(bClearAuto == true || nFrameCount < 3)  

Then try running your app fullscreen - with auto clearing disabled.
You might not notice it till your drop your frame rate down.

If you do ofSetFramerate(4); in your testApp::setup() you will see the issue.

What happens is in fullscreen you see two different scenes that are alternating back and forth. So half the things you have drawn (over the last few frames) are on one scene (buffer) and the rest are on the other. This causes a flickering effect when running your app at higher framerate.

My guess is that it is a bug with the GLUT implementation on windows and that for some reason we are seeing both the front and back buffers separately.

My understanding is that with openGL we are drawing into the back buffer - then when we are finishing drawing we swap the buffers and display the one we had just drawn into. Somehow in window mode the accumulation works across both buffers - so the back buffer gets updated by the front buffer before we start to draw. But in fullscreen mode they are completely separate and don’t update each other - this results in having two separate accumulations one for odd frames and one for even frames. I guess the trick to fixing this is somehow force the front buffer to draw to the back buffer before we draw into the back buffer.

I am pretty sure that is the problem - maybe people have some ideas about it?

Theo

Okay - I have a fix!
Works for me in game mode / full screen /window mode - both with and without auto clear.

Basically when wanting to do accumulation in fullscreen - we tell openGL to only draw to the front buffer. This is because at the moment openGL was drawing to one then the other - updating the two seperately. There may be a better solution to this issue and it is worth investigating the MESA_SWAP_HACK - which seems related. But my solution seems to work nicely and I don’t see any flickering or tearing of the graphics.

So here it is

in ofAppGlutGlue.h - replace the code between here:

  
	// we do nFrameCount < 3, so that the buffers are cleared at the start of the app  
	// or else we have video memory garbage to draw on to...  

and here:

  
  	// -------------- fps calculation:  

with

  
    int nFramesBeforeDisableClear = 8;  
  
	#ifdef TARGET_WIN32  
		//we need a few more frames of clearing to get rid of the windows taskbar  
  
		if ( bClearAuto == true || nFrameCount < nFramesBeforeDisableClear){  
            glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]);  
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
        }  
  
        //fix for fullscreen accumulation on windows  
        if ( bClearAuto == false && windowMode != OF_WINDOW && nFrameCount >= nFramesBeforeDisableClear){  
            glDrawBuffer(GL_FRONT);  
            glReadBuffer(GL_FRONT);  
        }  
  
	#else  
		//mac and linux does :)  
		if ( bClearAuto == true || nFrameCount < 3){  
            glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]);  
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
        }  
	#endif  
  
    //setup our screen and draw our app as normal  
	ofSetupScreen();  
	OFSAptr->draw();  
  
    #ifdef TARGET_WIN32  
        //fix for fullscreen accumulation on windows  
        if ( bClearAuto == false && windowMode != OF_WINDOW && nFrameCount >= nFramesBeforeDisableClear){  
            //we aren't swapping buffers - BUT glutSwapBuffers calls glflush to say its finished  
            //so we need to too!  
            glFlush();  
        }else{  
            glutSwapBuffers();  
        }  
	#else  
        glutSwapBuffers();  
	#endif  

Here is the fix also for the 00573 release

  
    int nFramesBeforeDisableClear = 8;  
  
	#ifdef TARGET_WIN32  
		//we need a few more frames of clearing to get rid of the windows taskbar  
  
		if ( bClearAuto == true || nFrameCount < nFramesBeforeDisableClear){  
            glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]);  
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
        }  
  
        //fix for fullscreen accumulation on windows  
        if ( bClearAuto == false && windowMode != OF_WINDOW && nFrameCount >= nFramesBeforeDisableClear){  
            glDrawBuffer(GL_FRONT);  
            glReadBuffer(GL_FRONT);  
        }  
  
	#else  
		//mac and linux does :)  
		if ( bClearAuto == true || nFrameCount < 3){  
            glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]);  
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
        }  
	#endif  
  
    //setup our screen and draw our app as normal  
	ofSetupScreen();  
    ofAppEvents.notifyDraw( NULL );  
  
    #ifdef TARGET_WIN32  
        //fix for fullscreen accumulation on windows  
        if ( bClearAuto == false && windowMode != OF_WINDOW && nFrameCount >= nFramesBeforeDisableClear){  
            //we aren't swapping buffers - BUT glutSwapBuffers calls glflush to say its finished  
            //so we need to too!  
            glFlush();  
        }else{  
            glutSwapBuffers();  
        }  
	#else  
        glutSwapBuffers();  
	#endif  

Awesome theo! I’ll give this a try in a bit and report back :slight_smile:

Hey theo,

I tried this today and I have flickering on windows. It seems to work until I go into fullscreen in which is then flickers a bit. Then if I toggle back into window (non fullscreen) it flickers a lot when it hadn’t previously. So toggling between fullscreen and window makes permanent flicker.

I’m using 00573 windows codeblocks version and replaced the code with your 00573 fix.

whoops~ i just encountered with the flicker thing
i just need a kind of drawing board thing. people draw things using the mouse and clear the board until they press A. so i made some changes based on xmlSettingsExample and set ofSetBackgroundAuto(false). when A is pressed, i just use ofBackground(255,255,255); to clear the board. well, it works well on my PC with the video card NVIDIA GeForce 8500GT, both for OF0.05 and 0.06
when i try to run this on another PC with Video card Intel 82845G the flicker things comes. And the exact things is, it flickers with OF0.05. For 0.06 it seems the application just omits the command ofSetBackgroundAuto(false). it just refresh every frame. so when you paint a new stroke the former one is cleared.
so i doubt maybe it’s because the video card. so i update the driver for the video card (now it’s 6.14.10.4020 for someone’s reference) and it works! With OF 0.05 it just works exactly as what i want. you can paint as many strokes as you want. the board is not cleared until A is pressed.
but for OF 0.06 problem still exists. i.e. it seems the application just omits the command ofSetBackgroundAuto(false)
above all, if you encounter this flicker thing, you can change to a better video card, or try to update your video card’s driver~
good luck~