Thanks for the response
Ok, so it looks like the clipping rectangle is the answer for me at this point. Here is the basic program flow, explained slightly differently for anyone who tries this in the future (in a gui using the default primitives). I'm getting perfectly smooth animations this way with zero flicker. Thank you for this library Kurt!
Start with the setup:
Code:
tft.begin();
tft.setRotation(1); //Or whatever
tft.useFrameBuffer(true);
draw_background_elements();
Then, any time a primitive needs to move, re-appear or disappear, a clipping rectangle needs to be calculated to encompass both the OLD and the NEW primitive bounds. This is super easy since all primitives have some start or start/finish points to borrow as the clipping rectangle bounds. I expand the clipping rectangle by a number of pixels for faster movements in case the shape must jump more than a pixel at a time. So my own simplified flow looks like this for any graphic change:
rebuild entire gui with new primitive location > set new clipping rectangle > refresh screen
For a 20x20px white square with smooth motion (does not teleport), it might look like this. BTW, my test indicates it doesn't matter that the clipping rectangle goes off screen.
Code:
void update_square(int position_x, int position_y, int width, int height){
draw_background_elements(); //some other function to draw whatever goes "underneath" the moving square
tft.fillRect(position_x, position_y, width ,height, 0xFFFF); //Draw the new square over the background elements
tft.setClipRect(position_x - 2, position_y - 2, width + 4, height +4);
This method will break down if the clipping rectangle gets large, so I am designing the gui to keep the clipping rectangle minimized. It will still flicker if the entire screen is set as a clipping rectangle. For changing pages in a gui, it's fine. Otherwise, the Teensy 4 is so fast, it can easily just re-calculate the whole gui with no noticeable delay/flicker when using the clipping rectangle. I noticed that if I need to change the entire screen, the clipping rectangle must be resized to the entire screen because it uses the last used clipping rectangle. Anyway, hopefully this is useful for another newbie like myself.