First of all I want to thank Sam and Martin for their help with my
"fullscreen" problem (didnât want to post a âthank-you-only-messageâ,
for not making the traffic to much / big ?)
Anes - thank you, too, but it seems there is no âSDL_VIDEOâ as a setting
for SDL_SetVideoMode with my version
Again there is a question I have: âIs there a special way to calculate
the time an update-rectâ needs (without reffering to the architecture of
the hardwareâŠ)
My problem is the following. Lets say I draw a Line on a SDL_Surface
wich goes from (0,0) to (100,100). I could update the whole rect like
graph-1 shows, or i could update it in 2 (graph 2) and so on up to
100x100 (=10.000) seperated rects (updating every pixel as a rect of 1x1
pixel), but i guess, it would be usesless updating 100rects, cos I think
it would take more time, but the use of 2 or 4 updaterects could be
optimizing performance here, so i need this calculation to find out,
where the âcritical pointâ might be.
Hope this isnât a stupid question
Greetings,
Sascha
±---------------------+ ±---------------------+
|\ | |\ | |
| \ | | \ | |
| \ 1 | | \ | |
| \ | | 1 \ | 2 |
| \ | | \ | |
| \ | |----------X-----------|
| \ | | | \ |
| \ | | | \ |
| \ | | | \ |
| \ | | 4 | 3 \ |
| \ | | | \ |
±---------------------+ ±---------------------+
(graph-01 100x100 update) (graph-02 2x50x50 update)
(2 and 4 donât need an update)±---------------------+
|\ | o | o | o | o | o |
|âX-------±â±--±â|
| o| \ | o | o | o | o |
|------Xâ±â±--±â|
| o| o | \ | o | o | o |
|----------Xâ±â±--|
| o| o | o | \ | o | o |
|--------------Xâ±â|
| o| o | o | o | \ | o |
|------------------Xâ|
| o| o | o | o | o | \ |
±---------------------+
(graph-01 10x10x10 update)
(areas marked with o donât need an update)
Generally, of course, you shouldnât be updating for 1 line unless you
really need to.
We have a âdirty rectanglesâ scheme. Currently itâs a fairly complex
span-line scheme, but I recently tried something extremely simple that
seemed to work just as well, and itâs kinda similar to your 10x10 grid.
The idea is to make a mxn grid of simple chars, choosing the grid size is a
trade off, as you describe, between wasted updates and lots of little rects.
Whenever something needs updating, just mark a â1â in any grid square touched.
Then âperiodicallyâ (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid
I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as itâs still
working)
Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object hierarchy.
The only catch is SDL will toss rather than clip any update rect which is
partially out of the surface, so some care is needed with the right column
and bottom row, if the grid isnât a perfect multiple of the screen size.
Anyway, thatâs one approach for a really simple scheme that does
generically and automatically what you seem to be after.
Generally, of course, you shouldnât be updating for 1 line unless you
really need to.
We have a âdirty rectanglesâ scheme. Currently itâs a fairly complex
span-line scheme, but I recently tried something extremely simple that
seemed to work just as well, and itâs kinda similar to your 10x10 grid.
The idea is to make a mxn grid of simple chars, choosing the grid size is
a
trade off, as you describe, between wasted updates and lots of little
rects.
I experimented with a scheme like you describe years ago
(Hercules grafics, at that time). At that time, with a 386SX
20 MHz CPU, i achieved optimum performance at 32x32
pixel, as far as i recall. (Blitting from memory to screen,
hand-optimized assembler blitting routines) (with loads and
loads of special cases for the borders)
Making the rectangles smaller resulted in management
overhead, making the whole thing slower and more memory-
consuming.
What optimum do you achieve with todays machines?
Whenever something needs updating, just mark a â1â in any grid square
touched.
Then âperiodicallyâ (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid
I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as itâs still
working)
Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object
hierarchy.
I didnât understand that one. Could you explain some more?
Dipl.Inform. Dirk-Ulrich Heise @Dirk-Ulrich_Heise
dheise at debitel.netVon: âMannyâ
First of all I want to thank Sam and Martin for their help with my
"fullscreen" problem (didnât want to post a âthank-you-only-messageâ,
for not making the traffic to much / big ?)
Anes - thank you, too, but it seems there is no âSDL_VIDEOâ as a setting
for SDL_SetVideoMode with my version
Ups âŠ
Sorry, i meant something like
screen=SDL_SetVideoMode(width,height,depth,SDL_HWSURFACE|SDL_FULLSCREEN);
My problem is the following. Lets say I draw a Line on a SDL_Surface
wich goes from (0,0) to (100,100). I could update the whole rect like
graph-1 shows, or i could update it in 2 (graph 2) and so on up to
100x100 (=10.000) seperated rects [âŠ]
This is a very artificial problem; you will rarely update the screen after
having drawn a single line. For a general line-vector graphics application,
Iâd use a simple bounding-box scheme or a fixed grid of dirty rectangles,
with coalescing to bigger rectangles as needed.
If this is important, do a small runtime test when initialising your game
to select the best method or rectangle size
I experimented with a scheme like you describe years ago
(Hercules grafics, at that time). At that time, with a 386SX
20 MHz CPU, i achieved optimum performance at 32x32
pixel, as far as i recall. (Blitting from memory to screen,
hand-optimized assembler blitting routines) (with loads and
loads of special cases for the borders)
Making the rectangles smaller resulted in management
overhead, making the whole thing slower and more memory-
consuming.
What optimum do you achieve with todays machines?
As I mentioned, weâre actually using a span-line based system. Itâs the
same basic idea in that it generates a list of dirty rectangles. I only
spent an evening experimenting with the simpler method, but the more I
think about it, the more I think the span-line scheme isnât giving any real
benefits for the added complexity (it gets a tighter fit on update regions,
but that doesnât seem important). I also ended up at 32x32, but I havenât
done any proper measurements yet. Growing out the rectangles takes away a
lot of the concern about small rectangles. A grid of 32x32 rectangles on a
1024x768 screen is only 32x24 or 768 bytes.
Whenever something needs updating, just mark a â1â in any grid square
touched.
Then âperiodicallyâ (for example, if the time since the last update is
greater than some threshold), flush out the dirty rects and clear the grid
I had also added a simple scheme to grow the update rects as far as
possible (I just grew right then down then repeat as long as itâs still
working)
Our scheme is somewhat complicated by not drawing to the backbuffer until
the dirty regions are flushed (avoids any duplicate or unnecessary
drawing). We do this by testing each update rect against an object
hierarchy.
I didnât understand that one. Could you explain some more?
Our loop is basically:
Process all pending events (stops early if itâs taking to long)
Get the current time, update & process timers
(steps 1 & 2 generally create dirty regions)
(2 1/2: back to 1 if very little time has passed, but I think Iâll take
this out)
Redraw dirty regions to back buffer
Update drawn regions to front buffer
We have a âGame Treeâ, sort of a simple 2d scene graph. When something
needs updating it just marks that part of the screen as dirty. If more
than one thing marks the same region, the area is only drawn once. When
the dirty areas are flushed, each rectangle is tested against the
GameTree. Itâs hierarchical, so if an object is outside the rectangle, so
are all of itâs children. Objects that overlap the dirty region are
clipped to the region and drawn.
We also had an occlusion test that wouldnât draw an object if something was
covering it up, but that took just as long as doing the extra drawing.
Process all pending events (stops early if itâs taking to long)
Get the current time, update & process timers
(steps 1 & 2 generally create dirty regions)
(2 1/2: back to 1 if very little time has passed, but I think Iâll take
this out)
Redraw dirty regions to back buffer
Update drawn regions to front buffer
Thanks, now i got it.
Itâs really funny that you say the new approach is simpler.
At the time i wrote it (and iâm about to revive that project,
it fell into coma 5 years ago, it was written in PASCAL, and now
iâm rewriting it in Python), i wondered whether a span-line
system would be better So this encourages me to keep
the old logic i already had. Thanks!
BTW, itâs not a game but a sort of grafical front end
to a database, where objects move randomly towards
their neighbours. Made for nice self-organizing data
associations.
Dipl.Inform. Dirk-Ulrich Heise @Dirk-Ulrich_Heise
dheise at debitel.netVon: âMannyâ