Problems in Full Screen

Hello!
Following some tutorials i made a program that “puts” an image
at the background, and then a new image in the foreground. Wich you can move
it with
the arrow keys. The program works just fine when i use Windowed screen.

But if i use FULL SCREEN, the screen starts flikering as hell, and the image
looks darker… and the screen REALLY.
I thought it was about my very old monitor, so i tried the same compiled
binary in
my fathers PC, that has an almost new 19’ phillips monitor. But it did the
same.
Also, i noticed in my fathers machine (new monitor), that it shows the
background image, and the DESKTOP at the same time, like if there is a loop
that SHOWS the background image, and then shows the desktop. Very strange.

Here is how i did initialized the video mode:

(screen is a SDL_Surface *screen;)

screen =
SDL_SetVideMode(800,600,16,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);

*I noticed that if i have my desktop in 24 bits, and the program is 16 bit
it works bad. So i used 16bpp desktop in the PC’s i tested the program.
and as i said, the program works perfectly when i use a windowed mode.

Can you tell me what could be the possible problem? Im sure that its not an
sdl problem, and its just the way im “showing” the images. Maybe the
background image. I can’t guess it.

Thanks in advantage!!

PD: Sorry if i didn’t explain the problem that well. Im very new to SDL.

----- Here is the code -----

#include
#include <stdlib.h>
#include "SDL/SDL.h"
using namespace std;

SDL_Surface *back;
SDL_Surface *screen;
SDL_Surface *image;

int ypos=0,xpos=0;

int InitImages() {
back = SDL_LoadBMP(“bg.bmp”);
image = SDL_LoadBMP(“image.bmp”);
return 0;
}

void DrawIMG(SDL_Surface *img, int x, int y) {
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}

void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2) {
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
}

void DrawBG() {
DrawIMG(back,0,0);
}

void DrawScene() {
DrawIMG(back,xpos-2,ypos-2,132,132,xpos-2,ypos-2);
DrawIMG(image,xpos,ypos);

 SDL_Flip(screen);
 }

int main(int argc, char *argv[])
{
Uint8 *keys;

  if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
     cout <<"Error (1): al cargar Video / Sonido:

"<<SDL_GetError()<<endl;
return 1;
}

  atexit(SDL_Quit);

  screen =

SDL_SetVideoMode(800,600,16,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);

  if (screen == NULL) {
     cout << "Error (2): No se puede inicializar la pantalla: " <<

SDL_GetError() <<endl;
return 1;
}

  InitImages();
  DrawBG();

  int done=0;

  while ( done == 0 ) {

        SDL_Event salir;

        while (SDL_PollEvent(&salir)) {
              if (salir.type == SDL_QUIT) { done = 1; }

              if (salir.type == SDL_KEYDOWN) {
                 if (salir.key.keysym.sym == SDLK_ESCAPE) { done = 1;}
              }
        }



  keys = SDL_GetKeyState(NULL);

       if (keys[SDLK_UP]) { ypos-=1; }
       if (keys[SDLK_DOWN]) { ypos+=1; }
       if (keys[SDLK_LEFT]) { xpos-=1; }
       if (keys[SDLK_RIGHT]) { xpos+=1; }

  DrawScene();

  }

  return 0;

}

                       Eduardo Garcia Rajo (h)------------------------------------------------------------------

Visite: http://www.solucion-digital.com.ar
SOLUCION DIGITAL
Redes - Software - Servicios

[…]

Can you tell me what could be the possible problem? Im sure that
its not an sdl problem, and its just the way im “showing” the
images. Maybe the background image. I can’t guess it.

When you use double buffering, there are basically two possible ways
it can be arranged:

1) True page flipping, with two hardware surfaces that
   are swapped when you SDL_Flip(). You render into one
   while the other one is being displayed.

2) "Fake" page flipping, with one hardware surface for
   the display, and one software surface for rendering.
   When you SDL_Flip(), the software back surface (or
   "shadow surface") is copied into the front hardware
   surface.

When you’re deailing with full screen scrollers and the like, where
the whole screen is repainted every frame, the difference is
irrelevant. Both arrangements will work fine.

However, as soon as you start doing partial updates, it makes a big
difference!

If you’re on a “case 2” display, there’s no problem; each flip will
just make sure the current version of your screen becomes visible.
You get to keep the back surface as a base for further rendering.

Now, if you do this on a “case 1” display, this no longer works. When
you flip, the page you just rendered into is swapped with the one
that was displayed. Of course, you still get your new frame
displayed, but your new back buffer is the previous frame you
flipped into display. You now have to perform updates for two frames
to catch up; one to get back to the state of the frame you just
flipped into display, and one to turn that into the next frame.

In short, if you set up a double buffered screen and get a hardware
surface, you need to do all updates twice per frame, or deal with the
"old back buffer" in some other way.

More specifically, you need to blit the background image twice, with
an SDL_Flip() in between, and then you need to do something about the
sprite removal.

The safe way (works with both styles of double buffering) is to
remember all sprite “dirty rects” for the last two frames. Before you
blit the sprites for a new frame, restore all dirty rects from both
buffers. Then blit your sprites, overwriting the oldest set of dirty
rects.

A more efficient way is to restore using only the older set of dirty
rects. (The newer one shouldn’t be relevant until the next frame,
since it describes the page that’s currently being displayed.)
However, do keep in mind that this breaks down unless you really
have a true hardware pageflipping (“case 1”) display.

Don’t start whining about modern video subsystems being a PITA just
yet, though. There’s a third, hybrid method that covers both cases
without much extra cost: Instead of just restoring every single dirty
rect in the two sets, make a first pass where you merge overlapping
rects, to avoid updating some areas multiple times.

In many cases when dealing with sprites, and you don’t have tons of
them (ie not too many overlapping sprites), you can just consider the
last two positions of each sprite, and create a dirty rect that
covers both positions. As long as sprites move a reasonable speeds,
this means the dirty rect is only a few pixels bigger than the
sprite. Just in case, you could calculate the area of the resulting
dirty rect, and if it’s more than twice the area of the sprite’s
bounding rect, keep the separate dirty rects instead.

In Project Spitfire/DOS (double buffered h/w scrolling with an extra
buffer for scheduled background rendering), I used a variant of the
"use only the older diry rects set" method. I didn’t use dirty rects
at all, but rather kept a local tiled map for each buffer. This map
would first be filed with the index of an illegal (non-drawing)
background tile. When rendering sprites into the buffer, I would copy
tile indices from the level map into the buffer for each tile that
the sprite would overdraw. To remove the sprites, I just scanned the
"dirty map" and repainted any valid tiles found in it. Very simple
and low cost way of avoiding overdraw when removing sprites.

Of course, there’s always the fool proof, totally portable, but not
too fast brute force approach: Always repaint the whole screen
whether you really need to or not.

If you’re scrolling the whole screen, you normally need to do this
anyway. For something like a Break-Out clone or something more like a
normal application (buttons, sliders and stuff), it would be a huge
waste of resources, and it would multiply your minimum system
requirements by an insane factor for no real reason.

So, you need to be aware of both methods, and pick the one that makes
most sense for each application.

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Friday 23 May 2003 06.10, eDU! wrote:

I wasnt the original poster, but anyway thanks for the good explanation!
I would also vote to make it a FAQ or html page linked into www.libsdl.org.

I remember some other posts (by Sam, etc.) in the past about this and related topics,
maybe you could merge them together (sorry, I am going on holiday now, so I cant help,
but will if necessary/possible when I am back),

thx,
Thomas> ----- Original Message -----

From: david@olofson.net (David Olofson)
To:
Sent: Friday, May 23, 2003 12:53 PM
Subject: Re: [SDL] Problems in Full Screen

On Friday 23 May 2003 06.10, eDU! wrote:
[…]

Can you tell me what could be the possible problem? Im sure that
its not an sdl problem, and its just the way im “showing” the
images. Maybe the background image. I can’t guess it.

When you use double buffering, there are basically two possible ways
it can be arranged:

  1. True page flipping, with two hardware surfaces that
    are swapped when you SDL_Flip(). You render into one
    while the other one is being displayed.

  2. “Fake” page flipping, with one hardware surface for
    the display, and one software surface for rendering.
    When you SDL_Flip(), the software back surface (or
    "shadow surface") is copied into the front hardware
    surface.

When you’re deailing with full screen scrollers and the like, where
the whole screen is repainted every frame, the difference is
irrelevant. Both arrangements will work fine.

However, as soon as you start doing partial updates, it makes a big
difference!

If you’re on a “case 2” display, there’s no problem; each flip will
just make sure the current version of your screen becomes visible.
You get to keep the back surface as a base for further rendering.

Now, if you do this on a “case 1” display, this no longer works. When
you flip, the page you just rendered into is swapped with the one
that was displayed. Of course, you still get your new frame
displayed, but your new back buffer is the previous frame you
flipped into display. You now have to perform updates for two frames
to catch up; one to get back to the state of the frame you just
flipped into display, and one to turn that into the next frame.

In short, if you set up a double buffered screen and get a hardware
surface, you need to do all updates twice per frame, or deal with the
"old back buffer" in some other way.

More specifically, you need to blit the background image twice, with
an SDL_Flip() in between, and then you need to do something about the
sprite removal.

The safe way (works with both styles of double buffering) is to
remember all sprite “dirty rects” for the last two frames. Before you
blit the sprites for a new frame, restore all dirty rects from both
buffers. Then blit your sprites, overwriting the oldest set of dirty
rects.

A more efficient way is to restore using only the older set of dirty
rects. (The newer one shouldn’t be relevant until the next frame,
since it describes the page that’s currently being displayed.)
However, do keep in mind that this breaks down unless you really
have a true hardware pageflipping (“case 1”) display.

Don’t start whining about modern video subsystems being a PITA just
yet, though. There’s a third, hybrid method that covers both cases
without much extra cost: Instead of just restoring every single dirty
rect in the two sets, make a first pass where you merge overlapping
rects, to avoid updating some areas multiple times.

In many cases when dealing with sprites, and you don’t have tons of
them (ie not too many overlapping sprites), you can just consider the
last two positions of each sprite, and create a dirty rect that
covers both positions. As long as sprites move a reasonable speeds,
this means the dirty rect is only a few pixels bigger than the
sprite. Just in case, you could calculate the area of the resulting
dirty rect, and if it’s more than twice the area of the sprite’s
bounding rect, keep the separate dirty rects instead.

In Project Spitfire/DOS (double buffered h/w scrolling with an extra
buffer for scheduled background rendering), I used a variant of the
"use only the older diry rects set" method. I didn’t use dirty rects
at all, but rather kept a local tiled map for each buffer. This map
would first be filed with the index of an illegal (non-drawing)
background tile. When rendering sprites into the buffer, I would copy
tile indices from the level map into the buffer for each tile that
the sprite would overdraw. To remove the sprites, I just scanned the
"dirty map" and repainted any valid tiles found in it. Very simple
and low cost way of avoiding overdraw when removing sprites.

Of course, there’s always the fool proof, totally portable, but not
too fast brute force approach: Always repaint the whole screen
whether you really need to or not.

If you’re scrolling the whole screen, you normally need to do this
anyway. For something like a Break-Out clone or something more like a
normal application (buttons, sliders and stuff), it would be a huge
waste of resources, and it would multiply your minimum system
requirements by an insane factor for no real reason.

So, you need to be aware of both methods, and pick the one that makes
most sense for each application.

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

file://David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Well, I’ll have a look at it.

If anything in my explanation is unclear, please ask, and I’ll try to
rephrase or something. It would be nice if we could avoid an FAQ
without creating a bunch of others. :wink:

As for examples, would these do?

1) Simple, safe and dog slow: Repaint the whole screen.

2) Smart: Keep two sets of dirty rects. Remove sprites
   using both sets, brute force.

3) Smarter and faster: Use only one set of dirty rects
   to remove sprites. Keep two sets and use the older
   one if the screen is hardware surface double buffered.
   Use only one set if the screen is single buffered,
   or uses a software back surface.

4) Tiled, fast and simple: "Paint" dirty areas in tile
   maps that are then used to remove sprites without
   overdraw.

Not sure if I’ll hack these as modes into the same program, or as
separate examples. I guess separate examples would be easier to read
and less confusing…

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Friday 23 May 2003 14.10, Thomas Eder wrote:

I wasnt the original poster, but anyway thanks for the good
explanation! I would also vote to make it a FAQ or html page linked
into www.libsdl.org.

I remember some other posts (by Sam, etc.) in the past about this
and related topics, maybe you could merge them together (sorry, I
am going on holiday now, so I cant help, but will if
necessary/possible when I am back),

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

Please do it. You have much insight into hw background of graphics
rendering, which is a notorically not so well understood topic. It’s
true you (and Sam and a couple of others) have probably already said
most of the important stuff on this list, but it’s hopelessly scattered
among numerous posts. It’s hard to find the correct one which leads to
same questions again and again. Having one authoritative reference for
rendering various types of games in various hardware environments
(preferably with simple compilable code examples) would be a real
service to the community (and could cut down volume of this list by a
quarter, at least :wink: . I for one would be very grateful if you
contributed your insights.

latimeriusOn Fri, May 23, 2003 at 12:53:50PM +0200, David Olofson wrote:

Me too. This things are very useful and should be organized in some way.On Fri, May 23, 2003 at 04:43:18PM +0200, Latimerius wrote:

On Fri, May 23, 2003 at 12:53:50PM +0200, David Olofson wrote:

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

Please do it. You have much insight into hw background of graphics
rendering, which is a notorically not so well understood topic. It’s
true you (and Sam and a couple of others) have probably already said
most of the important stuff on this list, but it’s hopelessly scattered
among numerous posts. It’s hard to find the correct one which leads to
same questions again and again. Having one authoritative reference for
rendering various types of games in various hardware environments
(preferably with simple compilable code examples) would be a real
service to the community (and could cut down volume of this list by a
quarter, at least :wink: . I for one would be very grateful if you
contributed your insights.


Ivan Stankovic, @Ivan_Stankovic

Hello Ivan,

Friday, May 23, 2003, 6:29:35 PM, you wrote:

IS> On Fri, May 23, 2003 at 04:43:18PM +0200, Latimerius wrote:>> On Fri, May 23, 2003 at 12:53:50PM +0200, David Olofson wrote:

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

Please do it. You have much insight into hw background of graphics
rendering, which is a notorically not so well understood topic. It’s
true you (and Sam and a couple of others) have probably already said
most of the important stuff on this list, but it’s hopelessly scattered
among numerous posts. It’s hard to find the correct one which leads to
same questions again and again. Having one authoritative reference for
rendering various types of games in various hardware environments
(preferably with simple compilable code examples) would be a real
service to the community (and could cut down volume of this list by a
quarter, at least :wink: . I for one would be very grateful if you
contributed your insights.

IS> Me too. This things are very useful and should be organized in some way.

Please explain about updating only the regions which should be
updated instead of entire screen.


Lynx,
http://foo.lynx.lv mailto:@Anatoly_R

[…]

Please explain about updating only the regions which should be
updated instead of entire screen.

Yes, that’s the tricky part, really… I’m going to try to explain
each one of the approaches I mentioned, around working example code.

First, though, I have to make something very similar work in Kobo
Deluxe, so everyone can finally us OpenGL without flickering. :slight_smile:

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Friday 23 May 2003 17.58, Anatoly R. wrote:

Hello David,

Friday, May 23, 2003, 7:26:59 PM, you wrote:

DO> On Friday 23 May 2003 17.58, Anatoly R. wrote:
DO> […]

Please explain about updating only the regions which should be
updated instead of entire screen.

DO> Yes, that’s the tricky part, really… I’m going to try to explain
DO> each one of the approaches I mentioned, around working example code.

DO> First, though, I have to make something very similar work in Kobo
DO> Deluxe, so everyone can finally us OpenGL without flickering. :slight_smile:

No GL please :slight_smile: I’m still interested in software-only solutions.
Oldskool groove.–
Lynx,
http://foo.lynx.lv mailto:@Anatoly_R

Well, unless you’re going to hack Kobo Deluxe, don’t worry! :slight_smile:

What I meant was just that Kobo Deluxe needs smart partial updates,
like the ones discussed, specifically for OpenGL. That’s the only
time Kobo may have to deal with true page flipping. Since there’s
quite a bit of alpha blending, I don’t want to render directly into a
h/w display surface, even when using h/w pageflipping. The solution
is to render into a third software buffer, blit updated parts into
the h/w back buffer and then flip. However, this is not possible with
OpenGL, so I need a different solution specifically for that.

(I could actually do it the same way as usual with glSDL, but then
it would all be software rendering into a fullscreen procedural
texture. Not much point in using OpenGL then, as Kobo doesn’t need
OpenGL to scale the screen for it, unlike emulators.)

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Friday 23 May 2003 18.52, Anatoly R. wrote:

Hello David,

Friday, May 23, 2003, 7:26:59 PM, you wrote:

DO> On Friday 23 May 2003 17.58, Anatoly R. wrote:
DO> […]

Please explain about updating only the regions which should be
updated instead of entire screen.

DO> Yes, that’s the tricky part, really… I’m going to try to
explain DO> each one of the approaches I mentioned, around working
example code.

DO> First, though, I have to make something very similar work in
Kobo DO> Deluxe, so everyone can finally us OpenGL without
flickering. :slight_smile:

No GL please :slight_smile: I’m still interested in software-only solutions.
Oldskool groove.

David THANKS U very much for your reply!

I will try the metoths u told, and thanks again for your ideas :slight_smile:

                       Eduardo Garcia Rajo (h)------------------------------------------------------------------

Visite: http://www.solucion-digital.com.ar
SOLUCION DIGITAL
Redes - Software - Servicios

----- Original Message -----
From: david@olofson.net (David Olofson)
To:
Sent: Friday, May 23, 2003 7:53 AM
Subject: Re: [SDL] Problems in Full Screen

On Friday 23 May 2003 06.10, eDU! wrote:
[…]

Can you tell me what could be the possible problem? Im sure that
its not an sdl problem, and its just the way im “showing” the
images. Maybe the background image. I can’t guess it.

When you use double buffering, there are basically two possible ways
it can be arranged:

  1. True page flipping, with two hardware surfaces that
    are swapped when you SDL_Flip(). You render into one
    while the other one is being displayed.

  2. “Fake” page flipping, with one hardware surface for
    the display, and one software surface for rendering.
    When you SDL_Flip(), the software back surface (or
    "shadow surface") is copied into the front hardware
    surface.

When you’re deailing with full screen scrollers and the like, where
the whole screen is repainted every frame, the difference is
irrelevant. Both arrangements will work fine.

However, as soon as you start doing partial updates, it makes a big
difference!

If you’re on a “case 2” display, there’s no problem; each flip will
just make sure the current version of your screen becomes visible.
You get to keep the back surface as a base for further rendering.

Now, if you do this on a “case 1” display, this no longer works. When
you flip, the page you just rendered into is swapped with the one
that was displayed. Of course, you still get your new frame
displayed, but your new back buffer is the previous frame you
flipped into display. You now have to perform updates for two frames
to catch up; one to get back to the state of the frame you just
flipped into display, and one to turn that into the next frame.

In short, if you set up a double buffered screen and get a hardware
surface, you need to do all updates twice per frame, or deal with the
"old back buffer" in some other way.

More specifically, you need to blit the background image twice, with
an SDL_Flip() in between, and then you need to do something about the
sprite removal.

The safe way (works with both styles of double buffering) is to
remember all sprite “dirty rects” for the last two frames. Before you
blit the sprites for a new frame, restore all dirty rects from both
buffers. Then blit your sprites, overwriting the oldest set of dirty
rects.

A more efficient way is to restore using only the older set of dirty
rects. (The newer one shouldn’t be relevant until the next frame,
since it describes the page that’s currently being displayed.)
However, do keep in mind that this breaks down unless you really
have a true hardware pageflipping (“case 1”) display.

Don’t start whining about modern video subsystems being a PITA just
yet, though. There’s a third, hybrid method that covers both cases
without much extra cost: Instead of just restoring every single dirty
rect in the two sets, make a first pass where you merge overlapping
rects, to avoid updating some areas multiple times.

In many cases when dealing with sprites, and you don’t have tons of
them (ie not too many overlapping sprites), you can just consider the
last two positions of each sprite, and create a dirty rect that
covers both positions. As long as sprites move a reasonable speeds,
this means the dirty rect is only a few pixels bigger than the
sprite. Just in case, you could calculate the area of the resulting
dirty rect, and if it’s more than twice the area of the sprite’s
bounding rect, keep the separate dirty rects instead.

In Project Spitfire/DOS (double buffered h/w scrolling with an extra
buffer for scheduled background rendering), I used a variant of the
"use only the older diry rects set" method. I didn’t use dirty rects
at all, but rather kept a local tiled map for each buffer. This map
would first be filed with the index of an illegal (non-drawing)
background tile. When rendering sprites into the buffer, I would copy
tile indices from the level map into the buffer for each tile that
the sprite would overdraw. To remove the sprites, I just scanned the
"dirty map" and repainted any valid tiles found in it. Very simple
and low cost way of avoiding overdraw when removing sprites.

Of course, there’s always the fool proof, totally portable, but not
too fast brute force approach: Always repaint the whole screen
whether you really need to or not.

If you’re scrolling the whole screen, you normally need to do this
anyway. For something like a Break-Out clone or something more like a
normal application (buttons, sliders and stuff), it would be a huge
waste of resources, and it would multiply your minimum system
requirements by an insane factor for no real reason.

So, you need to be aware of both methods, and pick the one that makes
most sense for each application.

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

file://David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Well it could be great to have a FAQ about this. Obviously.

thnks

                                                       Eduardo Garcia

Rajo (h)------------------------------------------------------------------
Visite: http://www.solucion-digital.com.ar
SOLUCION DIGITAL
Redes - Software - Servicios

----- Original Message -----
From: thomas.eder@nmi.at (Thomas Eder)
To:
Sent: Friday, May 23, 2003 9:10 AM
Subject: Re: [SDL] Problems in Full Screen

I wasnt the original poster, but anyway thanks for the good explanation!
I would also vote to make it a FAQ or html page linked into
www.libsdl.org.

I remember some other posts (by Sam, etc.) in the past about this and
related topics,
maybe you could merge them together (sorry, I am going on holiday now, so
I cant help,
but will if necessary/possible when I am back),

thx,
Thomas

----- Original Message -----
From: “David Olofson”
To:
Sent: Friday, May 23, 2003 12:53 PM
Subject: Re: [SDL] Problems in Full Screen

On Friday 23 May 2003 06.10, eDU! wrote:
[…]

Can you tell me what could be the possible problem? Im sure that
its not an sdl problem, and its just the way im “showing” the
images. Maybe the background image. I can’t guess it.

When you use double buffering, there are basically two possible ways
it can be arranged:

  1. True page flipping, with two hardware surfaces that
    are swapped when you SDL_Flip(). You render into one
    while the other one is being displayed.

  2. “Fake” page flipping, with one hardware surface for
    the display, and one software surface for rendering.
    When you SDL_Flip(), the software back surface (or
    "shadow surface") is copied into the front hardware
    surface.

When you’re deailing with full screen scrollers and the like, where
the whole screen is repainted every frame, the difference is
irrelevant. Both arrangements will work fine.

However, as soon as you start doing partial updates, it makes a big
difference!

If you’re on a “case 2” display, there’s no problem; each flip will
just make sure the current version of your screen becomes visible.
You get to keep the back surface as a base for further rendering.

Now, if you do this on a “case 1” display, this no longer works. When
you flip, the page you just rendered into is swapped with the one
that was displayed. Of course, you still get your new frame
displayed, but your new back buffer is the previous frame you
flipped into display. You now have to perform updates for two frames
to catch up; one to get back to the state of the frame you just
flipped into display, and one to turn that into the next frame.

In short, if you set up a double buffered screen and get a hardware
surface, you need to do all updates twice per frame, or deal with the
"old back buffer" in some other way.

More specifically, you need to blit the background image twice, with
an SDL_Flip() in between, and then you need to do something about the
sprite removal.

The safe way (works with both styles of double buffering) is to
remember all sprite “dirty rects” for the last two frames. Before you
blit the sprites for a new frame, restore all dirty rects from both
buffers. Then blit your sprites, overwriting the oldest set of dirty
rects.

A more efficient way is to restore using only the older set of dirty
rects. (The newer one shouldn’t be relevant until the next frame,
since it describes the page that’s currently being displayed.)
However, do keep in mind that this breaks down unless you really
have a true hardware pageflipping (“case 1”) display.

Don’t start whining about modern video subsystems being a PITA just
yet, though. There’s a third, hybrid method that covers both cases
without much extra cost: Instead of just restoring every single dirty
rect in the two sets, make a first pass where you merge overlapping
rects, to avoid updating some areas multiple times.

In many cases when dealing with sprites, and you don’t have tons of
them (ie not too many overlapping sprites), you can just consider the
last two positions of each sprite, and create a dirty rect that
covers both positions. As long as sprites move a reasonable speeds,
this means the dirty rect is only a few pixels bigger than the
sprite. Just in case, you could calculate the area of the resulting
dirty rect, and if it’s more than twice the area of the sprite’s
bounding rect, keep the separate dirty rects instead.

In Project Spitfire/DOS (double buffered h/w scrolling with an extra
buffer for scheduled background rendering), I used a variant of the
"use only the older diry rects set" method. I didn’t use dirty rects
at all, but rather kept a local tiled map for each buffer. This map
would first be filed with the index of an illegal (non-drawing)
background tile. When rendering sprites into the buffer, I would copy
tile indices from the level map into the buffer for each tile that
the sprite would overdraw. To remove the sprites, I just scanned the
"dirty map" and repainted any valid tiles found in it. Very simple
and low cost way of avoiding overdraw when removing sprites.

Of course, there’s always the fool proof, totally portable, but not
too fast brute force approach: Always repaint the whole screen
whether you really need to or not.

If you’re scrolling the whole screen, you normally need to do this
anyway. For something like a Break-Out clone or something more like a
normal application (buttons, sliders and stuff), it would be a huge
waste of resources, and it would multiply your minimum system
requirements by an insane factor for no real reason.

So, you need to be aware of both methods, and pick the one that makes
most sense for each application.

Hmm… I didn’t realize there was this much to say about basic sprite
rendering. It’s all obvious enough to me that I keep forgetting, I
guess. Maybe I should hack some basic "sprites on still background"
examples, and HTMLize the above to go with it? This is an FAQ entry,
by all means.

file://David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl