[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Slow rendering speed - sprites



Much better, thanks.

The only a bit serious impact on performance is the Surface.convert
method on loaded image here. Good point.

Sprite image is of 310x360 px dimensions and with alpha layer. With
200 sprites optimized with .convert_alpha I get about 19 fps, with
plain .convert it raises upto 67 fps but transparency is lost which is
unacceptable.

In the meantime I've tested by the same example also another python
game library called Pyglet, where at 200 sprites framerate of 40 per
second was achieved (60 fps at 180 sprites). Good gain, however API
esp. OpenGL primitives drawing feels a bit unwieldy to me.


On Sun, Mar 8, 2015 at 1:06 AM, bw <stabbingfinger@xxxxxxxxx> wrote:
> Hi,
>
> See the attached for some tweaks.
>
> I bumped the number of sprites up to 200.
>
> When I used my own 100x100-pixels png that has an alpha layer I get a bit
> more than 100 fps. Alpha layers take extra CPU to render.
>
> When I use same-size filled rects of the same dimensions I get a little over
> 200 fps.
>
> When you load your image, you might get better performance if you convert()
> it or convert_alpha().
>
> Hope this helps.
>
> Gumm
>
>
> On 3/7/2015 1:37 PM, David Unric wrote:
>>
>> Hello,
>>
>> I'm considering a game framework for next more serious project. As I'm
>> Python/Ruby language agnostic, I did rewrote simple sprite benchmark
>> from Gosu to latest Pygame to do a performance comparison. You may
>> find the code bellow.
>>
>> I was very surprised Pygame version performs much more worse. To get
>> an idea, it was tested on the same machine, in the same environment,
>> linked against same SDL 1.2.15, run with Python 2.7.5. It starts
>> significantly drop framerate when sprites count gets over 20, whereas
>> Gosu version with Ruby 2.2.0 smoothly renders 200 sprites at 60 fps !
>> At about 100 sprites on the screen it becomes just a very slow slideshow.
>>
>> I don't know if something important performance-wise was missed.
>> Simple background is a static surface, display is also initialized
>> with native resolution 1376x768 in fullscreen,
>> LayeredDirty group with DirtySprites for better performance (Gosu
>> version also handles z-order of each sprite).
>>
>> Any idea what am I doing wrong ?
>>
>>
>> _______________________________________ snip
>> ____________________________________________________
>> import pygame, pygame.gfxdraw
>> from pygame import *
>> from random import randint
>>
>> def main():
>>      pygame.init()
>>
>>      video_info = pygame.display.Info()
>>      if video_info.current_w != -1 and video_info.current_h != -1:
>>          screen_width, screen_height = video_info.current_w,
>> video_info.current_h
>>      else:
>>          screen_width, screen_height = 800, 600
>>
>>      screen  = pygame.display.set_mode((screen_width, screen_height),
>>              FULLSCREEN | DOUBLEBUF | HWSURFACE)
>>      pygame.display.set_caption(__name__.upper())
>>
>>      background  = pygame.Surface(screen.get_size()).convert()
>>      background.fill((0, 0, 0))
>>      pygame.gfxdraw.filled_trigon(background,
>>              screen_width/10, screen_height/10,
>>              screen_width*9/10, screen_height*9/10,
>>              screen_width/2, screen_height*9/10,
>>              (210, 200, 77))
>>      sprites     = pygame.sprite.LayeredDirty()
>>      image       = pygame.image.load('my_sprite.png')
>>      for _ in xrange(30): XSprite(image, sprites)
>>      del image
>>
>>      # main game loop
>>      while True:
>>          for event in pygame.event.get():
>>              if event.type   == QUIT: return
>>              elif event.type == KEYDOWN and event.key == K_ESCAPE: return
>>
>>          screen.blit(background, (0, 0))
>>          sprites.update(screen)
>>          sprites.draw(screen)
>>          pygame.display.flip()
>>
>> class XSprite(pygame.sprite.DirtySprite):
>>      def __init__(self, image, *groups):
>>          super(XSprite, self).__init__(*groups)
>>          self.image  = image
>>          self.rect   = self.image.get_rect()
>>          self.rect.x = randint(0, 60)
>>          self.rect.y = randint(0, 40)
>>          self.dx, self.dy = randint(1, 16), randint(1, 16)
>>
>>      def update(self, screen, *args):
>>          screen_w, screen_h = screen.get_size()
>>          self.rect.x += self.dx
>>          self.rect.y += self.dy
>>          if (self.rect.x + self.dx  + self.rect.w > screen_w) or \
>>                  (self.rect.x + self.dx < 0):
>>              self.dx = -self.dx
>>          if (self.rect.y + self.dy + self.rect.h > screen_h) or \
>>                  (self.rect.y + self.dy < 0):
>>              self.dy = -self.dy
>>          self.rect.move_ip(self.dx, self.dy)
>>
>> if __name__ == '__main__':
>>      main()
>>
>> # vim: set ft=python ts=8 sts=4 sw=4 tw=79 fdm=indent:
>> _______________________________________ snip
>> ____________________________________________________
>
>