openFrameworks
openFrameworks copied to clipboard
ofClear / ofBackground not working properly
I posted this in the forums and it was suggested that I repost it here as an issue.
I am getting some strange behavior when I turn off automatic clearing (ofSetBackgroundAuto(false);). I am prepared to believe that I’m doing something wrong, but the behavior seems like a bug.
I refined this down to a simple sketch that draws a new circle in a random location in each pass of the draw loop. There is a noticeable flicker as the circle count increases, which was a little surprising. However, the real buggy behavior is I have it configured to clear the screen when any key is typed. To make it really obvious I also change the circle color.
What I expect: the screen will slowly fill in with little circles of one color. When I press a key, the screen will clear and I will get a new collection of circles in the new color.
What I get: the screen doesn’t clear so I can see circles of both colors. However, it is weirder than just not working – it seems to partially clear. Some circles go away. If I clear enough times in rapid succession I can get it completely clear. At a conceptual level, it looks like we are double buffering and the clear only clears one of them (the flicker also seems to line up with multiple buffers that don’t both have the same information).
Here is my test code:
ofColor currentColor;
void changeColor(){
currentColor.set(ofRandom(0,255),ofRandom(0,255), ofRandom(0,255) );
ofBackground(0);
}
//--------------------------------------------------------------
void ofApp::setup(){
ofSetBackgroundAuto(false);
ofBackground(0);
changeColor();
}
//--------------------------------------------------------------
void ofApp::draw(){
ofSetColor(currentColor);
ofFill();
ofDrawCircle(ofRandom(0,ofGetWidth()), ofRandom(0,ofGetHeight()), 3);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
changeColor();
}
I tried turning off double buffering and it helped with the flicker problem and clearing work more often, but not all of the time. Sometimes the previous drawing will remain, and more bizarrely, sometimes a previous drawing that was cleared will return.
I posted in the forum thread about not being able to replicate the flicker or the return of a previous drawing on an m1 macbook air with the test code. I wonder if this is related to the unique displays in the current series of 14" and 16" macbook pros.
I am certainly prepared to believe that this is related to the new displays. However, changing the refresh rate and resolution did not alleviate the problem, nor did using an external display.
This has double buffering enabled. I set this to just white dots since the colors can make it harder to see the flicker. (the screen recording does accentuate the flicker) https://user-images.githubusercontent.com/6847199/186438307-ac41fb97-9875-4744-82ca-f16791e62ac5.mov
This is the code posted above. We should never see two different colors on screen. https://user-images.githubusercontent.com/6847199/186438398-e4b6790c-9f05-4dc2-a308-f00af8cb0ab7.mov
This is the same but with double buffering turned off. https://user-images.githubusercontent.com/6847199/186439357-3654986e-a3f8-4afc-aafc-8551fcc547c9.mov
Hey these videos are a great help! And verifying on external display is helpful too I think. It kinda looks like the same chunk of memory (sometimes) isn't being used as the base for the current drawing.
I confirm this buggy behaviour with 16" M2 pro, and what is "funny" is that running 2 instances of the app diminishes the flickering for a couple seconds (stumbled on that while testing debug vs release). moving to/from external screen also sometimes stabilizes things, as does resizing.
considering the generalized issues around ofSetBackgroundAuto()
, perhaps simply deprecate it and provide a good FBO example that (1) is a motivating learning step for (easy) FBO usage as many people want to accumulate drawings and (2) is a better way to do it anyway.
instead of deprecating it, what if we just use an fbo internally to help make ofSetBackgroundAuto() work as expected? It always has felt sort of shaky and it feels like the kind of thing that beginners just want to have available since it's an important part of certain graphics techniques in processing, etc.
For anyone else who might be running into this issue, here's an example of how to switch from using ofSetBackgroundAuto
to using a FBO so you don't have to do as much searching as I did. 😉 https://github.com/ggilder/patternLoops/commit/cca05baf907d88d09ca18650b60150e547538ab0