Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: have fast moving sprites without distortion?  (Read 13478 times)

0 Members and 1 Guest are viewing this topic.

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« on: October 21, 2011, 03:22:48 pm »
Hello everyone.

I am new with SFML and I'm having problems moving fast sprites across the screen.

For some reason when I try to accelerate the sprite it begin to truncate and flicking. If I reduce the speed, everything goes smoothly.

Another strange effect that I'm getting is that during the course of the sprite it seems to do some "bumps" by changing the speed at regular intervals.

To move the sprite I'm using:
position x + = speed * elapsed time

I need to learn about best practices and how to have extremely fast moving sprites around the screen without distortion.

Does anyone have any tips or suggestions?

Thanks!

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
have fast moving sprites without distortion?
« Reply #1 on: October 21, 2011, 04:33:07 pm »
The kind of distortion you're talking about could be tearing or an instable framerate.  The best solution for both is to vsync.

Code: [Select]

yourwindow.EnableVerticalSync(true);

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #2 on: October 21, 2011, 06:11:20 pm »
Hello Disch

You mean windows.UseVerticalSync(true) ?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
have fast moving sprites without distortion?
« Reply #3 on: October 21, 2011, 06:26:32 pm »
In SFML 1, it's UseVerticalSync(). The method has been renamed in SFML 2 to EnableVerticalSync().

A possible alternative is SetFramerateLimit().
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #4 on: October 21, 2011, 06:48:08 pm »
I enabled UseVerticalSync and experimenting different values ​​in SetFramerateLimit but the problem persists.

It seems that the monitor can not redraw fast enough and the sprites seem to leave a trail a few pixels, as it's not cleaning the old sprite position

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
have fast moving sprites without distortion?
« Reply #5 on: October 21, 2011, 07:23:02 pm »
Quote from: "crgimenes"
as it's not cleaning the old sprite position
Don't you call Clear() every frame?

If you do, please show us a minimal and complete example code that reproduces your problem. Otherwise, we have to continue guessing...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #6 on: October 21, 2011, 07:39:07 pm »
I tried using Clear() on each frame but had no effect on the problem.

I'll try reprodizir the problem with minimal and complete code and send ASAP.

Thank you!

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #7 on: October 24, 2011, 06:25:14 pm »
Hello guys.

I made a small example to demonstrate the problem.

The code is much smaller than one created for my project and because of that the FPS is much higher. Yet I keep getting the same problem. I need sprites moving at high speed across the screen but the sprites are not clear.
When I move the sprites at low speed all goes well, but when I accelerate them the problem reappears. I'm afraid that the monitor is not fast enough to redraw the sprites at the speed I need.

I need to know if I'm doing something wrong or if is all right with my code and I have a hardware performace problem.
Also I need to know if there is any way to get around the problem, perhaps using OpenGL directly or by using some trick that I do not know.

The complete project in VisualStudio can be obtained here:
http://dl.dropbox.com/u/15771508/testFPS.zip
If you prefer only the source in C++ use this URL:
http://dl.dropbox.com/u/15771508/main.cpp

here is the source:

Code: [Select]

#include <iostream>
#include <SFML/Graphics.hpp>

int main(void)
{
sf::Event Event;

sf::RenderWindow mainRenderWindow(sf::VideoMode(1280, 768, 32), "test", sf::Style::None);

//mainRenderWindow.UseVerticalSync(true);
//mainRenderWindow.SetFramerateLimit(60);

sf::Image Image;

if (!Image.LoadFromFile("b1.png"))
{
std::cout << "error at LoadFromFile(\"b1.png\")" << std::endl;
}

sf::Image ImageBackground;

if (!ImageBackground.LoadFromFile("bg.png"))
{
std::cout << "error at LoadFromFile(\"bg.png\")" << std::endl;
}

sf::Sprite Sprite;
sf::Sprite Background;

Background.SetImage(ImageBackground);
Sprite.SetImage(Image);

float x = 200;
float y = 300;

float force_x = 1200.0f;
float force_y = 0.0f;


while (mainRenderWindow.IsOpened())
{
//mainRenderWindow.Clear();

float Framerate = 1.0f / mainRenderWindow.GetFrameTime();
std::cout << "Framerate: " << Framerate << std::endl;

//mainRenderWindow.Draw(Sprite);

while (mainRenderWindow.GetEvent(Event))
{
if (Event.Type == sf::Event::KeyReleased && Event.Key.Code == sf::Key::Escape)
{
mainRenderWindow.Close();
}
}

x += force_x * mainRenderWindow.GetFrameTime();
y += force_y * mainRenderWindow.GetFrameTime();

if(x > mainRenderWindow.GetWidth())
{
force_x = (force_x * -1);
x = (float)mainRenderWindow.GetWidth();
}

if(x < 0)
{
force_x = (force_x * -1);
x = 0;
}

if(y > mainRenderWindow.GetHeight())
{
force_y = (force_y * -1);
y = (float)mainRenderWindow.GetHeight();
}

if(y < 0)
{
force_y = (force_y * -1);
y = 0;
}


Sprite.SetPosition( x, y);

mainRenderWindow.Draw(Background);
mainRenderWindow.Draw(Sprite);

mainRenderWindow.Display();
}

return EXIT_SUCCESS;
}


Any suggestions?

Fkscorpion

  • Newbie
  • *
  • Posts: 4
    • View Profile
have fast moving sprites without distortion?
« Reply #8 on: October 26, 2011, 11:58:13 am »
Quote from: "crgimenes"


Code: [Select]


[...]
//mainRenderWindow.UseVerticalSync(true);
//mainRenderWindow.SetFramerateLimit(60);

[...]
//mainRenderWindow.Clear();




Any suggestions?


Put away the comment slashes?

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #9 on: October 26, 2011, 01:46:22 pm »
Quote from: "Fkscorpion"

Put away the comment slashes?


Yes, of course.
I did several tests trying to solve the problem with and without these lines.

I understand that Clear() is not necessary since the backgroud image is covering the whole screen, but I tested with it too.

With UseVerticalSync(true) I could see the framerate drop to about 60 as expected.

And it's the same thing with SetFramerateLimit(60), I tried several values ​​trying to reduce the problem but without success.

When I move the sprite slowly everything seems fine, but if I go up the force_x or force_y above 600, the problem appears, and I need 1800 :(

I think it's a hardware limitation, the monitor may simply not fast enough. But I need to make sure I'm not doing anything wrong before saying this to the boss.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
have fast moving sprites without distortion?
« Reply #10 on: October 26, 2011, 04:28:10 pm »
Quote
I think it's a hardware limitation, the monitor may simply not fast enough.


I wouldn't say this this to your boss.  It doesn't really make any sense.

The monitor is fast enough.  It consistently redraws at whatever refresh rate it is set to redraw at (and based on what you said, it is set to redraw at 60Hz).

Attempting to draw faster than the refresh rate is pointless, because whatever you draw won't be visible until the next time the monitor refreshes.  So you can draw a scene at 1000 FPS, but if the monitor is refreshing at 60Hz, the end user will only see 60 FPS.  All those additional frames that you draw in between will never be seen (or will only be partially seen in the form of "tearing", an ugly video effect that distorts the image)


The only other thing I can think of is the way you're doing the timing:

Code: [Select]

      x += force_x * mainRenderWindow.GetFrameTime();
      y += force_y * mainRenderWindow.GetFrameTime();


While this is a commonly used technique because it's simple, it's actually kind of wrong.  You're drawing the next scene based on how long the previous frame was.

If, for example, you get a slow frame (40 ms) mixed in with your normal frames (let's say 20 ms to keep the math simple).  What will happen is the slow frame will draw normally, and the following frame will skip way ahead because the previous frame was slow.  This will result in a "jump" that will be especially noticable on things that are moving high speed.

The only way to solve this is to VSync, since that's the only way you can be "sure" that every frame will be the same length.  Otherwise you're at the mercy of the scheduler.

If you VSync, though, the above code should work fine and there shouldn't be any jumping.

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #11 on: October 27, 2011, 06:50:59 pm »
Hi Disch, thanks for the reply.

VSync makes the jump stop. But I still have problems with the sprites. They are not clear, as if there was not time to clear the old position of the sprite on the screen before drawing the new position. it makes you see multiple sprites at the same time especially when the ball is moving vertically. When it is moving horizontally it looks blurred.

Is there anything else I can do to solve or alleviate this problem?

julen26

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • http://julen26.blogspot.com
have fast moving sprites without distortion?
« Reply #12 on: October 27, 2011, 09:09:40 pm »
Quote from: "Disch"

Code: [Select]

      x += force_x * mainRenderWindow.GetFrameTime();
      y += force_y * mainRenderWindow.GetFrameTime();



This technique is something like Euler's Integration. If you try to implement Runge-Kutta4 (RK4) technique, maybe it can be solved.

Personally I think that it does not have at all that see. It's only a different idea.

Disch

  • Full Member
  • ***
  • Posts: 220
    • View Profile
have fast moving sprites without distortion?
« Reply #13 on: October 28, 2011, 02:47:10 am »
Quote
They are not clear, as if there was not time to clear the old position of the sprite on the screen before drawing the new position. it makes you see multiple sprites at the same time especially when the ball is moving vertically. When it is moving horizontally it looks blurred.


I suppose it's a possibility that the monitor might leave "trails", but it would have to be really old and worn.  Besides, you probably would have noticed it earlier.

A more likely explanation is that it's your eyes.  Maybe you need glasses?

crgimenes

  • Newbie
  • *
  • Posts: 12
    • View Profile
have fast moving sprites without distortion?
« Reply #14 on: November 04, 2011, 10:31:47 am »
maybe I really need glasses ... :(

Anyway the problem continues, I optimize my code as much as I could. The FPS is above 1200 with vsinc disabled.

I'm worried because there will be a much larger amount of sprites on the screen when the game been completed.