-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pygame Clock inaccurate #304
Comments
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): I get those same jitters with your script on 64-bit Windows 7. Similar issues with my pygame script are driving me crazy too. Can't find any fix that works by Googling. |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): I've just found the answer! The pygame.display.flip() doco says "If your display mode is using the flags pygame.HWSURFACE and pygame.DOUBLEBUF, this will wait for a vertical retrace and swap the surfaces". This should stop the display juddering. But putting those flags in pygame.display.set_mode() does nothing on my system, which defaults to using the windib driver. After changing the driver to directx, those flags are honoured, and the rectangle moves smoothly. Add these lines at the start of your script:-
Add the set_mode flags:-
Remove this line:-
or change it to:-
|
Original comment by Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone): Hi Christopher, thanks a lot for the very interesting hint! I've tried out both versions: If I do the changes and remove the line, the program runs extremely fast If I do the changes and amend the line as described below, the program (Win 10 Home 64bit) Additionally, this work-around would not solve the issue, because I do I got soooo tired of this clock issue recently, so I coded my own My own clock is pretty much as accurate as Pyglet's, but has much less I still believe that |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): So my fix evidently doesn't work on all systems: on both of my PCs (Windows |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): With your clock module, the motion test still jitters on my system. Raising |
Original comment by Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone): Hi again, What exactly do you mean with "it jitters"? Is it like when limitting I did lots of testings on both my machines (fast desktop and rather slow The pyglet clock behaves much like my clock, on both systems: The rect So I am stuck with either pyglet's clock or mine, but both seem to have I have included some code in my clock to see whether there's any frame Also I think the problem is not related to the display refresh rate, Is there some way to monitor what exactly happens in Windows while my And what is your suggestion? How can I code an NES-like program with |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): Movement is mostly smooth, but with occasional jitters with no apparent pattern. Interestingly, if I just change the driver to directx with
I get tearing of the blue rectangle, implying that pygame.display.flip() is writing to the frame buffer at the same time as it is being read out to the display. This doesn't happen with the default windib driver, so there must be some double-buffering and/or locking to prevent it. So although your clock accurately controls the frequency of the pygame.display.flip() calls, asynchronous processing inside this function may result in the actual frame buffer update happening slightly earlier or later on some frames. I still believe, therefore, that a 100% accurate solution must entail sychronisation to vertical retrace. I'm surprised that the fix I provided with pygame.HWSURFACE, pygame.DOUBLEBUF, and the directx driver didn't work for you. Could you check with
that the display flags have been accepted - should be 0xc0000001. |
Original comment by Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone): Hey again! I don't believe it... it worked?! It gave me 0xc0000001L (don't know I think I must have done something wrong in the 1st attempt, sorry. My only concern: How can we check the refresh rate of any connected But it's awesome! That's the 1st time I see real smooth motion in Thanks man |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): Glad it's working now!
but on my system that gives 59 not 60 fps. |
Original comment by Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone): Did many testings and once again, new issues popped up: I did a blitting benchmark which stops the time it needs to blit 1000 It seems that using the HWSURFACE + DOUBLEBUF flags results in a much Using the ordinary "display = pygame.display.set_mode(RES, If I use a HWSURFACE + DOUBLEBUF, the exact same code takes 35 - 1215 (I did all these benchmarks using the directx SDL vid driver.) Alas, using .jpg's with a colorkey doesn't work either because pygame Conclusion: If I don't use VSYNC I can blit as much per pixel transparent png's as I If I use VSYNC, I get smooth animation, which is a must-have for such a It seems my journey goes on... dammit! Have you experienced the same This stuff is really making me mad again.... I think I should really |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): Actually, you can get smooth movement with just the DOUBLEBUF flag and not the HWSURFACE flag. You could try benchmarking your sprite blits without HWSURFACE to see if it makes a difference. |
Original comment by Christopher Jones (Bitbucket: shortcipher, GitHub: shortcipher): I have reproduced your excessive blit timings for png images with alpha transparency. Removing HWSURFACE didn't help. A workaround which gives acceptable blit timings is to blit the images on to a non-transparent background image and then blit that to the display, along these lines:-
|
Original comment by Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone): Yes, it seems that's the only solution on Windows to get smooth motion in Pygame (so far). I have found out that it's the pygame.DOUBLEBUF flag that sets VSYNC to True, HWSURFACE is not needed. But it only works if you set the directx driver first, so that really did the trick. But still, it's all very quirky on windows with pygame.. I would prefer a non-jittering, non-VSYNC, and fast standard setup for pygame on windows without having to care about display flags and all that stuff. Is there no way to get smooth motion using the std windib driver? |
I was tinkering with this today and observed the same thing as described above - it seems the only way to get completely smooth screen scrolling/movement in pygame 1.9 is to trick the system into enabling vsynch to control the framerate. All the other combinations I've tried using the pygame clock you get a slight hitching every second or so. However, this hacky method is no longer available in pygame 2 as the:
...line is no longer available in SDL2 (the only available videodriver option on windows is now 'windows' see here: https://wiki.libsdl.org/FAQUsingSDL). So in pygame 2 we now have the worst of both worlds, the same, seemingly pygame clock caused hitching, and the hacky way to bypass it by enabling vsynch is no longer available. |
@MyreMylar Did you disable the clock and use vsync only? |
@robertpfeiffer To get smooth scrolling in pygame 1 on windows? Sort of, from memory you need to stop limiting the frame rate with clock.tick(60) or whatever and let the v sync take care of doing that instead - but you don't need to remove the clock entirely. You can still run clock.tick() with no FPS limit argument and calculate the current framerate. |
Oh, yeah. Clock.tick(60) should not wait at all when vsync is on and the vsync frame rate is 50 Hz. But then the game only runs at 50 Hz instead of 60. On the other hand, if the screen refresh rate is 50 Hz and you have clock.tick(30) in there somewhere, you might get additional stutter from clock.tick. I think modern game engines solve this by only locking the frame rate at 144fps, and parameterising the update step with the elapsed time, or by having the game logic that needs a fixed time step run at 30/60FPS in its own thread with separate threads for UI/input, game logic, rendering, and networking. We could enable vsync again, but we'd need to keep it turned off by default for backwards compatibility. (Edit: Compatibility with old pygame games, not old hardware or SDL versions I mean) |
Yes that is the sensible way to go. Add a flag to set mode or something
like that that lets users turn v sync on and off with it turned off by
default.
That way it is consistent, functionality wise, with pygame 1, but with a
less confusing interface for turning v sync on or off.
…On Thu, 31 Oct 2019, 11:44 robertpfeiffer, ***@***.***> wrote:
Oh, yeah. Clock.tick(60) should not wait at all when vsync is on and the
vsync frame rate is 50 Hz. But then the game only runs at 50 Hz instead of
60. On the other hand, if the screen refresh rate is 50 Hz and you have
clock.tick(30) in there somewhere, you might get additional stutter from
clock.tick. I think modern game engines solve this by only locking the
frame rate at 144fps, and parameterising the update step with the elapsed
time, or by having the game logic that needs a fixed time step run at
30/60FPS in its own thread with separate threads for UI/input, game logic,
rendering, and networking.
We could enable vsync again, but we'd need to keep it turned off by
default for backwards compatibility.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#304?email_source=notifications&email_token=ADGDGGQCD23ENTCCKCADPE3QRLAJZA5CNFSM4JCRLNT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECXOEFY#issuecomment-548332055>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADGDGGSGBCZJBMWR22YSQ7LQRLAJZANCNFSM4JCRLNTQ>
.
|
Originally reported by: Don Polettone (Bitbucket: DonPolettone, GitHub: DonPolettone)
Hi all,
this is something that's been making me mad for months, if not years, and I hope someone can finally fix this:
The clock seems not doing well in pygame; animation stutters / jitters. First I thought I was doing something wrong, but when I digged deeper and broke it down to a test as simple as can be, I recognised it must be an issue with pygame itself.
Try THIS out:
Every few seconds, the rect stutters a bit. In a pixelated game, this looks awful. Especially when scrolling over pixely tilemaps. I tried it out on both Mac and Win - it is a general issue.
Can someone help/test/agree/decline/fix this ??
Related Docs: https://www.pygame.org/docs/ref/time.html#pygame.time.Clock
The text was updated successfully, but these errors were encountered: