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

Re: [pygame] Alpha Channel Speed Question



On 27 Nov 2006 at 16:48, Kamilche wrote:

> Lenard Lindstrom wrote:
> > On 22 Nov 2006 at 21:15, Kamilche wrote:
> > 
> >> I have a question - Do you know of a way to get method 3 as outlined 
> >> below to be faster? The necessity of doing all those extra blits to 
> >> preserve the alpha channel is really slowing things down.
> >>
[snip]
> > 
> Colorkeys are incompatible with per pixel alpha - set_alpha only works 
> on pictures that don't have per pixel alpha.
> 
Yes and no. Colorkey doesn't work on a surface with per pixel alpha. 
But a colorkey surface does alpha blit to a surface with per pixel 
alpha, preserving the destination surfaces alpha values. Colorkey is 
just fine if  the night overlay only darkens the bitmap.


import pygame

WIDTH = 800
HEIGHT = 200
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)
     nightcolor = (0, 0, 0, 255)
     nightcolor_firstalpha = 64

     # Create a bitmap - assume this is an expensive operation
     # taking a few seconds.
     bitmap = pygame.Surface((100, 100), pygame.SRCALPHA, 32)
     pygame.draw.circle(bitmap, (0, 255, 255), [50, 50], 50, 0)
     pygame.draw.circle(bitmap, (0, 0, 255), [50, 50], 25, 0)
     bitmappos = [0, 0]

     # Create bitmap's nighttime travelling overlay
     bm_alpha = pygame.surfarray.pixels_alpha(bitmap)
     mask = pygame.Surface(bitmap.get_size(), pygame.SRCALPHA, 32)
     mask.fill(nightcolor)
     pygame.surfarray.pixels_alpha(mask)[:, :] = bm_alpha
     del bm_alpha
     night = pygame.Surface(bitmap.get_size(), 0, 32)
     night.fill((255, 255, 255))
     night.blit(mask, (0,0))
     del mask
     night.set_alpha(nightcolor_firstalpha)
     night.set_colorkey((255, 255, 255))
     
     # Loop forever
     quitgame = 0
     while not quitgame:
         pygame.event.pump()

         # Fill background
         bg.fill(bgcolor1, (0, 0, WIDTH, HEIGHT))
         Print(bg, "The circle has per-bit alpha."
                   " It is darkened by alpha blitting"
                   " a black and white mask onto it."
                   " The mask is a black foreground", (0, 10))
         Print(bg, "circle whose alpha is controlled"
                   " by surface alpha. The white mask"
                   " background is made transparent"
                   " with a white colorkey. Colorkey", (0, 25))
         Print(bg, "preserves the per-pixel alpha"
                   " of the surface blitted to.", (0, 40))

         # Render night (the part in question)
         bg.blit(bitmap, (bitmappos[0]-50, bitmappos[1]-50))
         bg.blit(night, (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
                 night.set_alpha(e.pos[0]/float(WIDTH) * 255)

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

Lenard Lindstrom
<len-l@xxxxxxxxx>