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

Re: [pygame] SDL vs. Pygame: Alpha Differences



On 12/23/06, Kamilche <kamilche@xxxxxxxxxxxx> 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->flags&SDL_SRCALPHA) &&
               !(src->format->Amask && !(src->flags&SDL_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()