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.


Messages - tisolo

Pages: [1]
1
General / Re: I'm losing my mind implementing a fixed frame rate.
« on: February 04, 2024, 05:07:15 pm »
Quote
It's important to realise that "position" is never aware of what the graphics are doing. It's the thing that is updated and should not affected by any of the "graphics effects", which is what interpolation is.

Makes complete sense to get rid of referencing the circles position in that case, thank you :)

Quote
Shouldn't the "within main loop" section be within the loop?

I was unsure how this fit this line within the example, as resetting the previousposition, along with the format, where its a function initialisation or something confused me.. I just followed a similar example I'd previously read, the Kairos Timestep example where:

       
        sf::Vector2f currentCirclePosition{ window.getSize() / 2u };
        sf::Vector2f previousCirclePosition = currentCirclePosition;
 

You still feel a little stutter on my t470s linux laptop but on my windows laptop with a dedicated graphics card, it seems smooth as butter, I can't see whether this is possible to fix further, seems like it should be doable for such a small example.

2
General / Re: I'm losing my mind implementing a fixed frame rate.
« on: February 04, 2024, 12:15:45 pm »
This makes way more sense, I had something similar with a Player class involved also originally but I've messed around since to this version - thank you for the explanation!

After implementing what I believe to be similar to how you are mentioning this should be done (I'll add it below without all the profiling this time), I still feel that the underlying issue is the time taken between loops really isn't consistent. There is a check for the first update which isn't the greatest solution to the initial values problem currently but it works, sorry about that.

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

int main() {
    sf::RenderWindow window(sf::VideoMode(1920, 1080), "SFML Test");

    float speed = 5.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;

    //within main loop    
    sf::Vector2f previousPosition;
    sf::Vector2f position = circle.getPosition();
    bool updated = false;

    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();
                }
            }
        }

        // update
        while (accumulator >= TIME_PER_FRAME) {
            previousPosition = position;
            position += (direction*speed);
            accumulator -= TIME_PER_FRAME;
            updated = true;
        }

        if (updated) {
            circle.setPosition(previousPosition + ((position - previousPosition) * (accumulator/TIME_PER_FRAME)));
        }

        //render
        window.clear();
        window.draw(circle);
        window.display();

    }
    return EXIT_SUCCESS;
}
 

I've graphed (there's a url of the graph image below) of the first few cycles of the example to try to explain what I mean as an 'alpha value vs while loop number' bar chart and 'rendering times vs loop number' bar chart.

https://imgur.com/a/vBEDtTj

There are moments in this graph that I expect it to act like all the time (101-111 as the loop number for example) as it's consistent in those cases but the rest seems really short and jumpy. These numbers seem to just come from the inconsistent rendering times - it really varies for just a circle.

Maybe I'm completely overlooking something, I thought about sleeping for the time of the rest of the frame but that still doesn't resolve the inconsistency of render time which after profiling that part, makes me think there is an issue there that I'm unsure how to fix.

Again, thanks so much for the response initially, that really helped a lot. :)

3
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]