Re: [pygame] OpenGL stretch of a pygame.Surface
right. Before you blit. My bad. On Mon, Aug 4, 2014 at 6:03 PM, Greg Ewing wrote: > Berlioz Silver wrote: > >> You want pixels2d, which gives you a variable which _references_ the data. >> > > Yes, sorry, I got it the wrong way round. You need to start > with a normal surface that you can blit into, and then use > pixels2d to create a numpy view of it that you can pass > directly to OpenGL. > > While the reference is still there, the surface is locked (otherwise you >> could change the data mid-blit, which would be bad). Instead, you should >> use: >> >> del (variable with pixels2d in it) >> >> right before you pass it off to GL or pygame. >> > > I think you mean *after* passing it to GL, don't you? > > -- > Greg >
Re: [pygame] OpenGL stretch of a pygame.Surface
Berlioz Silver wrote: You want pixels2d, which gives you a variable which _references_ the data. Yes, sorry, I got it the wrong way round. You need to start with a normal surface that you can blit into, and then use pixels2d to create a numpy view of it that you can pass directly to OpenGL. While the reference is still there, the surface is locked (otherwise you could change the data mid-blit, which would be bad). Instead, you should use: del (variable with pixels2d in it) right before you pass it off to GL or pygame. I think you mean *after* passing it to GL, don't you? -- Greg
Re: [pygame] OpenGL stretch of a pygame.Surface
Just a warning, glBegin(), glEnd() is deprecated, and so you know it's an old tutorial. Have you tried SFML's python binding? It's a bit like Pygame, and abstracts the OpenGL functions for you. On Tue, Jul 29, 2014 at 7:38 AM, sylvain.boussekey < sylvain.bousse...@vertpingouin.fr> 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 >> 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 >> [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 thi
Re: [pygame] OpenGL stretch of a pygame.Surface
You want pixels2d, which gives you a variable which _references_ the data. While the reference is still there, the surface is locked (otherwise you could change the data mid-blit, which would be bad). Instead, you should use: del (variable with pixels2d in it) right before you pass it off to GL or pygame. Also, how are you setting up opengl? I haven't gotten that working (hence why I've looked into surfarray). Also, if you are dropping to a reasonably moniterable framerate (~120 or so and below) you can check to see what is taking too long. Simply separate your commands with calls to time.time() and check at the end. you can print out the time required (possibly on keypress?) and it'll show you what is taking so long: firstTime = time.time() (create texture) aCheckpoint = time.time() (draw your sprites) bCheckpoint = time.time() (scale) cCheckpoint = time.time() print firstTime, aCheckpoint - firstTime, bCheckpoint - aCheckpoint - firstTime [etc] This'll give you the time used (in milliseconds) for each step of the frame. While I have my own suspicions of what is taking so long, timing it will show us for certain. On Wed, Jul 30, 2014 at 9:35 PM, VertPingouin < sylvain.bousse...@vertpingouin.fr> wrote: > Ok I now create my texture once. > > I'm having some issues with this > > > You're creating an extra copy of the texture data here. > > To avoid that, you could use surfarray to create a surface > > backed by a numpy array, do your drawing into that, and > > then pass the numpy array directly to glTexImage2D. > > As I understand it, you suggest a surface with a surfarray.pixel2d bound > to it. But I can't blit on such surface beacause it's locked. Did you > mean drawing directly in surfarray or just create and update a > surfarray.2darray which involve to do a copy of the native screen also ? > > > Thanks for all your advises everyone. > > > Le mercredi 30 juillet 2014 à 11:15 +1200, Greg Ewing a écrit : > > sylvain.boussekey wrote: > > > I managed to do it in opengl but perfs are poor. > > > > A few things to consider: > > > > > textureData = pygame.image.tostring(textureSurface, "RGBA", 1) > > > > * You're creating an extra copy of the texture data here. > > To avoid that, you could use surfarray to create a surface > > backed by a numpy array, do your drawing into that, and > > then pass the numpy array directly to glTexImage2D. > > > > > 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) > > > > * You're creating a new OpenGL texture for each frame and > > then discarding it. Try making these calls just once > > at the beginning and re-using the texture. > > > > * You're using a non-power-of-2 texture size. Not all > > OpenGL implementations support that; yours seemingly does, > > but it might be less efficient than a power-of-2 size. > > You could try allocating the next larger power-of-2 size and > > updating the part that you use with glTexSubImage2D(). > > > > >
Re: [pygame] OpenGL stretch of a pygame.Surface
Ok I now create my texture once. I'm having some issues with this > You're creating an extra copy of the texture data here. > To avoid that, you could use surfarray to create a surface > backed by a numpy array, do your drawing into that, and > then pass the numpy array directly to glTexImage2D. As I understand it, you suggest a surface with a surfarray.pixel2d bound to it. But I can't blit on such surface beacause it's locked. Did you mean drawing directly in surfarray or just create and update a surfarray.2darray which involve to do a copy of the native screen also ? Thanks for all your advises everyone. Le mercredi 30 juillet 2014 à 11:15 +1200, Greg Ewing a écrit : > sylvain.boussekey wrote: > > I managed to do it in opengl but perfs are poor. > > A few things to consider: > > > textureData = pygame.image.tostring(textureSurface, "RGBA", 1) > > * You're creating an extra copy of the texture data here. > To avoid that, you could use surfarray to create a surface > backed by a numpy array, do your drawing into that, and > then pass the numpy array directly to glTexImage2D. > > > 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) > > * You're creating a new OpenGL texture for each frame and > then discarding it. Try making these calls just once > at the beginning and re-using the texture. > > * You're using a non-power-of-2 texture size. Not all > OpenGL implementations support that; yours seemingly does, > but it might be less efficient than a power-of-2 size. > You could try allocating the next larger power-of-2 size and > updating the part that you use with glTexSubImage2D(). >
Re: [pygame] OpenGL stretch of a pygame.Surface
sylvain.boussekey wrote: > I managed to do it in opengl but perfs are poor. A few things to consider: > textureData = pygame.image.tostring(textureSurface, "RGBA", 1) * You're creating an extra copy of the texture data here. To avoid that, you could use surfarray to create a surface backed by a numpy array, do your drawing into that, and then pass the numpy array directly to glTexImage2D. > 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) * You're creating a new OpenGL texture for each frame and then discarding it. Try making these calls just once at the beginning and re-using the texture. * You're using a non-power-of-2 texture size. Not all OpenGL implementations support that; yours seemingly does, but it might be less efficient than a power-of-2 size. You could try allocating the next larger power-of-2 size and updating the part that you use with glTexSubImage2D(). -- Greg
Re: [pygame] OpenGL stretch of a pygame.Surface
Jeffrey Kleykamp wrote: On my not so fast computer, I acheive 400FPS, which is useless but a good indicator to know how many sprites I can draw simultaneously. Are you clearing and redrawing the whole screen each frame, or just drawing the areas where sprites have moved? If the latter, then some of the performance decrease could be due to the fact that you're now copying a whole screenful of data per frame. To avoid that with the OpenGL method, you would need to keep track of the changed areas and just copy them to the texture with glTexSubImage2D(). -- Greg
Re: [pygame] OpenGL stretch of a pygame.Surface
Well you might be able to scroll for some speedup. If everything is moving in the same general direction then scroll the biggest thing (like the background) and redraw everything else and the edges. On Tue, Jul 29, 2014 at 11:02 AM, sylvain.boussekey < sylvain.bousse...@vertpingouin.fr> wrote: > I have an asynchronous rendering function. > My game does logic updates at a fixed rate. > Rendering is done as fast as it can, possibly fps limited by a > pygame.time.Clock with interpolated position for sprites. > I'm actually drawing everything every frames because everthing is moving > constantly moving. > > On my not so fast computer, I acheive 400FPS, which is useless but a good > indicator to know how many sprites I can draw simultaneously. Pretty > confortable. > But if I want to go fullscreen in native resolution (to keep pixels art > pixelated !), I must resize and I drop below 60FPS. > > But maybe I don't need 60FPS in the first place... > > Le 2014-07-29 15:28, Jeffrey Kleykamp a écrit : > >> I still dont 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 theres 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 youre wasting resources! Its much faster to save >> >> the transformed image and blit it onto the screen each time you use >> it. Its even faster to not redraw the screen if nothing changed. >> >> I understand that each frame youre trying to draw is 640x480 and then >> you want to upscale that to your screens resolution. How many frames >> >> in total are you trying to draw over how much time?? If the answer >> isnt 60 frames over 1 second then theres 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 >> 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() >
Re: [pygame] OpenGL stretch of a pygame.Surface
I have an asynchronous rendering function. My game does logic updates at a fixed rate. Rendering is done as fast as it can, possibly fps limited by a pygame.time.Clock with interpolated position for sprites. I'm actually drawing everything every frames because everthing is moving constantly moving. On my not so fast computer, I acheive 400FPS, which is useless but a good indicator to know how many sprites I can draw simultaneously. Pretty confortable. But if I want to go fullscreen in native resolution (to keep pixels art pixelated !), I must resize and I drop below 60FPS. But maybe I don't need 60FPS in the first place... Le 2014-07-29 15:28, Jeffrey Kleykamp a écrit : I still dont 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 theres 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 youre wasting resources! Its much faster to save the transformed image and blit it onto the screen each time you use it. Its even faster to not redraw the screen if nothing changed. I understand that each frame youre trying to draw is 640x480 and then you want to upscale that to your screens resolution. How many frames in total are you trying to draw over how much time?? If the answer isnt 60 frames over 1 second then theres 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 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 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.scree
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.bousse...@vertpingouin.fr> 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 >> 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
Re: [pygame] OpenGL stretch of a pygame.Surface
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 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 > 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.hack...@sent.com [2] http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode [3] mailto:sylvain.bousse...@vertpingouin.fr
Re: [pygame] OpenGL stretch of a pygame.Surface
vertpingouin, If you are doing that every frame as part of the sprite's .draw or .update method , it's 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 sprite's .image attribute to your display surface mySpriteGroup.draw( screen ) pygame.display.update() On Mon, Jul 28, 2014 at 4:41 PM, vertpingouin < sylvain.bousse...@vertpingouin.fr> wrote: > to Sam : > I'm using HWSURFACE flag but I got exatly the same framerate. The ideal > would be to rewrite everything in openGL but I don't know it well... > yet. > > to Noel: > On the topic of performing transform one time only, I'm 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. > > I'm 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. Don't know if it's 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 > > 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 don't 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, it's possible > > this might > > provide the necessary speedup without going to OpenGL. > > > > > http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode > > > > > > >
Re: [pygame] OpenGL stretch of a pygame.Surface
to Sam : I'm using HWSURFACE flag but I got exatly the same framerate. The ideal would be to rewrite everything in openGL but I don't know it well... yet. to Noel: On the topic of performing transform one time only, I'm 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. I'm 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. Don't know if it's 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 > 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 don't 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, it's possible > this might > provide the necessary speedup without going to OpenGL. > > http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode > >
Re: [pygame] OpenGL stretch of a pygame.Surface
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 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 don't 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, it's possible this might > provide the necessary speedup without going to OpenGL. > > http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode >
Re: [pygame] OpenGL stretch of a pygame.Surface
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 don't 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, it's possible this might provide the necessary speedup without going to OpenGL. http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode signature.asc Description: This is a digitally signed message part
[pygame] OpenGL stretch of a pygame.Surface
Hi everyone, I try to make a little 2d engines for my needs. I use the gameobject library which bring me to a really really decent frame rate (between 400 and 2000 FPS depending on the computer). But I wanted to do some beautiful pixel art so every frame, I pygame.transform.scale my 640 x 480 display into my native resolution. Despite the fact I carefully have converted my surfaces to match each other, FPS is really slower (can't have constant 60FPS anymore !). After a few investigation, the transformation is slow but not as the blitting of an 1920x1080 surface. So I came up with the idea of an hardware opengl texture stretching instead of a dumb blit but I don't know how to achieve it. Anyone has already done this ?