Re: [pygame] SDL vs. Pygame: Alpha Differences
On 12/24/06, Kamilche [EMAIL PROTECTED] wrote: The problem is this: Let's say the above worked. I still have to compose the desired sprites into a temporary buffer, apply the night with the special blit, then blit them out of that temporary buffer onto the final buffer. Those two extra blits are killing the speed. well even if you are seeing a huge frame rate hit when you are doing some effect every frame, you still might be able to get great run-time performance by caching the effect's intermediate steps in the app you are building how often does the night darken things enough that you can notice the change? To explain what I mean - If it took say 5 minutes to go from day to completely pitch black, that would mean that there would be more than a second between times where the result of the effect would change at all (5 min * 60 sec/min / 256 color values = 1.17 seconds/color value change. So maybe the darkened temp copies can be reused enough to make it run well? That special blit would still be nice, but it's not a showstopper, because there's several methods around it, including Brian's and a couple of others I've used. If there was a special blit that might be able to help, I would think it would be colorized blit - where as you blit the source color alpha is multiplied by a blending color alpha, and that product is what is used for blending to the dest. A colorized blit would probably be significantly slower than a normal 32-24 blit, but would still be much faster than making surface copies and modifiying them (FYI, openGL can do colorized blits with absolutely no speed penalty at all on the vast majority of hardware by setting the color of vertices)
Re: [pygame] SDL vs. Pygame: Alpha Differences
Brian Fisher wrote: On 12/24/06, Kamilche [EMAIL PROTECTED] wrote: That special blit would still be nice, but it's not a showstopper, because there's several methods around it, including Brian's and a couple of others I've used. If there was a special blit that might be able to help, I would think it would be colorized blit - where as you blit the source color alpha is multiplied by a blending color alpha, and that product is what is used for blending to the dest. A colorized blit would probably be significantly slower than a normal 32-24 blit, but would still be much faster than making surface copies and modifiying them (FYI, openGL can do colorized blits with absolutely no speed penalty at all on the vast majority of hardware by setting the color of vertices) I'm confused... Aren't you (Kamilche) using OpenGL? If so then such a colorized blit definitely works. Simply update a quad's color, which is multiplied with it's texture. If you want to also change between textures, you could instead fade between several effects like sunset/rise or stars by blending layers with an alpha quad color. Not sure how large your sky texture is though, so perhaps this would burn too much video card ram. -Jasper
Re: [pygame] SDL vs. Pygame: Alpha Differences
There is the BLEND_ADD blitter with pygame 1.8. This leaves the dest alpha alone, and just adds the color from the source image. These blitters aren't very optimized - but still fairly fast C. I wanted to modify the surface.fill method to also have these extra blend flags, but never got around to it. That would allow you to really quickly add/sub/mult different colors. Which is handy for lighting functions. It's much faster because you don't need to read two bits of data, just add the same color to each pixel. So it requires half the memory bandwidth. Maybe for the next release. On 12/24/06, Brian Fisher [EMAIL PROTECTED] wrote: On 12/24/06, Kamilche [EMAIL PROTECTED] wrote: The problem is this: Let's say the above worked. I still have to compose the desired sprites into a temporary buffer, apply the night with the special blit, then blit them out of that temporary buffer onto the final buffer. Those two extra blits are killing the speed. well even if you are seeing a huge frame rate hit when you are doing some effect every frame, you still might be able to get great run-time performance by caching the effect's intermediate steps in the app you are building how often does the night darken things enough that you can notice the change? To explain what I mean - If it took say 5 minutes to go from day to completely pitch black, that would mean that there would be more than a second between times where the result of the effect would change at all (5 min * 60 sec/min / 256 color values = 1.17 seconds/color value change. So maybe the darkened temp copies can be reused enough to make it run well? That special blit would still be nice, but it's not a showstopper, because there's several methods around it, including Brian's and a couple of others I've used. If there was a special blit that might be able to help, I would think it would be colorized blit - where as you blit the source color alpha is multiplied by a blending color alpha, and that product is what is used for blending to the dest. A colorized blit would probably be significantly slower than a normal 32-24 blit, but would still be much faster than making surface copies and modifiying them (FYI, openGL can do colorized blits with absolutely no speed penalty at all on the vast majority of hardware by setting the color of vertices)
Re: [pygame] SDL vs. Pygame: Alpha Differences
On Sat, 2006-12-23 at 12:10 -0800, Kamilche wrote: In the SDL documentation, it says under 'SDL_SetAlpha': When blitting RGBA-RGBA with SDL_SRCALPHA: The source is alpha-blended with the destination using the source alpha channel. The alpha channel in the destination surface is left untouched. SDL_SRCCOLORKEY is ignored. However, in Pygame, the alpha channel IS overwritten. Is there any technique to overcome this, to make it match what is written in the SDL documentation? Or is it a bug in SDL? Yes, SDL has a special blitter for blending alpha to alpha. You can work around this by disabling the SRC_ALPHA flag on the source. then it will work the same as SDL.
Re: [pygame] SDL vs. Pygame: Alpha Differences
Pete Shinners wrote: On Sat, 2006-12-23 at 12:10 -0800, Kamilche wrote: In the SDL documentation, it says under 'SDL_SetAlpha': When blitting RGBA-RGBA with SDL_SRCALPHA: The source is alpha-blended with the destination using the source alpha channel. The alpha channel in the destination surface is left untouched. SDL_SRCCOLORKEY is ignored. However, in Pygame, the alpha channel IS overwritten. Is there any technique to overcome this, to make it match what is written in the SDL documentation? Or is it a bug in SDL? Yes, SDL has a special blitter for blending alpha to alpha. You can work around this by disabling the SRC_ALPHA flag on the source. then it will work the same as SDL. I tried disabling the SRC_ALPHA on the source of a picture using two methods, and both of them still modified the alpha map of the original picture. Maybe you can tell me what I'm doing wrong? # Sample program - 'full.png' should be a full color pic # with an alpha channel. import pygame def main(): pygame.init() nightcolor = (0, 0, 0, 64) bg = pygame.display.set_mode((800, 600), pygame.SRCALPHA, 32) bg.fill((128, 128, 128, 255)) pic = pygame.image.load('full.png').convert_alpha() ''' # This blitted a black picture on top night = pygame.Surface(pic.get_size(), 0, 32) night.fill(nightcolor) night.set_alpha(None) pic.blit(night, (0, 0)) ''' # This blitted a nighttime overlay, but messed up # the alpha channel of the destination pic. night = pygame.Surface(pic.get_size(), 0, 24) night.fill(nightcolor[:3]) night.set_alpha(nightcolor[3]) pic.blit(night, (0, 0)) bg.blit(pic, (0, 0)) pygame.display.update() main()
Re: [pygame] SDL vs. Pygame: Alpha Differences
On 12/23/06, Pete Shinners [EMAIL PROTECTED] wrote: Yes, SDL has a special blitter for blending alpha to alpha. I assume you meant pygame has a special blitter - you mean pygame_AlphaBlit, right? You can work around this by disabling the SRC_ALPHA flag on the source. then it will work the same as SDL. I think you mean you work around this by clearing the SRC_ALPHA flag on the dest, not clearing it on the source the thing Kamilche wanted was to blit a 32 bit to a 32 bit with SRC_ALPHA on the source and go through to SDL, so that SDL would do the blending using the SRC_ALPHA, but not write to the dest alpha. If you turn off SRC_ALPHA on the source, then SDL doesn't alpha blend the color and instead copies pixels (including the alpha)... but from looking at pygame's surface.c it seems you can get at SDL's blit if the dest doesn't have SRC_ALPHA ... also, about the pygame special alpha blit... looking at the code in surface.c it looks like it doesn't do anything very useful - it's not a pixel copy (like SDL does with SRC_ALPHA off on the source), and it's not decaling, or doing a color blend that preserves dest alpha (like SDL does when the source doesn't have SRC_ALPHA), and it's not something that does proper compositing cause it gets the color saturation all wrong when the original dest alpha is not 0 or 255 (the easy way to see the code is wrong is that ALPHA_BLEND doesn't consider the original dest alpha when blending the color). so what is it that it is trying to be? Is it trying to composite correctly? (i.e so that blitting a-b then b-c is the same as b-c then a-c). Cause if that's what it's supposed to do, I would be delighted to help fix it... (it looks like it gets the final alpha value correct for compositing, it just needs to make the dest contribute to the final color proportional to the part of the final alpha value that came from the dest)
Re: [pygame] SDL vs. Pygame: Alpha Differences
On 12/23/06, Kamilche [EMAIL PROTECTED] wrote: I tried disabling the SRC_ALPHA on the source of a picture using two methods, and both of them still modified the alpha map of the original picture. Maybe you can tell me what I'm doing wrong? You need to have the source having SRC_ALPHA and the dest not having SRC_ALPHA to get the sdl overlay-style blending feature ... I dug up the thing you posted before (where you move the mouse around) and modified it to use that thing as the 3rd method (when you are in the lower third of the screen) and it seems to work. FYI, if you're curious why the dest flags matters, it's cause these lines in pygame's surface.c: if(dst-format-Amask (dst-flagsSDL_SRCALPHA) !(src-format-Amask !(src-flagsSDL_SRCALPHA)) (dst-format-BytesPerPixel == 2 || dst-format-BytesPerPixel==4)) { result = pygame_AlphaBlit(src, srcrect, dst, dstrect); } else if(the_args != 0) { result = pygame_Blit(src, srcrect, dst, dstrect, the_args); } else { result = SDL_BlitSurface(src, srcrect, dst, dstrect); } ... which actually makes a lot of sense now that I think about it, if pygame is trying to do proper image compositing - the dest flags is a good way of communicating whether you want the alpha modified import pygame WIDTH = 800 HEIGHT = 600 bg = None def Init(): global bg, font pygame.init() bg = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) font = pygame.font.Font(None, 18) def Run(): bgcolor1 = (255, 255, 255) bgcolor2 = (192, 192, 192) bgcolor3 = (128, 128, 128) nightcolor = [0, 0, 0, 192] # Create a bitmap - assume this is an expensive operation # taking a few seconds. bitmap = pygame.Surface((100, 100), pygame.SRCALPHA,32).convert_alpha() pygame.draw.circle(bitmap, (0, 255, 255), [50, 50], 50, 0) bitmappos = [0, 0] # Create the nighttime overlay night = pygame.Surface((WIDTH, HEIGHT/3), pygame.SRCALPHA,32).convert_alpha() night.fill(nightcolor) # Loop forever quitgame = 0 while not quitgame: pygame.event.pump() # Fill background bg.fill(bgcolor1, (0, 0, WIDTH, HEIGHT/3)) Print(bg, 'I want to darken the circle only. (Move the mouseleft and right to test.)', (0, 10)) Print(bg, 'Moving the mouse up here uses overlay method 1,which overlays the background and circle.', (0, 25)) Print(bg, 'This method is fast, but undesirable because itcolors the background.', (0, 40)) bg.fill(bgcolor2, (0, HEIGHT*1/3, WIDTH, HEIGHT/3)) Print(bg, Moving the mouse up here uses overlay method 2,which overlays the circle only, but also destroys the circle's alphachannel., (0, HEIGHT/3+10)) bg.fill(bgcolor3, (0, HEIGHT*2/3, WIDTH, HEIGHT/3)) Print(bg, 'Moving the mouse down uses an SDL feature where the color is alpha blended but dest alpha is preserved (basically an overlay or decal)', (0, HEIGHT*2/3+10)) Print(bg, To get at this feature, you need to let pygame know you don't want to composite the image, by turning SRC_ALPHA off on the dest, (0, HEIGHT*2/3+25)) # Render night (the part in question) if bitmappos[1] HEIGHT/3: # Method that colors it all include the background bg.blit(bitmap, (bitmappos[0]-50, bitmappos[1]-50)) bg.blit(night, (0, 0)) elif bitmappos[1] HEIGHT*2/3: # Method that colors only the circle but destroys its alphachannel w, h = bitmap.get_size() temp = pygame.Surface((w, h), pygame.SRCALPHA,32).convert_alpha() temp.blit(bitmap, (0, 0)) temp.blit(night, (0, 0)) bg.blit(temp, (bitmappos[0]-50, bitmappos[1]-50)) else: # Method that uses sdl's overlay style blending feature w, h = bitmap.get_size() temp = pygame.Surface((w, h), pygame.SRCALPHA,32).convert_alpha() bitmap.set_alpha(None) temp.blit(bitmap, (0, 0)) bitmap.set_alpha(255) temp.set_alpha(None) temp.blit(night, (0,0)) temp.set_alpha(255) bg.blit(temp, (bitmappos[0]-50, bitmappos[1]-50)) pygame.display.update() # Look for quit for e in pygame.event.get(): if e.type in [pygame.QUIT, pygame.MOUSEBUTTONDOWN]: quitgame = 1 break elif e.type == pygame.KEYDOWN: if e.key == 27: quitgame = 1 break elif e.type == pygame.MOUSEMOTION: bitmappos = e.pos nightcolor[3] = e.pos[0]/float(WIDTH) * 255 night.fill(nightcolor) def Print(bg, text, loc): fontcolor = (0, 0, 0) pic = font.render(text, 1, fontcolor) bg.blit(pic, loc) def Terminate(): pygame.quit() def main(): Init() Run() Terminate() main()
Re: [pygame] SDL vs. Pygame: Alpha Differences
Hi, maybe I could put in a new blit mode for you before this release... if it can't be done already. Can you describe what you want? I'm still not clear on it. Do you want this? DR, DG, DB, DA = SR, SG, SB, DA On 12/24/06, Kamilche [EMAIL PROTECTED] wrote: Brian Fisher wrote: On 12/23/06, Kamilche [EMAIL PROTECTED] wrote: ... I dug up the thing you posted before (where you move the mouse around) and modified it to use that thing as the 3rd method (when you are in the lower third of the screen) and it seems to work. Thanks for modifying that example. I see this is a variant on the other technique that was posted, but involves a couple more blits to preserve the alpha. I was trying to avoid all these extra blits to preserve the alpha, as it slows down nighttime by quite a lot. I was hoping the new blit flags on Pygame 1.8 would help me here - that's why I was eager to try it out! But my initial testing came up with the same results - all those extra blits to not overwrite the destination alpha. Basically - I would dearly love a single blit from one picture to another, to NOT modify the destination alpha, without require extra blits or manipulation, but I guess that's not available. The speed hit on preserving that alpha is significant enough, I believe I will just have to let the nighttime modify the entire background, instead of only the landscaping. I did think of one technique not mentioned tho! One of my variants blitted the night to the entire screen, then used Numeric to strip out the pixels where it was equal to the nighttime color. Boy, that one was slower than my existing method! --Kamilche
Re: [pygame] SDL vs. Pygame: Alpha Differences
On 12/23/06, Kamilche [EMAIL PROTECTED] wrote: Thanks for modifying that example. I see this is a variant on the other technique that was posted, but involves a couple more blits to preserve the alpha. I was trying to avoid all these extra blits to preserve the alpha, as it slows down nighttime by quite a lot. I don't know how this relates to your older question about darkening, but this example does exactly what you asked for in the post that I was replying to. It shows how to use pygame to get SDL to blit exactly the way it is described in the SDL docs. The case I modified (case 3) does 3 things: 1. copy the source art to a temp (including the source's alpha) 2. blit to the temp, darkening the color without modifying the alpha of the dest (the temp) 3. blit the temp to the background I suppose if there was a colorized blit, you could do that in a single blit without using a temp, but isn't it what you were asking for? (in particular, there is no extra step to copy the original alpha back to the temp) Basically - I would dearly love a single blit from one picture to another, to NOT modify the destination alpha, without require extra blits or manipulation, but I guess that's not available. That's exactly what the example I sent did... In particular these lines do a blit from one picture to another, which darkens the color without modifying the destination alpha: dest.set_alpha(None) src.set_alpha(255) dest.blit(src, (0,0)) It's like what Pete was emailing about - turning off the SDL_SRCALPHA flag on the dest, so that the pygame code would call straight to SDL, and then SDL seems the SDL_SRCALPHA on the source so it knows to blend the colors but leave the alpha
Re: [pygame] SDL vs. Pygame: Alpha Differences
On 12/23/06, René Dudfield [EMAIL PROTECTED] wrote: maybe I could put in a new blit mode for you before this release... if it can't be done already. hey Rene, what you mentioned below can absolutely be done already, so I don't think a new blit is needed there. However I do think it would be nice to improve ALPHA_BLEND in pygame's own blit before release Do you want this? DR, DG, DB, DA = SR, SG, SB, DA This is exactly what pygame blit will do if: 1. SDL_SRCALPHA is on the source 2. SDL_SRCALPHA is NOT on the dest 3. the source alpha is 255 everywhere