megamarc / Tilengine

Free 2D graphics engine with raster effects for retro/classic style game development
https://www.tilengine.org
Mozilla Public License 2.0
802 stars 94 forks source link

144hz and VSync #61

Open turric4n opened 4 years ago

turric4n commented 4 years ago

Hi Marc,

Samples and main game loop are unplayable under 144Hz (aka 144 fps). VSync is not working here...

I don't know if caused by SDL2 or by Tilengine... How can be addressed?

megamarc commented 4 years ago

Hi! By default TLN_CreateWindow() sets vsync flag. If it's not working for you, you should modify Window.c and remove CWF_VSYNC from line 426: https://github.com/megamarc/Tilengine/blob/master/src/Window.c#L426

Then you'll have to do frame throttling on your game loop to adjust to your target frame rate, for example using SDL_Delay() + SDL_GetTicks() if you're using libSDL.

turric4n commented 4 years ago

Thanks Marc,

Please take a look here :

https://stackoverflow.com/questions/40854974/sdl-opengl-game-runs-too-fast-on-144hz-screen-cant-use-vsync

Today 144hz screens are common things under gaming scene, so, ther is my two cents :


int32_t tickInteval = 1000/FPS; // frequency in Hz to period in ms
uint32_t lastUpdateTime = 0;
int32_t deltaTime = 0;
while (running) { // running condition
    uint32_t currentTime = SDL_GetTicks();
    deltaTime = currentTime - lastUpdateTime;

    int32_t timeToSleep = tickInteval - deltaTime;
    if(timeToSleep > 0)
    {
        SDL_Delay(timeToSleep); // energy saving
    }

    update(deltaTime); // game logic
    lastUpdateTime = currentTime;
}
megamarc commented 4 years ago

Hi again, Your frame throttling should work, the basic idea is measuring the time it takes to process one frame (game logic, render, etc) and delay/sleep until the time to next frame at your target FPS. Why is vsync not working for you? I don't know as I don't have such 144 Hz monitor, mine is standard 60 Hz. But I guess is more related to G-sync and adaptive refresh rates than to a fixed 60/144 Hz issue. SDL2 just asks the underlying graphics API to enable vsync, but it's ultimately graphics driver and hardware to do the job.

turric4n commented 4 years ago

Hi again, Your frame throttling should work, the basic idea is measuring the time it takes to process one frame (game logic, render, etc) and delay/sleep until the time to next frame at your target FPS. Why is vsync not working for you? I don't know as I don't have such 144 Hz monitor, mine is standard 60 Hz. But I guess is more related to G-sync and adaptive refresh rates than to a fixed 60/144 Hz issue. SDL2 just asks the underlying graphics API to enable vsync, but it's ultimately graphics driver and hardware to do the job.

Thanks Mark, I will take a look over Nvidia low level things like GSync and how affect to SDL2 Window handling.

Because Tilengine demos are affected too, we need to think about maintaining compatibility with more screen refresh frequencies before making serious projects.

Greetings

megamarc commented 4 years ago

Maybe this article on how SDL2 handles adaptive sync may help: https://wiki.libsdl.org/SDL_GL_SetSwapInterval However this is not a tilengine issue, but a general windowing/vsync one on modern monitors.