The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Problem gettting a smooth continous background scroll (SDL2)
exerion


Joined: 10 Aug 2016
Posts: 4
Hello.

I imagine this topic is not new but I haven't found much about this.

I'm learning steb by step SDL2 and now I'm trying to create an infinite/continous horizontal scroll. To create the continous effect, it uses 3 images to create a big background, chaining the images while they are being scrolled and rendered. A classical.
But I noticed it's not smooth, jerking slightly.

Furthermore, I compiled the LazyFoo's tutorial #31 about continous scroll with 1 image, noticing the same effect but in a lower pace, I guess due the tutorial only uses 1 image therefore there are less rectangles to process. Not sure about this. The "jerking" is still there, normally when the image is close or just dissappearing by the left side of the window.

To discard a problem in code, I translated it into similar projects in XNA (just the calculations and rendering since I don't know much about XNA), and it is completely smooth. So I don't think the problem is in how the continous scroll is made... perhaps the timing?. The code is pretty simple.

- Window and redender are created with default parameters.
- I used a simple delay for getting 60FPS, to avoid messing with variable FPS, etc. (perhaps could it be the problem?).
- Use a left scroll with 3 pixels per frame (it could be changed in source since I'm testing it).
- Images are 400 x 300; same size for main window.
- I'm using Visual Studio 2013, 32bit mode, default compilation parameters for debug/release (I don't think I need to mess with optimizations, etc. for this simple code), under Windows7 64b.
- SDL2 last version to date.

Sample code:

Code:
   int direction = -1; // left
   int speed = 3;    // 3 pixels per frame
   bool loop = true;
   int delay = 16;   // for 60FPs

   while (loop)
   {
      SDL_Event event;
      while (SDL_PollEvent(&event))
      {
         if (event.type == SDL_QUIT) {
            loop = false;
         }
      }

      //chain images for left scroll [b](note 1)[/b]
      if (bgPosOne.x < -bgPosOne.w)
         bgPosOne.x = bgPosThree.x + bgPosThree.w;
      if (bgPosTwo.x < -bgPosTwo.w)
         bgPosTwo.x = bgPosOne.x + bgPosOne.w;
      if (bgPosThree.x < -bgPosThree.w)
         bgPosThree.x = bgPosTwo.x + bgPosTwo.w;

      // scroll images [b](note 2)[/b]
      bgPosOne.x = bgPosOne.x + (direction * speed);
      bgPosTwo.x = bgPosTwo.x + (direction * speed);
      bgPosThree.x = bgPosThree.x + (direction * speed);


      //show result[b] (note 3)[/b]
      // Clear the window and make it all red
      SDL_RenderClear( renderer );
      // Render the background images (only the images with coordenates inside the camera will be shown)
      SDL_RenderCopy(renderer, bgTextureOne, NULL, &bgPosOne );
      SDL_RenderCopy(renderer, bgTextureTwo, NULL, &bgPosTwo);
      SDL_RenderCopy(renderer, bgTextureThree, NULL, &bgPosThree);
      // Render the changes above
      SDL_RenderPresent( renderer);


      // Add a 16msec delay to make our game run at ~60 fps
      SDL_Delay(delay);
   }


-(1) it chains the images in sequence to simulate a big image. When an image goes out of the window, it's appended with the last image in the right side making it look continous. If the image is still inside the visible window, the X coordinate of each image is adjusted to the previous image. Ie:

image_1 pos x = 0; image_2 pos x = 400; image_3 pos x = 800
then scroll 3p, new X values are:
image_1 pos x = -3; image_2 pos x = 397; image_3 pos x = -797
then scroll 3p, new X values are:
image_1 pos x = -6; image_2 pos x= 394; image_3 pos x = -794
so on...

It's the classical approach to this kind of continous scroll.

-(2) scroll images to left

-(3) renders the result.


Some variations tested over this code (and not shown here):

-Changing the speed (pixels advanced per frame) or delay, doesn't show any improvement or makes the problem worse.
-Checking if an image is out of the window, therefore it's not renderered and not sent to render, doesn't improve anything.
-The effect is more noticeable when scrolling to right.
-Using other time control variations, kind of simple delta-time, etc. no improvement noticeable.
-Used surfaces and blitting instead textures, the effect is even worse.


Any suggestion is welcome. I ran out ideas about why or what happens, so any suggestion is welcome. I'm not asking about debugging my code. If you have a simple working example of smooth background and can share it, nice, I could study it and compare with my code.

Thanks you.
BenoitRen


Joined: 26 Feb 2010
Posts: 41
Location: Belgium
I see several problems:

-The duration of one frame when rendering at 60 frames per second is not 16 milliseconds, but 16.67 milliseconds (1000 / 60 = 16.67). This difference in timing adds up.

-Every frame you insert a waiting period of 16 milliseconds. This does not take into account the time it takes to process one frame between the delays.

-SDL_Delay is not very reliable. The operating system's scheduler might decide to allocate some time to another process instead of yours at the time you expect control back.

There are two approaches you can take.

One approach is using timers, which Lazy Foo' also explains in one of his tutorials. To solve the problem of one second not cleanly being divisible by 60, you can combine it with the approach explained by Aaron at Wolfire (http://forums.wolfire.com/viewtopic.php?f=1&t=16539). In short, it makes every first and second frame take 17 milliseconds, and every third frame 16 milliseconds. Personally, I combined all of that with what Disch explained at NESDev (http://forums.nesdev.com/viewtopic.php?f=3&t=6107) to try to mitigate SDL_Delay's unreliability.

The second approach is to have your program wait for vsync after rendering a frame. To use this, pass the SDL_RENDERER_PRESENTVSYNC flag to SDL_CreateRenderer's flags parameter.
Problem gettting a smooth continous background scroll (SDL2)
Jonny D


Joined: 12 Sep 2009
Posts: 932
I wanted to point out something about smooth scrolling (though this is not your particular problem), that SDL uses integer positions and so doesn't support subpixel positioning.  If you have a low rate of scrolling, like on the order of 10 pixels per second or less, you will experience pixel-sized jitter.

Jonny D




On Wed, Aug 17, 2016 at 1:44 PM, BenoitRen wrote:
Quote:
I see several problems:

-The duration of one frame when rendering at 60 frames per second is not 16 milliseconds, but 16.67 milliseconds (1000 / 60 = 16.67). This difference in timing adds up.

-Every frame you insert a waiting period of 16 milliseconds. This does not take into account the time it takes to process one frame between the delays.

-SDL_Delay is not very reliable. The operating system's scheduler might decide to allocate some time to another process instead of yours at the time you expect control back.

There are two approaches you can take.

One approach is using timers, which Lazy Foo' also explains in one of his tutorials. To solve the problem of one second not cleanly being divisible by 60, you can combine it with the approach explained by Aaron at Wolfire (http://forums.wolfire.com/viewtopic.php?f=1&t=16539). In short, it makes every first and second frame take 17 milliseconds, and every third frame 16 milliseconds. Personally, I combined all of that with what Disch explained at NESDev (http://forums.nesdev.com/viewtopic.php?f=3&t=6107) to try to mitigate SDL_Delay's unreliability.

The second approach is to have your program wait for vsync after rendering a frame. To use this, pass the SDL_RENDERER_PRESENTVSYNC flag to SDL_CreateRenderer's flags parameter.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

exerion


Joined: 10 Aug 2016
Posts: 4
BenoitRen wrote:

-The duration of one frame when rendering at 60 frames per second is not 16 milliseconds, but 16.67 milliseconds (1000 / 60 = 16.67). This difference in timing adds up.


Right. But I tried with different delays, speeds, etc. configurable while processing the scroll so I could see the changes in runtime.
Problem is still there.
I'm not completely sure if it's tearing. Looks so, if I understood correctly what tearing is.

BenoitRen wrote:

-Every frame you insert a waiting period of 16 milliseconds. This does not take into account the time it takes to process one frame between the delays.


Right. But I tried to use more advanced timing control and the problem is still there.

BenoitRen wrote:

-SDL_Delay is not very reliable. The operating system's scheduler might decide to allocate some time to another process instead of yours at the time you expect control back.


True. I was reading about that the last days and applied some timing methods withotu using SDL_Delay, related to previous suggestions. Some improvement but I still see the problem.


BenoitRen wrote:

There are two approaches you can take.

One approach is using timers, which Lazy Foo' also explains in one of his tutorials. To solve the problem of one second not cleanly being divisible by 60, you can combine it with the approach explained by Aaron at Wolfire (http://forums.wolfire.com/viewtopic.php?f=1&t=16539). In short, it makes every first and second frame take 17 milliseconds, and every third frame 16 milliseconds. Personally, I combined all of that with what Disch explained at NESDev (http://forums.nesdev.com/viewtopic.php?f=3&t=6107) to try to mitigate SDL_Delay's unreliability.

The second approach is to have your program wait for vsync after rendering a frame. To use this, pass the SDL_RENDERER_PRESENTVSYNC flag to SDL_CreateRenderer's flags parameter.


Timers... pending subject. I'll start with them.

I tried enabling Vsync before reading your suggestion. The scroll is smooth, perfect. Although I don't want to use this, because it limits the frame rate to the monitor refresh (60Hz in my case), and for this simple example is ok but for more complex processing can be a big limitation. Anyway I don't know much about game development to see if this can be or not an issue for a real 2D game.

I found many examples claiming "smooth" scrolls but 99% of them use VSync.
Few days ago I found 1 example with a very smooth scroll without using Vsync. This example (http://olofson.net/download/smoothscroll-1.1.tar.gz) uses SDL1 or GL (selectable), and a "time filter" to deal with shedulling jitter.
The example shows a very smooth scroll with a map bigger than screen (in fact it's a parallax scroll of 3 layers).
It comes with a precompiled example. The example works nicely. I compiled the source in VS2013, and... tadaaaaa with the new compiled code the scroll is not smooth Crying or Very sad

I have to explore this, because makes no sense unless something is happening related to my especific hardware (I'm using a laptop). Again from my novice perspective a simple smooth scrool shouldn't be so hard, but it looks it is a challenge (of course without using Vsync).


Jonny D wrote:

If you have a low rate of scrolling, like on the order of 10 pixels per second or less, you will experience pixel-sized jitter.


Yep, I was reading indirectly about that, when people use floats for calculating speeds and positioning what is correct then rendering with floats results and weird things happened.


I'll try all your suggestions (and read the websites you posted), and will return with the results. I don't want to use Vsyng. If anyone has more to say, don't hesitate, I'll read the forum often.
Problem gettting a smooth continous background scroll (SDL2)
Faluk


Joined: 16 Apr 2015
Posts: 17
If you send me a link to download your solution I can take a look to it tomorrow morning and see if I see something wrong, I have free time and willing to help. (I tried to check the tutorial but I'm lazy to compile SDL_Image).

Smile


2016-08-19 17:19 GMT+02:00 exerion:
Quote:



BenoitRen wrote:


-The duration of one frame when rendering at 60 frames per second is not 16 milliseconds, but 16.67 milliseconds (1000 / 60 = 16.67). This difference in timing adds up.




Right. But I tried with different delays, speeds, etc. configurable while processing the scroll so I could see the changes in runtime.
Problem is still there.
I'm not completely sure if it's tearing. Looks so, if I understood correctly what tearing is.




BenoitRen wrote:


-Every frame you insert a waiting period of 16 milliseconds. This does not take into account the time it takes to process one frame between the delays.





Right. But I tried to use more advanced timing control and the problem is still there.




BenoitRen wrote:


-SDL_Delay is not very reliable. The operating system's scheduler might decide to allocate some time to another process instead of yours at the time you expect control back.





True. I was reading about that the last days and applied some timing methods withotu using SDL_Delay, related to previous suggestions. Some improvement but I still see the problem.





BenoitRen wrote:


There are two approaches you can take.

One approach is using timers, which Lazy Foo' also explains in one of his tutorials. To solve the problem of one second not cleanly being divisible by 60, you can combine it with the approach explained by Aaron at Wolfire (http://forums.wolfire.com/viewtopic.php?f=1&t=16539). In short, it makes every first and second frame take 17 milliseconds, and every third frame 16 milliseconds. Personally, I combined all of that with what Disch explained at NESDev (http://forums.nesdev.com/viewtopic.php?f=3&t=6107) to try to mitigate SDL_Delay's unreliability.

The second approach is to have your program wait for vsync after rendering a frame. To use this, pass the SDL_RENDERER_PRESENTVSYNC flag to SDL_CreateRenderer's flags parameter.




Timers... pending subject. I'll start with them.

I tried enabling Vsync before reading your suggestion. The scroll is smooth, perfect. Although I don't want to use this, because it limits the frame rate to the monitor refresh (60Hz in my case), and for this simple example is ok but for more complex processing can be a big limitation. Anyway I don't know much about game development to see if this can be or not an issue for a real 2D game.

I found many examples claiming "smooth" scrolls but 99% of them use VSync.
Few days ago I found 1 example with a very smooth scroll without using Vsync. This example (http://olofson.net/download/smoothscroll-1.1.tar.gz) uses SDL1 or GL (selectable), and a "time filter" to deal with shedulling jitter.
The example shows a very smooth scroll with a map bigger than screen (in fact it's a parallax scroll of 3 layers).
It comes with a precompiled example. The example works nicely. I compiled the source in VS2013, and... tadaaaaa with the new compiled code the scroll is not smooth

I have to explore this, because makes no sense unless something is happening related to my especific hardware (I'm using a laptop). Again from my novice perspective a simple smooth scrool shouldn't be so hard, but it looks it is a challenge (of course without using Vsync).





Jonny D wrote:


If you have a low rate of scrolling, like on the order of 10 pixels per second or less, you will experience pixel-sized jitter.




Yep, I was reading indirectly about that, when people use floats for calculating speeds and positioning what is correct then rendering with floats results and weird things happened.


I'll try all your suggestions (and read the websites you posted), and will return with the results. I don't want to use Vsyng. If anyone has more to say, don't hesitate, I'll read the forum often.



Signature under construction.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

exerion


Joined: 10 Aug 2016
Posts: 4
Which tutorial? Lazy foo's Timers? I still have to read it.

I'm using a basic delta-time for timing.

In these few hours I was guessing why the same code is smooth in the example I found (see link provided in previous posts), but not when compiled in my computer. So I wanted to check if the compiler can affect in some way and so evident.

I installed Eclipse + Mingw + SLD2 -I have to say wasting 90% of time dealing with errors, problems detecting the toolchain, etc-. Finally I got it working and compiled my continous scroll example (because it's simplier and i know it). Performance is pretty similar to VS2013, with minimal differences in speed (there are some but for me, 1-2ms per frame is not relevant now). Images still are tearing (again I say tearing because I think this is the effect).


Link with my code and the example i was talking about:

https://mega.nz/#!DgVjVaYJ!OBSd3q4G44ex5EOUCAazjjGGuFl__bw4asMo4TzqVQU

There are some .exe and dlls. All exes for VS2013 are compiled by me, the DLLs are from SDL official package. Anyother exe was compiled by third parties but I haven't found any wrong with them.

I'll continue with this odissey...

If anyone has some article, book or any other reference about SMOOTH scrolls (key here is smooth of course Very Happy ), I'd appreciate this. This has becomed something personal Very Happy
Problem gettting a smooth continous background scroll (SDL2)
Jonny D


Joined: 12 Sep 2009
Posts: 932
I doubt that timers are going to get you any better response.  Timers with SDL are just threaded callbacks set with SDL_AddTimer().  This starts a thread which will fire your callback when the timer expires.

Also, vsync is a good thing.  It caps the framerate to 60 fps and makes sure you hit the vertical refresh of your monitor to avoid tearing/flickering.  It makes your GPU do less work by not rendering frames that your monitor wouldn't be capable of displaying anyway.  Pretty much the only time you need to disable vsync is when you want to measure performance above 60 fps.


Jonny D





On Fri, Aug 19, 2016 at 2:12 PM, exerion wrote:
Quote:
Which tutorial? Lazy foo's Timers? I still have to read it.

I'm using a basic delta-time for timing.

In these few hours I was guessing why the same code is smooth in the example I found (see link provided in previous posts), but not when compiled in my computer. So I wanted to check if the compiler can affect in some way and so evident.

I installed Eclipse + Mingw + SLD2 -I have to say wasting 90% of time dealing with errors, problems detecting the toolchain, etc-. Finally I got it working and compiled my continous scroll example (because it's simplier and i know it). Performance is pretty similar to VS2013, with minimal differences in speed (there are some but for me, 1-2ms per frame is not relevant now). Images still are tearing (again I say tearing because I think this is the effect).


Link with my code and the example i was talking about:

https://mega.nz/#!DgVjVaYJ!OBSd3q4G44ex5EOUCAazjjGGuFl__bw4asMo4TzqVQU

There are some .exe and dlls. All exes for VS2013 are compiled by me, the DLLs are from SDL official package. Anyother exe was compiled by third parties but I haven't found any wrong with them.

I'll continue with this odissey...

If anyone has some article, book or any other reference about SMOOTH scrolls (key here is smooth of course ), I'd appreciate this. This has becomed something personal



Signature under construction.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Problem gettting a smooth continous background scroll (SDL2)
Faluk


Joined: 16 Apr 2015
Posts: 17
This define is the problem:

#define MIN_FRAMETIME_MSECS 33


Modify it to 16 and goes really smoth.

#define MIN_FRAMETIME_MSECS 16

Smile


2016-08-19 20:12 GMT+02:00 exerion:
Quote:
Which tutorial? Lazy foo's Timers? I still have to read it.

I'm using a basic delta-time for timing.

In these few hours I was guessing why the same code is smooth in the example I found (see link provided in previous posts), but not when compiled in my computer. So I wanted to check if the compiler can affect in some way and so evident.

I installed Eclipse + Mingw + SLD2 -I have to say wasting 90% of time dealing with errors, problems detecting the toolchain, etc-. Finally I got it working and compiled my continous scroll example (because it's simplier and i know it). Performance is pretty similar to VS2013, with minimal differences in speed (there are some but for me, 1-2ms per frame is not relevant now). Images still are tearing (again I say tearing because I think this is the effect).


Link with my code and the example i was talking about:

https://mega.nz/#!DgVjVaYJ!OBSd3q4G44ex5EOUCAazjjGGuFl__bw4asMo4TzqVQU

There are some .exe and dlls. All exes for VS2013 are compiled by me, the DLLs are from SDL official package. Anyother exe was compiled by third parties but I haven't found any wrong with them.

I'll continue with this odissey...

If anyone has some article, book or any other reference about SMOOTH scrolls (key here is smooth of course ), I'd appreciate this. This has becomed something personal



Signature under construction.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

exerion


Joined: 10 Aug 2016
Posts: 4
Yes, chaging the value from 33 to 16 smoothens the transition a lot, but I still see the problem.
And in the moment I change the speed (faster), is more evident. It's too noticeable.

I know not using V-sync imposes some visual limitations, aka, it's quite hard to achieve a smooth scroll in the same way v-sync is enabled. Is it so hard to have a smooth scroll without v-sync? looks so.

Basicaly the image looks like shaking or jumping, not sure how to explain. The effect is more evident when I replaced the original images with a chess-pattern as I read in a forum, that helps to detect problems with moving images.

I'll continue working on it.

Btw I appreciate a lot all of your suggestions Very Happy.
Problem gettting a smooth continous background scroll (SDL2)
Faluk


Joined: 16 Apr 2015
Posts: 17
It's going to be hard to make it completely smooth without vSync. Sometimes you will see the same image for 2 screen refresh, and sometimes you will call to render two times on the same screen refresh. Since there is no synchronization that is the best you can reach without it. Also sometimes you will see part of the render moved in horizontal because the game is rendering in the middle of the screen refresh. The odds of not using vSync....


Good luck with it.



2016-08-21 20:39 GMT+02:00 exerion:
Quote:
Yes, chaging the value from 33 to 16 smoothens the transition a lot, but I still see the problem.
And in the moment I change the speed (faster), is more evident. It's too noticeable.

I know not using V-sync imposes some visual limitations, aka, it's quite hard to achieve a smooth scroll in the same way v-sync is enabled. Is it so hard to have a smooth scroll without v-sync? looks so.

Basicaly the image looks like shaking or jumping, not sure how to explain. The effect is more evident when I replaced the original images with a chess-pattern as I read in a forum, that helps to detect problems with moving images.

I'll continue working on it.

Btw I appreciate a lot all of your suggestions .



Signature under construction.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org