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

Author Topic: Image of Sprite Skipping on Screen  (Read 14176 times)

0 Members and 1 Guest are viewing this topic.

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Image of Sprite Skipping on Screen
« on: February 15, 2018, 05:32:40 am »
EDIT: TO ANYONE READING THIS, IT IS NOT THE BIG JUMP THAT IS THE ISSUE. THAT'S JUST THE GIF LOOPING. THE PROBLEM IS THE JITTERING OF THE IMAGE, BACK AND FORTH IF YOU LOOK CLOSELY.

Hey, everyone. So this is something that I believe might be a bug, however, I have only been using SFML for about a week now, so I could definitely be doing something wrong.

First of all, let's get my hardware and software specifications out of the way:
RAM: 16GB DDR3
CPU: i5-3570k
GPU: GTX 1060 6GB, most recent drivers 390.77
Monitor #1: 2560 x 1440 @ 144fps w/ G-Sync
Monitor #2: 1280 x 1024 @ 60fps

OS: Windows 10, v. 1709, build 16299
IDE: Visual Studio 2015
SFML Version: 2.4.2

So, here is the problem I'm having. When I try to modify the position of anything related to a sprite, the image of the sprite appears to "jump" back and forth, and I've provided an image of how it looks for me below.



Here is the code that reproduces this problem for me:

Quote
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

int main() {

   sf::RenderWindow window(sf::VideoMode(900, 600), "SFML", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close);

   //window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(144);
   //window.setFramerateLimit(60);

   int refresh_rate = 60;
   float frame_time = (float) 1 / (float) 60;

   // Background //
   sf::Texture background;
   if (!background.loadFromFile("stars.png"))
      exit(1);
   background.setRepeated(true);

   sf::Sprite stars(background);

   int posx = 0;
   // ---------- //

   sf::Clock clock;
   sf::Time passed_time;
   while ( window.isOpen() ) {

      sf::Event event;
      while (window.pollEvent(event)) {
         switch (event.type)
         {
            case sf::Event::Closed:
               window.close();
               break;
            case sf::Event::Resized:
               window.setView(sf::View(sf::FloatRect(0.f, 0.f, event.size.width, event.size.height)));
               break;
         }
      }

      passed_time += clock.restart();
      while (passed_time.asSeconds() >= frame_time) {

         stars.setTextureRect(sf::IntRect(posx, 0, window.getSize().x, window.getSize().y));
         posx += 2;

         window.clear();
         window.draw(stars);
         window.display();

         passed_time -= sf::seconds(frame_time);

      }

   }

}

I've read the entire FAQ and documentation provided for SFML over the last week from https://www.sfml-dev.org/learn.php

I thought that I might be doing something wrong, and here are outside resources I've utilized so far to try and understand, and come up with, this code above, other than my 3 years of C++ experience in university:
https://gafferongames.com/post/fix_your_timestep/
https://maksimdan.gitbooks.io/sfml-and-gamedevelopement/content/frame_rate.html
https://gamedev.stackexchange.com/questions/97675/sfml-game-loop-and-fps-problems

None of these seemed to fix the skipping problem, and after some more Googling, I found that some people had an issue with Nvidia's "Threaded Optimization" setting, however this had no measurable effect on performance for me when switched from "auto" to "off."

I had also seen that some people had an issue similar to mine depending on what their framerate was set to. So, I tried every possible combination of enabling vertical sync, limiting the frame rate, changing my threading optimization, and changing from debug to release.

None of these were able to remedy the issue. If it is something obvious, please let me know. I've been re-reading the documentation and tutorials for hours (from 7pm - 11pm just today) and would really appreciate any step in the right direction.

Thank you.  :)
« Last Edit: February 17, 2018, 08:51:13 pm by Kondie »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Image of Sprite Skipping on Screen
« Reply #1 on: February 15, 2018, 06:38:33 am »
What's the value of posx when it jumps? Maybe you should try to put it back to 0 when it reaches the texture width, so that it doesn't increase endlessly.
Laurent Gomila - SFML developer

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #2 on: February 15, 2018, 05:25:04 pm »
Well, I took your advice on this and changed the main loop to the following:

Quote
      while (passed_time.asSeconds() >= frame_time) {

         stars.setTextureRect(sf::IntRect(posx, 0, window.getSize().x, window.getSize().y));

         //std::cout << "POSX: " << posx + 2 << " % " << background.getSize().x << "\n";
         posx = (posx + 2) % (background.getSize().x);
         //std::cout << " = " << posx << "\n\n";

         window.clear();
         window.draw(stars);
         window.display();

         passed_time -= sf::seconds(frame_time);

      }

The lag is noticeably better, but still present. It's as if every few seconds the image decides it would like to take 1 jump back, and 2 jumps forward. This is after I tried all combinations of, once again, disabling threaded optimization, running in release, and the various frame modifiers that are commented out in the code of my original post.

I've commented out the cout statements in the loop above, but added them in after trying the previous steps to see if there were any consistencies in the textures wrapped position vs when the frame lag appears. I found none.

Is it possibly some faulty logic with my clock?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Image of Sprite Skipping on Screen
« Reply #3 on: February 15, 2018, 06:12:10 pm »
Quote
Is it possibly some faulty logic with my clock?
Well, there's only one way to be sure: try without it. Write the simplest example possible that scrolls the sprite, and see if it still happens.
Laurent Gomila - SFML developer

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #4 on: February 15, 2018, 06:23:34 pm »
I was under the impression that wouldn't help me either because I am now relying on the the frame rate for how smooth the texture scrolls. It was skipping for me before, which is why I attempted to add in the clock, as I thought the lack of one might be why it was skipping in the first place.

The following code still produces a skipping image when trying all combinations previously mentioned:

Quote
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

int main() {

   sf::RenderWindow window(sf::VideoMode(900, 600), "SFML", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close);

   //window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(144);
   //window.setFramerateLimit(60);

   // Background //
   sf::Texture background;
   if (!background.loadFromFile("stars_square.png"))
      exit(1);
   background.setRepeated(true);

   sf::Sprite stars(background);

   // ---------- //

   int posx = 0;
   while ( window.isOpen() ) {

      sf::Event event;
      while (window.pollEvent(event)) {
         switch (event.type)
         {
            case sf::Event::Closed:
               window.close();
               break;
            case sf::Event::Resized:
               window.setView(sf::View(sf::FloatRect(0.f, 0.f, event.size.width, event.size.height)));
               break;
         }
      }

      stars.setTextureRect(sf::IntRect(posx, 0, window.getSize().x, window.getSize().y));
      posx = (posx + 1) % (background.getSize().x);

      window.clear();
      window.draw(stars);
      window.display();

   }

}

Setting the framerate to my monitor, running in release mode, and turning off threaded optimization yielded the best results. However, after a few seconds there is still noticeable skipping of the image on my screen.

If there are any glaringly obvious errors that I've missed here I would really appreciate a tip. I've been working on this for hours now, so it could be as simple as needing someone else to read my code to find the dumb mistake.
« Last Edit: February 15, 2018, 06:31:26 pm by Kondie »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #5 on: February 15, 2018, 06:31:24 pm »
I'm guessing the big jump I see is actually just your gif looping? Your real problem is the slight stuttering that happens a few times between the big jumps in your gif?

Can you double check that your driver isn't forcing vsync on? What does your framerate look like?

If you try replacing your original fixed timestep with a variable delta time do you still get stuttering?



Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #6 on: February 16, 2018, 02:51:03 am »
Yes, that's correct. The big jump is the gif looping, and the real issue is the slight stuttering. It's extremely noticeable at times when it repeatedly stutters.

So, I checked and ensured that my graphics drivers weren't forcing v-sync, and turned it off completely just to make sure, even though my GPU was running at an extremely high percentage, just to be safe lol.

The next step was implementing the variable delta time step from here: https://gafferongames.com/post/fix_your_timestep/, which... still lead to the stuttering issue with all combinations of what I've previously tried: threaded optimization, forced v-sync, setting the window frame limit, setting the window to v-sync...

Here's a visual:


Here's the code:
Quote
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

int main() {

   sf::RenderWindow window(sf::VideoMode(900, 600), "SFML", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close);

   //window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(144);
   //window.setFramerateLimit(60);

   int refresh_rate = 60;

   // Background //
   sf::Texture background;
   if (!background.loadFromFile("stars_square.png"))
      exit(1);
   background.setRepeated(true);

   sf::Sprite stars(background);

   float posx = 0;
   float currentspeed = 0;
   float picture_speed = 30;
   // ---------- //

   sf::Clock clock;
   float current_time = clock.getElapsedTime().asSeconds();
   float frame_time = 0;
   while ( window.isOpen() ) {

      sf::Event event;
      while (window.pollEvent(event)) {
         switch (event.type)
         {
            case sf::Event::Closed:
               window.close();
               break;
            case sf::Event::Resized:
               window.setView(sf::View(sf::FloatRect(0.f, 0.f, event.size.width, event.size.height)));
               break;

         }
      }

      float new_time = clock.getElapsedTime().asSeconds();
      frame_time = new_time - current_time;
      current_time = new_time;

      stars.setTextureRect(sf::IntRect(posx, 0, window.getSize().x, window.getSize().y));

      posx = std::fmod(posx + (picture_speed * frame_time), background.getSize().x);

      window.clear();
      window.draw(stars);
      window.display();

   }

}

Anymore ideas? Really appreciate the help so far, guys.

As a side note, just to double check that the skipping wasn't due to the value of posx never increasing or somehow moving back (no idea what would cause this, but figured I'd check), I added in a cout statement.

Here is the output:
Quote
posx is <= what it was before
0.00170898 <= 399.996
posx is <= what it was before
0.00354004 <= 400
posx is <= what it was before
0.00378418 <= 399.998
posx is <= what it was before
0.00219727 <= 399.998
posx is <= what it was before
0.00317383 <= 399.999
posx is <= what it was before
0.0057373 <= 399.992

And here's the code I added to the loop:
Quote
      posx = std::fmod(posx + (picture_speed * frame_time), background.getSize().x);

      if (posx <= previous_posx) std::cout << "\nposx is <= what it was before\n" << posx << " <= " << previous_posx;

      window.clear();
      window.draw(stars);
      window.display();

So, that's not the issue as far as I can tell.

Edit: So I tried out a few of the games here https://www.youtube.com/watch?time_continue=191&v=zH_omFPqMO4 that require smooth movement and every single one of them gave me the skipping issue when trying all of the things I mentioned here to remedy it. So, I'm beginning to think it's a hardware issue. However, absolutely no other games do this for me except those that utilize SFML.

Aaaaaand this game https://eigen.itch.io/pioneers exhibits the same behavior...
« Last Edit: February 16, 2018, 06:53:45 am by Kondie »

dmitry_t

  • Newbie
  • *
  • Posts: 17
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #7 on: February 16, 2018, 07:04:09 am »
Can you try updating the sprite position every frame instead of changing its texture rect?

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #8 on: February 16, 2018, 07:26:39 am »
Still produces the same skipping. Even with removing the timer. Here are both code snippets:

Quote
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

int main() {

   sf::RenderWindow window(sf::VideoMode(900, 600), "SFML", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close);

   //window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(144);
   //window.setFramerateLimit(60);

   int refresh_rate = 60;

   // Background //
   sf::Texture background;
   if (!background.loadFromFile("stars_square.png"))
      exit(1);
   background.setRepeated(true);

   sf::Sprite stars(background);

   float posx = 0;
   float currentspeed = 0;
   float picture_speed = 30;
   // ---------- //

   sf::Clock clock;
   float current_time = clock.getElapsedTime().asSeconds();
   float frame_time = 0;

   while ( window.isOpen() ) {

      sf::Event event;
      while (window.pollEvent(event)) {
         switch (event.type)
         {
            case sf::Event::Closed:
               window.close();
               break;
            case sf::Event::Resized:
               window.setView(sf::View(sf::FloatRect(0.f, 0.f, event.size.width, event.size.height)));
               break;
               
         }
      }

      float new_time = clock.getElapsedTime().asSeconds();
      frame_time = new_time - current_time;
      current_time = new_time;

      stars.setPosition(posx, 0);

      posx = std::fmod(posx + (picture_speed * frame_time), background.getSize().x);

      window.clear();
      window.draw(stars);
      window.display();

   }

}

Quote
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

int main() {

   sf::RenderWindow window(sf::VideoMode(900, 600), "SFML", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close);

   //window.setVerticalSyncEnabled(true);
   //window.setFramerateLimit(144);
   //window.setFramerateLimit(60);

   int refresh_rate = 60;

   // Background //
   sf::Texture background;
   if (!background.loadFromFile("stars_square.png"))
      exit(1);
   background.setRepeated(true);

   sf::Sprite stars(background);

   float posx = 0;
   // ---------- //

   while ( window.isOpen() ) {

      sf::Event event;
      while (window.pollEvent(event)) {
         switch (event.type)
         {
            case sf::Event::Closed:
               window.close();
               break;
            case sf::Event::Resized:
               window.setView(sf::View(sf::FloatRect(0.f, 0.f, event.size.width, event.size.height)));
               break;
               
         }
      }

      stars.setPosition(posx, 0);

      posx += .01;

      window.clear();
      window.draw(stars);
      window.display();

   }

}

fallahn

  • Hero Member
  • *****
  • Posts: 507
  • Buns.
    • View Profile
    • Trederia
Re: Image of Sprite Skipping on Screen
« Reply #9 on: February 16, 2018, 08:58:04 am »

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #10 on: February 16, 2018, 04:19:00 pm »
As I stated in most of my posts above, I've tried that along with every other combination of suggestions for frame rate issues like this that I could find. Thank you for the suggestion, though. Anymore ideas anyone? Am I just SOL on using SFML?

Paul

  • Jr. Member
  • **
  • Posts: 78
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #11 on: February 16, 2018, 09:57:46 pm »
@Kondie

I'm not sure if Pioneers game have smooth scrolling or sprite movement. Don't take it as benchmark.

I have similar problems with my projects, sometimes when I run exe there is really bad tearing without any reason. But mostly it's ok (AMD RX480).

I sent you PM, if you can test it. I'm just curious.

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #12 on: February 16, 2018, 10:05:24 pm »
I appreciate the attempt to help, but I'd rather not run a random exe that has been sent to me. If you provide the source for the "smooth_test" executable I'd be more than happy to run it.

Paul

  • Jr. Member
  • **
  • Posts: 78
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #13 on: February 16, 2018, 10:14:24 pm »
Ok, no problem. Forget about it because it's not C/C++ language (I'm using Pascal bindings). I can give you the source codes but without compilation you can't test it :)

Kondie

  • Newbie
  • *
  • Posts: 14
    • View Profile
Re: Image of Sprite Skipping on Screen
« Reply #14 on: February 16, 2018, 10:34:11 pm »
Alright, well thanks anyways. If anyone has ideas, I'm more than willing to try them. I've spent a good portion of time learning SFML. I have a long history with C++, and a brief history with OpenGL. This is my ideal framework to develop a game with from all the research I've done, so I'm pretty desperate here.