Double Buffering With SDL

Started by
19 comments, last by pseudobot 14 years, 11 months ago
Hi all! :) As some of you might now, I just started learning SDL. One problem I came across is that when I move something on the screen, sometimes a tear/rip will show. What I heard is that a double-buffer would eliminate this problem. Now my problem is this: I have no idea on how to use a double buffer in SDL. If someone would be so kind, could you please show me how to Set up 2 Surfaces that can be blitted to, and swapping them around as viewable? Thank you for you time and effort. :) Please do not mark threads 'solved' in this forum. -- jpetrie [Edited by - jpetrie on May 4, 2009 11:33:32 PM]
Advertisement
Just use SDL in software mode, it does double buffering by default. (When creating the window, pass the SDL_SWSURFACE flag, instead of SDL_HWSURFACE)

Also, only call SDL_Flip() once per frame, after doing all your drawing. Don't call it more than once a frame.
^Wouldn't I have to set up two surfaces for double buffering (one in the background that I can swap around, and one that is being displayed right now)? I was pretty sure I would have to do that... :-/
By the way, I am flipping the screen only once per frame, and I am using the SDL_SWSURFACE flag when creating my surface.
No, don't use software mode, add this flag to SDL_SetVideoMode:
SDL_DOUBLEBUF

for example, you could use this line:

SDL_SetVideoMode(800, 600, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);

software mode does tend to use double buffering by default but you really want hardware acceleration.

Also, no, you don't have to manually handle different buffers, SetVideoMode actually sets the display surface, this is not the same as using a surface for holding an image. In hardware mode, the GPU memory will be used for the back and front buffers.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
Thanks for your help guys. However, my application (just a ball that you can move around the screen with the arrow keys) still Tear/Rips and seems to freeze in/out for a split second sometimes. Could it be the way I am blitting the images? Or is there some other reason why this happens?

Here is my rendering code:
(screen is the screen surface, background the background image and hero the movable ball)
void render() {    SDL_FillRect(screen, NULL, 0);    SDL_BlitSurface(background, NULL, screen, &backgroundRect);    SDL_BlitSurface(hero, NULL, screen, &heroRect);    SDL_Flip(screen);}

Thanks in advance. :)
Quote:Original post by pseudobot
^Wouldn't I have to set up two surfaces for double buffering (one in the background that I can swap around, and one that is being displayed right now)? I was pretty sure I would have to do that...

That's what double buffering is, yes, but SDL handles it for you, so you don't need to. If you were writing your game using Win32, or some other API, then yeah, you might need to manually handle two different buffers, but SDL swaps/flips the buffers for you, when you call SDL_Flip(). [smile]
Quote:Original post by pseudobot
Thanks for your help guys. However, my application (just a ball that you can move around the screen with the arrow keys) still Tear/Rips and seems to freeze in/out for a split second sometimes. Could it be the way I am blitting the images? Or is there some other reason why this happens?

Is your 'render()' function the only place where you do any blitting, or SDL_Flip()ing? Is your render() function only called once per frame?

What exactly do you mean by ripping/tearing? Does the screen flash white for a fraction of a second, or flash the color of the background? Does the ball 'jitter' from side to side (or up/down)? And if so, are you using floats anywhere?

What exactly do you mean by 'freezing' in and out for a moment? The game ceases to respond to your input, and you can't move the ball?
Quote:Original post by speciesUnknown
software mode does tend to use double buffering by default but you really want hardware acceleration.

There's no point to optimize unneccasarily. If and when he needs the extra speed, then he can always change it, but if this is his first project with SDL, he probably won't need to run the game on the videocard anyway. I've never had to use hardware acceleration with my SDL projects. I admit, my most recent game wasn't really fast-paced, but I was doing plenty of alpha-surface blits per frame, with a smooth framerate.

I understand your point though; why not gain extra speed just by changing the flags? I just never found it necessary with my small projects. If it had become necessary , then I'd make the appropriate changes, but until then, I don't think there's any reason to do so (Except to brag that your game runs at 200 fps per second while mine only runs at 40. [wink]).
Quote:Is your 'render()' function the only place where you do any blitting, or SDL_Flip()ing? Is your render() function only called once per frame?

What exactly do you mean by ripping/tearing? Does the screen flash white for a fraction of a second, or flash the color of the background? Does the ball 'jitter' from side to side (or up/down)? And if so, are you using floats anywhere?

Yes, I am calling SDL_Flip() only once (at the end of the rendering function). With tearing, I mean that the ball that you can move jitters from side to side sometimes. And yes, I am using a double to store the X and Y Velocity of the ball, that gets then added to the SDL_Rect holding the hero. Is this the cause of the problem?

Btw, that with the freezing up was my own fault - messed up a calculation of friction so it LOOKED like it was freezing up. But that's fixed now. :)


Quote:Original post by pseudobot
Yes, I am calling SDL_Flip() only once (at the end of the rendering function). With tearing, I mean that the ball that you can move jitters from side to side sometimes. And yes, I am using a double to store the X and Y Velocity of the ball, that gets then added to the SDL_Rect holding the hero. Is this the cause of the problem?

Most likely, yes. If it was a double-buffering problem, you'd see the screen get cleared, and it'd take too long (fractions of a second) to draw the image, so the program would 'flash' the background color before it'd finish draw the image, and your quick eyes would notice it. But that's not happening here.
A lack of double buffering wouldn't make your images move from side to side, so it has to be something with your positioning of the images. I assumed it was a float; sometimes floats behave that way because they aren't too accurate, they sometimes cause these kind of problems.

Unfortunately, I don't have too much experience with floats/doubles; I only have casual familiarity with them, so hopefully someone with more experience with them could tell you how to resolve your problem.
Quote:Btw, that with the freezing up was my own fault - messed up a calculation of friction so it LOOKED like it was freezing up. But that's fixed now. :)

Glad that that has been fixed, at least. [smile]
So, should I round the doubles number before making the X and Y of the rect those values? If so, is tehre allready a rounding function with the C++ standard libraries?
To round a value, add 0.5, then cast to int or call floor(). Only round a copy that you're putting into the rect, not the original value, or you'll end up changing its velocity.

This topic is closed to new replies.

Advertisement