On Wed, 30 Jun 2004, Sami Hangaslammi wrote:
I was bored, so here. ;)
def shadeMapSurfArray( surface, shadeSurf, elevation=55.0, compensate=False ):
array = pygame.surfarray.array3d(surface)
shade = pygame.surfarray.array3d(shadeSurf).astype(N.Float64)
if compensate:
compensation = sin(elevation)
shade /= compensation
shade /= 255.0
# repeat the shade pattern as many times as needed
# to cover the whole surface
x,y = surface.get_size()
xx,yy = shadeSurf.get_size()
mx,my = (x+xx)//xx, (y+yy)//yy
shade = N.concatenate((shade,)*mx,0)
shade = N.concatenate((shade,)*my,1)
shade = shade[:x,:y,...]
array = array * shade
array = N.where(array > 255, 255, array).astype(N.Int0)
return pygame.surfarray.make_surface(array)
Probably someone more familiar with the surfarray can make it faster,
but should beat get_at/set_at at least.
Cool, thanks! This helped quite a bit, as I was fumbling around trying to
find a way to multiply 2 arrays of different sizes, and also didn't know
about N.where().
For 380x360 I got .35 seconds for a ~3.7x speed improvement.
For 1220x840 I got 1.30 seconds for a ~7.5x speed improvement.
For the next size up (~2000x2000) it appears to suck up memory/cpu and hang!
Not sure what's going on here. :-/
Let's see, 2000x2000*4/1024 = 15.6MB. -This requires changing the rest of the code to store shades as
(shade,shade,shade) instead of (shade,0,0)
Actually, you should be able to use just "shade", instead of backing it
into an array with 3 values. Numeric will automatically apply the value
in the "2D" array to each of the values in the "3D" array. If anything
this will help with the memory situation.