[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Fubared set_alpha()
Pete Shinners wrote:
looks good. now what is unfortunately causing you trouble is that the
blitting does try to blend, so if we blit this again you can see the
values will not match..
>>> s2.blit(s1, (0,0))
<rect(0, 0, 9, 18)>
>>> s1.get_at((7,7)), s2.get_at((7,7))
((128, 64, 32, 240), (127, 63, 31, 255))
this should be easy enough to solve by clearing the destination first.
What do you mean by "clearing the destination first"?
sure. the whole problem comes down to the fact that SDL support for
pixel alphas is pretty weak in my opinion.
Indeed; consider the face that the Surface constructor is called
SDL_CreateRGBSurface(), but there is no corresponding
"SDL_CreateRGBASurface()" to go with it. In fact, the only way I could
find to create a blank RGBA surface was to create a new surface with
pygame.Surface() and then call Surface.convert() and pass in the RGBA
surface I got back from the TTF function.
disables the SRCALPHA. the other problem is when blitting to a
destination with SRCALPHA, none of SDL's blitters set the destination
SRCALPHA (well, all except the one you've just pointed out). in this
case pygame hijacks the blit with it's own built-in blit functions that
actually do what you want. this is what has changed and is throwing off
your desired effect.
Hmm.. my reading of http://sdldoc.csn.ul.ie/sdlsetalpha.php makes it
sound like the SRCALPHA bit of the destination is irrelevant.
It looks to me like SRCALPHA flag of the source Surface is the only one
that matters when blitting.
So, unless I pass in an alpha value that is PyNone, SDL_SRCALPHA
automatically gets set for me.
"Fine", you say, "just pass in an alpha argument of None and the
flags will be left alone". Except that when the alpha argument is
None, the value passed to the underlying SDL_SetAlpha() is a default
of zero
ah, this is a potentially strange, but no one has been snubbed by it
before now. still, it seems it shouldn't effect anything in SDL since if
there is no SDL_SRCALPHA flag, SDL ignores all surface and pixel alpha
values. in your case, if the surface does have pixel alphas, then the
surface alpha is entirely ignored anyway. i'm trying to guess if this is
what is the real problem.
Yes, this was a little weird for me, too.
[...]
I just did some more testing. It looks like I made a mistake. I
thought that the SRCALPHA on the _source_ image was what mattered. But,
after playing with it, I need to clear the "SRCALPHA" flag on BOTH
_source_ and the _destination_ image before doing the blit.
That is, using standard PyGame 1.5.5, without that patch I posted, I
can get my RGBA->RGBA blit to work correctly if I do this:
dest.set_alpha(None, 0) # Clear SRCALPHA flag on dest
source.set_alpha(None, 0) # Clear it on the source also
dest.blit(source, [0,0])
...and ta-da, things work.
I'm not sure what is up with this. I think it may be this snipped from
surface.c, in the C function PySurface_Blit():
if(dst->format->Amask && dst->flags&SDL_SRCALPHA &&
(dst->format->BytesPerPixel == 2 ||
dst->format->BytesPerPixel==4))
{
result = pygame_AlphaBlit(src, srcrect, dst, dstrect);
}
Is this why I need to clear the SRCALPHA bit on the _destination_
image? I don't know.
But, in any event, it looks like reverting out that patch I posted is
the best course of action. I will let somebody more familiar with SDL
figure this out... right now, my code is working with standard PyGame,
and I have a GUI to build :)
And now in venting mode, it took me several hours to find and
correct this (highly frustrating and very well-hidden) bug.
...and so I apologize for this. :)
i've got this all fixed up in pygame cvs now (phew, first checkin in a
month)
Again, please revert that checkin until this problem has been more
fully analyzed. (Also, my test results from before must be ignored, as
I was clearing the SRCALPHA on my _destination_ surface without knowing it.)
My question is, with SDL, am I supposed to clear the SRCALPHA on the
destination surface, the source surface, or both? I was always under
the impression it had to be on the cleared on the source surface. And
my second question is, what does that translate into with PyGame?
Thank you for all your help.
--Derek