Alpha Blitting behavior

I am wondering what the ‘correct’ behavior of alphablitting should be.

From the Docs:

RGBA->RGBA with SDL_SRCALPHA The source is alpha-blended with the
destination using the source alpha channel. The alpha channel in the
destination surface is left untouched. SDL_SRCCOLORKEY is ignored.

RGBA->RGBA without SDL_SRCALPHA The RGBA data is copied to the destination
surface. If SDL_SRCCOLORKEY is set, only the pixels not matching the
colorkey value are copied.

Note that RGBA->RGBA blits (with SDL_SRCALPHA set) keep the alpha of the
destination surface. This means that you cannot compose two arbitrary RGBA
surfaces this way and get the result you would expect from "overlaying"
them; the destination alpha will work as a mask.

The problem I see here, is that the when SDL_SRCALPHA is enabled, and you
alphablit to a 100% transparant surface, you get nothing.

What I’m trying to do is assemble several alpha images into a single alpha
image (IE, overlaying them to form one alpha image)

But the behavior of both of these blitting modes are useless to accomplish
this.

I’ve been having to blit everything directly to the SW_Surface Video mode to
get the intended effect, and it’s incredably slow.

If SDL_SRCALPHA isn’t set, then it replaces the graphical data, which is
also useless for what I’m trying to do, since it replaces it.

Blitting to a non-alpha surface achives the intended effect, however has the
negative problem of not being able to overlay that surface over something
else.

What we need is a alpha blending that blends the images, but the resulting
alpha is only when both pixels in the images are transparent.

So If you blend two images, any part that is Opaque in both images, the
source image replaces that pixel. If the pixel in the source is opaque, but
the pixel in the destination is transparent it replaces the pixel. If both
of the pixels are transparent, they are blended and the alpha value is
recalculated. If the src image pixel is completely transparent and the the
destination pixel is transparent, the image retains the destinations alpha
value. If both images have completely transparent pixels, the final image
will retain the alpha value._________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

The problem I see here, is that the when SDL_SRCALPHA is enabled, and you
alphablit to a 100% transparant surface, you get nothing.

What I’m trying to do is assemble several alpha images into a single alpha
image (IE, overlaying them to form one alpha image)

yes, this is a known problem (hence the note). To do a correct
RGBA->RGBA alpha blit (the Porter-Duff OVER operator) would require
several integer divisions per pixel. The way to do it is to use
premultiplied alpha instead, which probably won’t be hacked into the
current SDL 1.x line

I’ve been having to blit everything directly to the SW_Surface Video mode to
get the intended effect, and it’s incredably slow.

you are doing a read-modify-write cycle for each pixel. Try blitting
it to a software surface instead, and copy parts of that to the screen
(or specify SWSURFACE in SetVideoMode)

Hello,

I’m experimenting some crashes while blitting surfaces created with
SDL_SWSURFACE to the screen, when the src blt rect has width = 1. It happens
only fullscreen (SDL_FULLSCREEN|SDL_DOUBLEBUF), while it works flawlessly in
debug. RLE compression is completely orthogonal.
Is this “normal” behaviour? Or known bug?

Thanks—
Giovanni Bajo
Lead Programmer

Protonic Interactive
www.protonic.net

  • Black holes are generated when God divides by zero -

I’m experimenting some crashes while blitting surfaces created with
SDL_SWSURFACE to the screen, when the src blt rect has width = 1. It happens
only fullscreen (SDL_FULLSCREEN|SDL_DOUBLEBUF), while it works flawlessly in
debug. RLE compression is completely orthogonal.

can you produce the smallest possible program that shows the bug?

also please give us platform details, video target used etc

I’m experimenting some crashes while blitting surfaces created with
SDL_SWSURFACE to the screen, when the src blt rect has width = 1. It happens
only fullscreen (SDL_FULLSCREEN|SDL_DOUBLEBUF), while it works flawlessly in
debug. RLE compression is completely orthogonal.
Is this “normal” behaviour? Or known bug?

I forgot to mention that a related bug was fixed just before 1.2 was
released so make sure you have a recent SDL version

Mattias,

I’m experimenting some crashes while blitting surfaces created with
SDL_SWSURFACE to the screen, when the src blt rect has width =

  1. It happens

only fullscreen (SDL_FULLSCREEN|SDL_DOUBLEBUF), while it works
flawlessly in
debug. RLE compression is completely orthogonal.

can you produce the smallest possible program that shows the bug?
also please give us platform details, video target used etc

I’m very near to a deadline for this product using SDL, so I really don’t
have time right now to prepare a small repro.
We are working only under Windows.
Let me recall all the conditions:

  • The bug appears only on one computer, running Windows ME and a TNT2 card.

  • Bit depth is 8 bit. The crash happens whenever a blit occurs between a
    SWSURFACE and the screen. the SWSURFACE is obviously 8bit as well, and there
    is no color conversion map (the logical palette is the same for both the
    surface and the screen). ColorKey is on, RLE is orthogonal. Basically, it
    should go through Blit1to1Key() to perform the blits.

  • Since I cannot remote debug from that computer, and I don’t have any stack
    walker going on, and the bug occurs only in fullscreen, I’ve tried to
    generate some logs from within the SDL to see where it happens. It basically
    crashes inside SDL_LowerBlit(), just before do_blit() is called. I’m sure
    that memory is not corrupted (do_blit pointer is valid), but it never enters
    SDL_SoftBlit(). I’d say that the stack is corrupted since it cannot perform
    that call, but the product is very solid and stable apart this issue.

  • Since it was near to impossible to prevent 1-width blits from the product
    code within the deadline, I’ve modified directly SDL_LowerBlit(), making it
    skip all blits with that condition:

    if (srcrect && srcrect->w == 1)
    return 0;

I promise that I’ll try to setup a remote debugger and see why this happens,
but defintely not before the second week of July.

Thanks anyway—
Giovanni Bajo
Lead Programmer

Protonic Interactive
www.protonic.net

  • Black holes are generated when God divides by zero -

The problem I see here, is that the when SDL_SRCALPHA is enabled, and you
alphablit to a 100% transparant surface, you get nothing.

What I’m trying to do is assemble several alpha images into a single alpha
image (IE, overlaying them to form one alpha image)

yes, this is a known problem (hence the note). To do a correct
RGBA->RGBA alpha blit (the Porter-Duff OVER operator) would require
several integer divisions per pixel. The way to do it is to use
premultiplied alpha instead, which probably won’t be hacked into the
current SDL 1.x line

I’ve been having to blit everything directly to the SW_Surface Video mode
to

get the intended effect, and it’s incredably slow.

you are doing a read-modify-write cycle for each pixel. Try blitting
it to a software surface instead, and copy parts of that to the screen
(or specify SWSURFACE in SetVideoMode)

Well the problem is that if I do anything other than writing to the software
surface that is the final video output, I don’t get the intended effect

Basically it goes
SDL_BlitSurface(image, NULL , screen, &drect[0]);
several times
then flips. This is using a software video surface.
But I can’t get more than 5fps this way.

I’ve been telling the people who have been testing it to use the OpenGL mode
instead (which goes at 30fps at least, some people get like 200fps) unless
they have a software-openGL implementation (MESA/Microsoft Software modes.)
Which ends up being
0.1fps then.

What I’m trying to do is provide a “soft” mode that isn’t as slow as the
sofware OpenGL implemenations.

But I’ve been trying to basically emulate the drawing process that’s in
OpenGL in the software mode. There is no “3D” in the program, it’s just 2D
surfaces being overlaid.

I get the intended effect in OpenGL I use
GL_SRC_ALPHA (As/kA, As/kA, As/kA, As/kA) for source
GL_ONE_MINUS_SRC_ALPHA (1, 1, 1, 1 ) - (As/kA, As/kA, As/kA, As/kA) for
destination
with glBlendFunc_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com