Dirty Rectangles
Ludwig Auer

Hi!
I'm new in Allegro, an I made my first steps with al small Program, which allows the user to move an image by the mouse.

Ok, I tried Doublebuffering! Is ist right, that this methode isn't very fast. By playing the Demogame with Doublebuffering I got about 60 fps - with this 'Dirty Rectangle' Variante, I got ca. 500.

The Screenresolution was 640x480...

Now I'm Searching for a simple implementation of Dirty Rectangle. Can sb. help me? It would be kind of you.

THX
lnx_root:)

Jouser

To use dirty rectangles in your small program instead of double buffering:

1. Simply save the part of the screen that your box is going to be blitted to (using blit())

2. Blit() your image box or whatever you have to its destination on screen.

3. Calculate the new position from keyboard input or whatever...

4. Blit() the original part of the screen from step 1 back to its place.

5. Start over at step 1 with a new (x,y)

miran

Actually DRS is a bit different although Jouser's method works too:

1. make a buffer you draw to just like with normal double buffering
2. draw to this buffer like if you had double buffering and always mark the rectangle that was changed by the drawing function dirty (i.e. add it to a dirty list which can be a linked list or an STL vector or something like that)
3. when you blit the buffer to the physical screen don't blit all of it, only the rectangles that are dirty (i.e. go through the dirty list, blit every rectangle from the buffer to the screen and remove the rectangle from the list)

Ludwig Auer

Thank you for your reply, but I don't really understand.:-/??? Like I said: I'm new to coding with C and allegro... Perhaps you have an old (small) code which includes Dirty Rectangles.
Sorry, if my questions sound stupid, i'm not good in my English-classes either.:-[

miran

There's a DRS tutorial (along with a bunch of other tutorials) here: [url http://agdn.cjb.net]

Steve Terry

:P Sorry that AGDN tutorial only confused me further when trying to learn all about DRS. The tutorial was wrong IIRC because it used a sort of DRS, but still completely double buffered the screen... but it could also help you understand the problem. My way was sort of both Mirans and the other guys way (sorry about that).

1. Create buffer exactly as you would using a double buffer.
2. Create a seperate buffer the size of teh image you wish to make a dirty rectangle out of that will hold the background information of the buffer so when it moves you can erase where it was.
3. Copy the buffer into your seperate buffer where the sprite will be.
4. Blit your sprite to the buffer
5. Add a dirty rectangle to the list (simply a linked list containing x, y, w, and h of your sprite)
6. You may wish to make the DRS "smarter" by combining rectangles or deleting those that exist inside another rectangle.
7. Blit your dirty list to the screen from the buffer.
8. Blit your seperate buffer to the buffer to erase what you just drew
9. Move sprite
10. Repeat 2 - 10 until program exits.

Sounds complicated but generally isn't. Good Luck.

Surt
Ludwig Auer said:

Ok, I tried Doublebuffering! Is ist right, that this methode isn't very fast. By playing the Demogame with Doublebuffering I got about 60 fps - with this 'Dirty Rectangle' Variante, I got ca. 500

The 60 fps you got on double buffering may well be due to v-syncing on a 60 Hz video mode, if that's the case, then turning off v-sync should allow a higher frame rate.

Steve Terry said:

6. You may wish to make the DRS "smarter" by combining rectangles or deleting those that exist inside another rectangle.

Has anyone implemented an exclusive dirty rects. What kind of overhead does the spliting/merging of rects incur?

miran
Carl Olsson said:

What kind of overhead does the spliting/merging of rects incur?

It depends on what you're doing. If you have lots of rects and many overlap you can save quite a bit of time but if overlapping rects are few and far between then most of the time the code will just iterate through the list for no reason doing a lot of unnecessary checking ultimately proving to be more trouble than it's worth. The only way to answer the question is to implement the algo and make some tests...

With all that in mind it has to be said that with the processing power of todays CPUs the performance lost or gained will most probably be minimal...

Evert
Quote:

Has anyone implemented an exclusive dirty rects. What kind of overhead does the spliting/merging of rects incur?

I have a dirty rectangle system that merges aligned rectangles or rectangles that are fully contained within each other, but not the general case of overlapping rectangles.
It offers a measurable speed boost (but I don't remember how large) in the tile-based games I use it for, since the overhead of blitting a number of tiles seperately is larger than the overhead of blitting one strip of tiles at a time.

I based most of my DRS system on the Allegro demo game, btw. A bit complicated to learn from if you're really a beginner, but it might be worthwhile to look into it nevertheless.

Tobias Dammers

Before implementing a dr algo, be sure you are making the right kind of game for it. As soon as you have scrolling backgrounds, parallax effects, or do 3d, or for some other reason update most part of the screen in every frame, double-buffering is the way to go (or check if triple-buffering is an option).
If you only need to update small areas though, dirty rectangles is for you.
Anyway, 60 fps is about as fast as you need; the eye won't really notice the difference anyway. In fact, in a 60Hz screen mode, the image quality will suffer from any update rate above 60 Hz, because the image will be updated mid-frame.
/// EDIT ///
Re-reading the above posts, it seems that there are two opinions on what DR actually means.

Method 1:
- Create a back buffer like double buffering
- For each object that moves, mark source and dest rects as dirty
- Redraw back buffer (could restrict this roughly to dirty rects, ie redraw only objects that intersect with dirty rects)
- Blit dirty rectangles from backbuffer to screen

Method 2:
- For each object, create a backbuffer the size of the object
- Before drawing the object, save the previous screen contents to the objects backbuffer
- When moving, restore screen content from backbuffer, then save from new position, then draw.

While method 2 is certainly faster and needs less memory, it has the big disadvantage that it only works correctly if either first all sprites restore, then all sprites draw in the exact same order (but that can easily cause flicker), or if no two sprites overlap. This might be feasible for some kinds of games (tile-based come to mind), but not for others (side-scrollers).
I would go for method 1 even if not necessary, because if you do your drawing somewhat cleverly, there shouldn't be too much speed difference. And you can do whatver you want with your sprites.

Ludwig Auer

>>The 60 fps you got on double buffering may well >>be due to v-syncing on a 60 Hz video mode, if >>that's the case, then turning off v-sync should >>allow a higher frame rate.

Maybe you're right! I often get these 60fps, also in BlitBasic under Windows. How can I turn off this v-sync?

I guess, that this DR stuff is a bit to complicated for me, right now. Althogh Thank you for your support. I will soon post my variante of double buffering... A thing is confusing me: My Code is bucking a lot, but the demo game (in double buffering mode) isn't. Perhaps I make a stupid mistake?!?!?

bye
lnx_root

Evert
Quote:

How can I turn off this v-sync?

Toggle the button on the lower right hand corner of your monitor ;)

Ok, bad joke - you can't disable the retrace, but you can choose not to wait for the sync, however this is generally a bad idea IMO. Image quality will suffer and you will/may get flickering. (See Tobias's post above)

Surt
Ludwig Auer said:

How can I turn off this v-sync?

If you are using v-sync (vertical refresh syncronisation), then you should be calling the vsync function just before you blit the contents of the buffer to the screen. Just comment it out and see how your frame rate changes.

Evert said:

...you can choose not to wait for the sync, however this is generally a bad idea IMO. Image quality will suffer and you will/may get flickering.

Without v-sync the screen may "tear", with the monitor updating before the frame is fully draw, leaving part of the old frame on screen. (This may still happen with v-sync if drawing takes longer than a refresh cycle.) This will look nasty if the screen image changes a great deal each frame. For example, with fast moving sprites, the top half of the sprite may draw at the edge of the screen with the bottom half mid screen.
How ever if the screen dosn't change radically each frame, the screen tearing can be quite acceptable, even unnoticable.
Most commercial games come set to use v-sync as default, but give you the option to turn it off, to score that few extra fps.

Thread #233953. Printed from Allegro.cc