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

Re: [pygame] OpenGL stretch of a pygame.Surface



I still don't understand what you are doing in the first place. Are you taking a bunch of frames of art and running them as a movie? Do you really have 60 frames of art per second? If not, then there's no reason to redraw everything each frame. Only redraw when something changes. Or, redraw only the part of the screen that changes. At least, as a rule, only transform an image ONCE. If you transform the same image more than once then you're wasting resources! It's much faster to save the transformed image and blit it onto the screen each time you use it. It's even faster to not redraw the screen if nothing changed.

I understand that each frame you're trying to draw is 640x480 and then you want to upscale that to your screen's resolution. How many frames in total are you trying to draw over how much time?? If the answer isn't 60 frames over 1 second then there's no reason to redo your transform and blit each frame!

Are they looping? If they are then save the transformed image for the next loop.

I hope that helps,
Jeffrey




On Tue, Jul 29, 2014 at 8:38 AM, sylvain.boussekey <sylvain.boussekey@xxxxxxxxxxxxxxx> wrote:
I tried that with almost no perf gain.
I managed to do it in opengl but perfs are poor... The only advantage is
that there is almost no fps differences when increasing resolution. But
still framerate is poor. Here is roughly what I do (without knowing what I
do really)e :

  def openglblit(self, surf):
    textureSurface = surf

    textureData = pygame.image.tostring(textureSurface, "RGBA", 1)

    width = textureSurface.get_width()
    height = textureSurface.get_height()

    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, textureData)

    glClear(GL_COLOR_BUFFER_BIT)

    glBindTexture(GL_TEXTURE_2D, texture)
    glBegin(GL_QUADS)
    glTexCoord2d(0,1)
    glVertex2d(-1,1)
    glTexCoord2d(0,0)
    glVertex2d(-1,-1)
    glTexCoord2d(1,0)
    glVertex2d(1,-1)
    glTexCoord2d(1,1)
    glVertex2d(1,1)

    glEnd()
    glFlush()

    glDeleteTextures(texture)

But it seems that the conversion between pygame surface and opengl tex is
slow.
Argh !! I will really need to go full opengl if I want better perfs... sad...


Le 2014-07-28 23:14, Noel Garwick a ÃcritÂ:
vertpingouin,

If you are doing that every frame as part of the sprites .draw or
.update method , its still possible the transform is what is taking up

CPU time. ÂYou may want to use something like this instead:

class MySpriteThing( pygame.sprite.Sprite):
  image = None
  def __init___( self ):

    .....
    if MySpriteThing.image is None:
      MySpriteThing.image = pygame.image.load( "foo.png" )
      size = MySpriteThing.image.get_size()
      new_width = size[0] * X_SCALE # where X_SCALE is the
ratio between RESOLUTION_X (the big resolution) and GRAPHICS_X (the
resolution the images were made at) ; ( 1920 / 640 )
      new_height = size[1] * Y_SCALE
      MySpriteThing..image = pygame.transform.scale(
self.image, ( new_width, new_height ) )Â

    self.image = MySpriteThing.image

........

# then, in your main loop, blit the sprites .image attribute to your

display surface

mySpriteGroup.draw( screen )

Âpygame.display.update()

On Mon, Jul 28, 2014 at 4:41 PM, vertpingouin
<sylvain.boussekey@vertpingouin.fr [3]> wrote:

to Sam :

Im using HWSURFACE flag but I got exatly the same framerate. The
ideal
would be to rewrite everything in openGL but I dont know it well...
yet.

to Noel:
On the topic of performing transform one time only, Im not sure

what
mean here. If I scale my surface one time, it gets, say, 1920x1080,
but
then blitting is done only of a 640x480 part of the surface... So
maybe
I misunderstood something here.

Im using this to transform :

pygame.transform.scale(self.native, (SCREENWIDTH, SCREENHEIGHT),
self.screen)

where native is the little one and screen the big one. I assume
that
self.native is scaled then blit onto self.screen...

I think this is the blitting that is slow because if I use a lesser
resolution for self.screen, I almost get back my precious frames
per
second.

It will be really cool to send my little native surface to my
graphic
card, then let it scale by itself. Dont know if its even possible.


Le lundi 28 juillet 2014 Ã 11:50 -0400, Noel Garwick a Ãcrit :

Right now you are blitting tiles to a 640x480 surface, and then
> performing a transform on the whole surface and then blitting it
to
> the display?
>
>
> If this is the case, then try to only perform the scale operation
when
> the resolution is changed (instead of once each frame) and see
how
> that works. ÂI know you mentioned that the full screen blit
operation
> seems to be the main bottleneck, but this should help too.
>
>
>
>
>
>
>
> On Mon, Jul 28, 2014 at 7:32 AM, Sam Bull <sam.hacking@xxxxxxxx
[1]>

> wrote:
> Â Â Â Â On lun, 2014-07-28 at 06:54 +0200, VertPingouin
wrote:
> Â Â Â Â > So I came up with the idea of an hardware opengl
texture
> Â Â Â Â stretching
> Â Â Â Â > instead of a dumb blit but I dont know how to

achieve it.
> Â Â Â Â >
> Â Â Â Â > Anyone has already done this ?
> Â Â Â Â >
>
>
> Â Â Â Â You would just need to code the graphics in OpenGL
without
> Â Â Â Â using
> Â Â Â Â pygame.Surface and pygame.draw. First though, check
you are
> Â Â Â Â using the
> Â Â Â Â HWSURFACE flag, if you are running fullscreen, its

possible
> Â Â Â Â this might
> Â Â Â Â provide the necessary speedup without going to
OpenGL.
>
> Â Â Â Â
http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode
[2]
>
>



Links:
------
[1] mailto:sam.hacking@xxxxxxxx
[2] http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode
[3] mailto:sylvain.boussekey@vertpingouin.fr




--

   Jeffrey Kleykamp