[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()