Re: [SPAM: 10.100] Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
I too think the "more processing time" inference might be right. Interestingly, the issue got fixed on one restart and came back with the next. Pygame doesnt stop suprising me :)
Re: [SPAM: 10.100] Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
One thing I noticed about your code is you're making your own rectangle. The draw function returns a rect so you should pass that. It's useful because the rect it returns is constrained by the screen so there's less to update. Plus you don't have to make as many rects. But that doesn't fix your problem. Here's just a list of observations I made while experimenting. I'm not sure what's causing this issue. It's weird because it goes in all directions. It seems to be affected by the time it has to compute. Eg. if you change fps down to 20 it goes away. And if you change it to 120 it gets terrible. Also the amount of clipping is proportional to the speed at which you move. More speed = more clipping. I'm not sure why flipping or increasing the size of the rect fixes the problem but it does. If you inflate your rect slightly it fixes it. But if you increase speed too much then it comes back. The final observation that I made is that's it's not possible to stop on a clipped rect. This makes me think this is a vsync issue. I'm pretty sure that pygame does not vsync unless it's in hardware accelerated fullscreen. So maybe the reason that flipping and bigger rects stop the issue is because they give the system a slight delay. I also managed to get two circles to draw and the effect goes away entirely. This might also have to do with a longer processing time. Here's modified code that allows you to try to "catch" the clipping in action (it's not observable). It also toggles from inflating to not if you uncomment the right part. This doesn't have two circles. import pygame w,h=500,500 fps=40 pygame.init() screen = pygame.display.set_mode([w, h]) color=pygame.Color("white") clock=pygame.time.Clock() radius=20 x,y=w/2,h dx = 10 r = pygame.Rect((0,0), (radius*2, radius*2)) r.center = (x, y) inflate = False def get_bbox(x,y): left = x - radius top = y - radius width = radius * 2 height = radius * 2 return pygame.Rect((left, top), (width, height)) while True: old_r=r y-=dx if y < 100: y = w #fps -= 5 #dx += 1 fps = 0 #inflate = not inflate if fps <= 0: fps = 40 pygame.time.wait(500) screen.fill(pygame.Color("black"),old_r) r = pygame.draw.circle(screen, color, (x, h-y), radius, 0) if inflate: r.inflate_ip(20,20) pygame.display.update([r,old_r]) clock.tick(fps) I'm really at a loss as to what this actually is, Jeffrey On Fri, Jun 13, 2014 at 7:41 PM, Greg Ewing wrote: > I just tried this on a Mac, and it works fine, > no flickering or tearing. > > The only thing I can think of is that, on your system, > display.update() is not waiting for vertical sync, > whereas display.flip() is. > > The pygame docs aren't very clear about whether it's > supposed to or not. They say that flip() does, and then > just say that update() is an "optimised version" of > flip(). > > This suggest to me that it should, and it does seem > to on my system, but maybe some implementations are > different. > > Maybe you could try passing a single rect to update() > that's the union of the old an new rects. While that > won't eliminate all possibility of tearing, it may > make it less likely. > > -- > Greg > > -- Jeffrey Kleykamp
Re: [SPAM: 10.100] Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
I just tried this on a Mac, and it works fine, no flickering or tearing. The only thing I can think of is that, on your system, display.update() is not waiting for vertical sync, whereas display.flip() is. The pygame docs aren't very clear about whether it's supposed to or not. They say that flip() does, and then just say that update() is an "optimised version" of flip(). This suggest to me that it should, and it does seem to on my system, but maybe some implementations are different. Maybe you could try passing a single rect to update() that's the union of the old an new rects. While that won't eliminate all possibility of tearing, it may make it less likely. -- Greg
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Oops. I spotted a couple things I changed to aid my experimentation, and did not revert. They do not affect the operation of the program, but I want to identify them as a red herring so you don't waste time wondering about the differences. The import Color and KEYDOWN. This had no impact on the behavior. The calls to get_bbox() are reversed in pygame.display.update(). This had no impact on the behavior either way. The changes I made that do impact the code are the lines that contain speedx. Cheers, Gumm On Fri, Jun 13, 2014 at 9:42 AM, B W wrote: > Try this. > > import pygame > from pygame import Color, KEYDOWN > > w,h=800,200 > fps=60 > pygame.init() > screen = pygame.display.set_mode([w, h]) > color=pygame.Color("white") > clock=pygame.time.Clock() > radius=20 > x,y=800,100 > speedx=-4 > def get_bbox(x,y): > left = x - radius + speedx > > top = y - radius > width = radius * 2 + abs(speedx) * 2 > > height = radius * 2 > return pygame.Rect((left, top), (width, height)) > > while True: > old_x=x > x+=speedx > > screen.fill(pygame.Color("black"),get_bbox(old_x,y)) > pygame.draw.circle(screen, color, (x, y), radius, 1) > get_bbox(x,y) > pygame.display.update([get_bbox(old_x,y),get_bbox(x,y)]) > clock.tick(fps) > > > > On Thu, Jun 12, 2014 at 7:32 PM, Abhas Bhattacharya < > abhasbhattachar...@gmail.com> wrote: > >> What is also quite surprising is that the circle gets cut off in the >> same direction in which it is moving. That makes me think it cant be a >> v-sync/screen-refresh issue. >> > >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Try this. import pygame from pygame import Color, KEYDOWN w,h=800,200 fps=60 pygame.init() screen = pygame.display.set_mode([w, h]) color=pygame.Color("white") clock=pygame.time.Clock() radius=20 x,y=800,100 speedx=-4 def get_bbox(x,y): left = x - radius + speedx top = y - radius width = radius * 2 + abs(speedx) * 2 height = radius * 2 return pygame.Rect((left, top), (width, height)) while True: old_x=x x+=speedx screen.fill(pygame.Color("black"),get_bbox(old_x,y)) pygame.draw.circle(screen, color, (x, y), radius, 1) get_bbox(x,y) pygame.display.update([get_bbox(old_x,y),get_bbox(x,y)]) clock.tick(fps) On Thu, Jun 12, 2014 at 7:32 PM, Abhas Bhattacharya < abhasbhattachar...@gmail.com> wrote: > What is also quite surprising is that the circle gets cut off in the > same direction in which it is moving. That makes me think it cant be a > v-sync/screen-refresh issue. >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
What is also quite surprising is that the circle gets cut off in the same direction in which it is moving. That makes me think it cant be a v-sync/screen-refresh issue.
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Using display.flip is slower since it updates all the screen. display.update updates only the area covered by the list of "dirty" rectangles. 2014-06-12 15:49 GMT+02:00 Christopher Night : > I get that you want to understand what's going on, but beyond that, is > there some problem with just using display.flip? > > > On Thu, Jun 12, 2014 at 3:31 AM, Abhas Bhattacharya < > abhasbhattachar...@gmail.com> wrote: > >> The following code draws a circle and moves it by 4px to left every step. >> >> Problem is that at about 60 fps or more, the circle flickers and >> sometimes looks cut off to me (approx. illustration - >> http://i.imgur.com/4nKzsCP.png). The flickering is not like a screen >> flicker, more like state switching between full circle and cut-off circle. >> This problems doesnt occur at all upto 45 fps, couldnt be reproduced by >> screen capture or pausing the game, as if the problem is only visible to >> the naked eye. >> >> Now, there could be two possibilities: >> >> * Screen is not updated over the required region. >> >> None of the update code depends on the fps, so the flicker should have >> been fps-independent. But, the problem disappears at 30/45 fps. But, >> surprisingly, it is also fixed if display.flip is used instead of update. >> >> * V-sync/monitor refresh problem >> >> Some other pygame flicker questions mentioned this problem. I thought >> software rendering doesnt have this problem, but not really sure. Also, why >> would display.flip fix this? >> >> Ver- 1.9.2 a0 >> >> import pygame >> w,h=800,200 >> fps=60 >> pygame.init() >> screen = pygame.display.set_mode([w, h]) >> color=pygame.Color("white") >> clock=pygame.time.Clock() >> radius=20 >> x,y=800,100 >> def get_bbox(x,y): >> left = x - radius >> top = y - radius >> width = radius * 2 >> height = radius * 2 >> return pygame.Rect((left, top), (width, height)) >> >> while True: >> old_x=x >> x-=4 >> screen.fill(pygame.Color("black"),get_bbox(old_x,y)) >> pygame.draw.circle(screen, color, (x, y), radius, 1) >> pygame.display.update([get_bbox(x,y),get_bbox(old_x,y)]) >> clock.tick(fps) >> > >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
I get that you want to understand what's going on, but beyond that, is there some problem with just using display.flip? On Thu, Jun 12, 2014 at 3:31 AM, Abhas Bhattacharya < abhasbhattachar...@gmail.com> wrote: > The following code draws a circle and moves it by 4px to left every step. > > Problem is that at about 60 fps or more, the circle flickers and sometimes > looks cut off to me (approx. illustration - http://i.imgur.com/4nKzsCP.png). > The flickering is not like a screen flicker, more like state switching > between full circle and cut-off circle. This problems doesnt occur at all > upto 45 fps, couldnt be reproduced by screen capture or pausing the game, > as if the problem is only visible to the naked eye. > > Now, there could be two possibilities: > > * Screen is not updated over the required region. > > None of the update code depends on the fps, so the flicker should have > been fps-independent. But, the problem disappears at 30/45 fps. But, > surprisingly, it is also fixed if display.flip is used instead of update. > > * V-sync/monitor refresh problem > > Some other pygame flicker questions mentioned this problem. I thought > software rendering doesnt have this problem, but not really sure. Also, why > would display.flip fix this? > > Ver- 1.9.2 a0 > > import pygame > w,h=800,200 > fps=60 > pygame.init() > screen = pygame.display.set_mode([w, h]) > color=pygame.Color("white") > clock=pygame.time.Clock() > radius=20 > x,y=800,100 > def get_bbox(x,y): > left = x - radius > top = y - radius > width = radius * 2 > height = radius * 2 > return pygame.Rect((left, top), (width, height)) > > while True: > old_x=x > x-=4 > screen.fill(pygame.Color("black"),get_bbox(old_x,y)) > pygame.draw.circle(screen, color, (x, y), radius, 1) > pygame.display.update([get_bbox(x,y),get_bbox(old_x,y)]) > clock.tick(fps) >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
I ran your code and clearly noticed the same problem. Also displayed the dirty rectangles and there's nothing wrong here. I tried with a Sprite/RenderUpdates approach so I can use the RenderUpdates.draw method and I observed the same result. I also agree that pygame should handle this stuff internally. This behavior really surprises me. I'll keep experimenting a bit 2014-06-12 14:16 GMT+02:00 Abhas Bhattacharya : > Also, just to mention again, screen,flip magically solves the problem, > which made me think that it was a incorrect screen update issue. But > the code seems pretty simple and couldnt really find any screen update > bug. >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Also, just to mention again, screen,flip magically solves the problem, which made me think that it was a incorrect screen update issue. But the code seems pretty simple and couldnt really find any screen update bug.
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Great article, lots of new stuff to consume. But coming to the problem, I've never really had such problems earlier. Were you able to re-create the situation or is it just me? I was under the impression that pygame handled all this stuff internally just fine.
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
Yes. The article seems long and detailed. V-sync isn't only an issue on 3D-Accelerated Graphics, it has been there since early TVs and throughout the entire 2D - Graphice - Era as well. In short, if you don't wait for the "gap" or until the monitor had time to draw the entire screen, it's possible that you push him the next image while he's in the middle of the last image, and therefore creating a break in animated sequences. Best wishes Daniel On Thu, Jun 12, 2014 at 11:05 AM, Radomir Dopieralski wrote: > On 06/12/2014 09:31 AM, Abhas Bhattacharya wrote: > > > Problem is that at about 60 fps or more, the circle flickers and > > sometimes looks cut off to me (approx. illustration - > > http://i.imgur.com/4nKzsCP.png). The flickering is not like a screen > > flicker, more like state switching between full circle and cut-off > > circle. This problems doesnt occur at all upto 45 fps, couldnt be > > reproduced by screen capture or pausing the game, as if the problem is > > only visible to the naked eye. > > Please read this article for at least a partial explanation: > http://paulbakaus.com/tutorials/performance/the-illusion-of-motion/ > > > -- > The Sheep >
Re: [pygame] Circle cut off at 60+fps, fixed by display.flip
On 06/12/2014 09:31 AM, Abhas Bhattacharya wrote: > Problem is that at about 60 fps or more, the circle flickers and > sometimes looks cut off to me (approx. illustration - > http://i.imgur.com/4nKzsCP.png). The flickering is not like a screen > flicker, more like state switching between full circle and cut-off > circle. This problems doesnt occur at all upto 45 fps, couldnt be > reproduced by screen capture or pausing the game, as if the problem is > only visible to the naked eye. Please read this article for at least a partial explanation: http://paulbakaus.com/tutorials/performance/the-illusion-of-motion/ -- The Sheep