Search code examples
c++sdlsdl-2

Animated transition/wipe using SDL2 and black/white mask?


I've been tearing my hair out over how to do this simple effect. I've got an image (see below), and when this image is used in a game, it produces a clockwise transition to black effect. I have been trying to recreate this effect in SDL(2) but to no avail. I know it's got something to do with masking but I've no idea how to do that in code.

The closest I could get was by using "SDL_SetColorKey" and incrementing the RGB values so it would not draw the "wiping" part of the animation.

Uint32 colorkey = SDL_MapRGBA(blitSurf->format, 
    0xFF - counter, 
    0xFF - counter, 
    0xFF - counter, 
    0
);
SDL_SetColorKey(blitSurf, SDL_TRUE, colorkey);

// Yes, I'm turning the surface into a texture every frame!
SDL_DestroyTexture(streamTexture);
streamTexture = SDL_CreateTextureFromSurface(RENDERER, blitSurf);

SDL_RenderCopy(RENDERER, streamTexture, NULL, NULL);

I've searched all over and am now just desperate for an answer for my own curiosity- and sanity! I guess this question isn't exactly specific to SDL; I just need to know how to think about this!


Solution

  • Arbitrarily came up with a solution. It's expensive, but works. By iterating through every pixel in the image and mapping the colour like so:

    int tempAlpha = (int)alpha + (speed * 5) - (int)color;
    int tempColor = (int)color - speed;
    *pixel = SDL_MapRGBA(fmt,
                    (Uint8)tempColor,
                    (Uint8)tempColor,
                    (Uint8)tempColor,
                    (Uint8)tempAlpha
                );
    

    Where alpha is the current alpha of the pixel, speed is the parameterised speed of the animation, and color is the current color of the pixel. fmt is the SDL_PixelFormat of the image. This is for fading to black, the following is for fading in from black:

    if ((255 - counter) > origColor)
                    continue;
    int tempAlpha = alpha - speed*5;
    *pixel = SDL_MapRGBA(fmt,
                    (Uint8)0,
                    (Uint8)0,
                    (Uint8)0,
                    (Uint8)tempAlpha
                );
    

    Where origColor is the color of the pixel in the original grayscale image.

    I made a quick API to do all of this, so feel free to check it out: https://github.com/Slynchy/SDL-AlphaMaskWipes