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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - tisolo

Pages: [1]
1
General / I'm losing my mind implementing a fixed frame rate.
« on: February 03, 2024, 05:17:53 pm »
Hi all,

This problem has existed in my game across two laptops for months now but I've decided to tackle it. Over the past week I've tried to understand how to smooth the movement in my game as currently stutters are very prominent.

I've been browsing videos, tutorials. I've seen both the Fix Your Timestep! and DeWitters pages detailing how to make it independent of frame rate and interpolate for smoothness.

I have an example below with a circle and trying to start as simple as possible.

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

int main() {
    sf::RenderWindow window(sf::VideoMode(1920, 1080), "SFML Test");
    // window.setFramerateLimit(0);
    // window.setFramerateLimit(60);
    // window.setVerticalSyncEnabled(false);

    float speed = 1.0f;
    sf::Vector2f direction = sf::Vector2f(1.0f, 0);

    sf::CircleShape circle;
    circle.setRadius(20.0f);
    circle.setOrigin(circle.getRadius(), circle.getRadius());
    circle.setPosition(0, window.getSize().y/2);

    sf::Time TIME_PER_FRAME = sf::seconds( 1.0f / 60.0f );

    sf::Clock clock;
    sf::Time accumulator;
    sf::Time frameTime;

    sf::Clock profileClock;
    sf::Time eventsTime;
    std::vector<sf::Time> eventsTimes;
    sf::Time updateTime;
    std::vector<sf::Time> updateTimes;
    sf::Time renderTime;
    std::vector<sf::Time> renderTimes;

    while(window.isOpen()) {
        frameTime = clock.restart();
        accumulator += frameTime;

        // events
        sf::Event event;
        while(window.pollEvent(event)) {
            if (event.key.code == sf::Keyboard::Escape) {
                if (event.type == sf::Event::KeyPressed) {
                    window.close();
                }
            }
        }
        eventsTimes.push_back(profileClock.restart());

        // update
        while (accumulator >= TIME_PER_FRAME) {
            circle.move(direction*speed);
            accumulator -= TIME_PER_FRAME;
        }
        //interpolate
        circle.move(direction*speed*(accumulator/TIME_PER_FRAME));
        updateTimes.push_back(profileClock.restart());

        //render
        window.clear();
        window.draw(circle);
        window.display();
        renderTimes.push_back(profileClock.restart());
    }


    std::ofstream myfile;
    myfile.open ("time_logs.csv");
    for (sf::Time i : eventsTimes) {
        myfile << i.asMicroseconds() << ",";
    }
    myfile << std::endl;
    for (sf::Time i : updateTimes) {
        myfile << i.asMicroseconds() << ",";
    }
    myfile << std::endl;
    for (sf::Time i : renderTimes) {
        myfile << i.asMicroseconds() << ",";
    }
    myfile.close();
    return EXIT_SUCCESS;
}
 

Before this example I had two positions for the circle, one would be the actual position, the other would be interpolated based on this position and an alpha - calculated by the proportion of the timestep (accumulated_time / time_per_frame). In both scenarios, the issue I'm having is that, after profiling the time for events, updates and rendering, rendering time varied considerably. From what I can see, the frameTime varying - making the alpha for interpolation not consistent, could be the issue?

I looked into the differences with setting a framerate limit on the window and vsync, the former made the rendering time consistent, but it didn't affect the result.

I'm really struggling in just getting to a point of smooth movement and any direction is much appreciated, if you want any details in terms of hardware set up, if you'd guide me on how best to do this - I can.

Thank you!




Pages: [1]
anything