Darn it! Who left the Rectangles in the sink without washing them?
Also known as RefreshRectangles
Dirty Rectangles are used extensively in computer/video game programming for fast, flicker-free double-buffer graphic updating.
It's been a while since I've looked at the internals, but the following will give you the gist of it:
Ideally, the bounding rectangles of the items on screen which need to be drawn are accumulated in a list. Intersecting rectangles are unioned, the union stored in the list, and the two original rectangles thrown away (other optimizations are possible.)
When it comes time to draw, we can use the list of dirty rectangles to limit what actually gets blitted (copied.) We blit the background thru the rectangles, and then draw whatever needs to get drawn - whatever intersects any dirty rectangle.
We save that list for the next pass because we will union that entire list with the new list of things to be drawn so that we erase everything properly. We also use that combined list to blit thru onto the screen. We then throw away the combined list, and save the most recent Dirty Rectangle list for the next pass.
Obviously, Dirty Rectangles are useful for any graphical system where many small objects change over time. This is true for game sprites as well as user interfaces. It is inefficient for, say, full-screen animation.
Again, I've put this together from memory, so it might not be completely orthogonal. A fully working C version of a Dirty Rectangle manager can be found in
Tricks of the Mac Game Programming Gurus
ISBN 1568301839 in the chapter Mick Foley wrote about advanced graphics.
-- Jon Benton
Saving the list of Dirty Rectangles between frames and doesn't work because you miss painting the old positions of sprites that had not moved last frame. It's better to record which rectangles need to be redrawn as objects move. For example, when moving a sprite:
class Sprite { Dimension size; int x, y; ... void move( int dx, int dy ) { invalidateBounds(); x += dx; y += dy; invalidateBounds(); } void invalidateBounds() { Display.invalidateRect( new Rectangle( size, x, y ) ); } }
Also see GraphicsPatterns, DeferredUpdate.