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

Author Topic: My problem with frame time and it's blurriness...  (Read 3792 times)

0 Members and 1 Guest are viewing this topic.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
My problem with frame time and it's blurriness...
« on: October 09, 2008, 01:55:13 pm »
I've gotten a good game engine going after spending quite some time with SFML, but now I've run into a bit of a problem.
You see, if I move a render window's view by any decimal, it blurs the image to appear to be in multiple pixels at the same time.
Up until now, It's never really been a real problem because I only drew box-shaped objects to the view.
However, now that I have started to draw objects with more complicated geometry, it's really annoying to see how blurry things can get.
Most would figure that it'd just be as easy as moving all my objects by whole numbers instead of decimals.
This wouldn't work though because I am multiplying the movement of my view by the application's frame time in order to maintain the same speed across different systems.

Here's some code that can help replicate the problem:
Code: [Select]
       float Offset  = App.GetFrameTime() * 128.f;
        float OffsetX = 0.f;
        float OffsetY = 0.f;

        if (Input.IsKeyDown(sf::Key::Up))    OffsetY = -Offset;
        if (Input.IsKeyDown(sf::Key::Left))  OffsetX = -Offset;
        if (Input.IsKeyDown(sf::Key::Down))  OffsetY += Offset;
        if (Input.IsKeyDown(sf::Key::Right)) OffsetX += Offset;

        View.Move(OffsetX, OffsetY);


I have thought of rounding the offset to the nearest whole number, but that would lower the resolution of my view.
Perhaps it'd be best if SFML rounded to the nearest whole number while rendering each frame without modifying the resolution of my view.
Anyways, I am simply looking for advice on the subject; it doesn't look too great having a blurry game.

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
My problem with frame time and it's blurriness...
« Reply #1 on: October 09, 2008, 04:06:02 pm »
What's hard about calculating a camera pos as a float and then rounding to an int before setting the actual position?

Edit:  Also, that "blur" can make things in motion look smoother.  You probably only notice it when you stop moving.  So you might consider not rounding while the screen is scrolling.  (See what looks better to you)

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
My problem with frame time and it's blurriness...
« Reply #2 on: October 09, 2008, 06:11:28 pm »
Quote from: "quasius"
What's hard about calculating a camera pos as a float and then rounding to an int before setting the actual position?

That's what I figured I would have to do, but that would mean widening the speed gap between systems.

Quote
Edit:  Also, that "blur" can make things in motion look smoother.  You probably only notice it when you stop moving.  So you might consider not rounding while the screen is scrolling.  (See what looks better to you)

I guess it depends on how fast your objects are moving (it's really noticeable on my slow app).


Edit:
I tried rounding to the nearest whole number, but that made an extreme difference in the speed of objects when I ran the program at different frame limits.
The only way I can think of to get around this is to derive a class from RenderWindow and override it's Draw member function.
That way, I can make it round to the nearest whole number while drawing, rather than changing the actual position of the view.

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
My problem with frame time and it's blurriness...
« Reply #3 on: October 10, 2008, 07:08:23 am »
Quote from: "Wizzard"

That's what I figured I would have to do, but that would mean widening the speed gap between systems.


Wut?  You're worried about the speed of rounding floats?  If that made an "extreme difference" in FPS you're almost certainly doing something wrong or have some off-the-wall not-real-world corner case for your test.  And deriving a new drawable won't accomplish anything.  You still have to round at some point if you want objects on a whole number position.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
My problem with frame time and it's blurriness...
« Reply #4 on: October 10, 2008, 08:55:05 am »
Quote from: "quasius"
Wut?  You're worried about the speed of rounding floats?  If that made an "extreme difference" in FPS you're almost certainly doing something wrong or have some off-the-wall not-real-world corner case for your test.  And deriving a new drawable won't accomplish anything.  You still have to round at some point if you want objects on a whole number position.

I did not mean to say that it made a difference in my FPS, but that it made a difference in the speed of my objects too much.
For example, if I set the frame limit of my application to 72, it takes approximately 5 seconds for an object to travel 1024 pixels.
On the contrary, if I set the frame limit of my application to 60, it takes approximately 4 seconds for an object to travel 1024 pixels.

Here's the code:
Code: [Select]
       int   Offset  = static_cast<int>(App.GetFrameTime() * 128.f);
        float OffsetX = 0.f;
        float OffsetY = 0.f;

        if (Input.IsKeyDown(sf::Key::Up))    OffsetY = -Offset;
        if (Input.IsKeyDown(sf::Key::Left))  OffsetX = -Offset;
        if (Input.IsKeyDown(sf::Key::Down))  OffsetY += Offset;
        if (Input.IsKeyDown(sf::Key::Right)) OffsetX += Offset;

        View.Move(OffsetX, OffsetY);


I would very much like my objects to travel at the same speed regardless of how much FPS my user is getting, but I would also like to not have blurriness.

I will try to post my fix later in this thread if you're interested in seeing what I come up with.

quasius

  • Full Member
  • ***
  • Posts: 166
    • View Profile
My problem with frame time and it's blurriness...
« Reply #5 on: October 11, 2008, 04:42:37 am »
You're missing the point.  You internally track the position of the object as normal.  You don't round that.  If you do, you're obviously going to change the movement speed calculations.
Just round the position right before rendering then change it back.  You don't even need another class variable.  Just do it in-line in the render code.  Temp save the real value, wright the rounded value, render, write-back the real value.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
My problem with frame time and it's blurriness...
« Reply #6 on: October 13, 2008, 08:41:52 am »
I was out this weekend, but soon I can get to writing this simple bit of code. Anyways, I was thinking of the exact same thing as you, but I was going to implement it in a nice way by making views have an unsigned int Rect member that remains private in which only the friend RenderWindow could see. That way we don't have to round the position for every object drawn. We only round when we move the view.


Edit:
Aw man, I thought this was going to be easy. I tried prototyping it before making it fancy, but it doesn't produce the results you'd think it would:

Code: [Select]
       const sf::Vector2f& Center = View.GetCenter();

        View.SetCenter(static_cast<int>(Center.x), static_cast<int>(Center.y));

        App.SetView(View);
        App.Draw(World);
        App.Draw(Enemy);

        View.SetCenter(Center);



Edit:
I found a way to round floats flawlessly and now my project is working flawlessly:

Code: [Select]
       const sf::Vector2f& Center = View.GetCenter();

        View.SetCenter(floorf(Center.x + 0.5f), floorf(Center.y + 0.5f));

        App.SetView(View);
        App.Draw(World);
        App.Draw(Enemy);

        View.SetCenter(Center);