c++sdl-2transparentalpharender-to-texture

Alpha channel have no effect when drawn to texture and pasted to window


Using SDL2, I want to draw some graphics on texture and paste it on window for speed enhancement. When I paste it I want my alpha channel preserved.

This code is supposed to show a white rotating transparent rectangle.

But it shows opaque white rectangle.

How can I get a transparent white rectangle?

#ifdef __linux__
#include <SDL2/SDL.h>
#elif defined(_WIN32)
#include <SDL.h>
#endif

const int WIN_WIDTH = 640;
const int WIN_HEIGHT = 480;

int main(int argc, char **argv){
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
        std::cerr << "SDL_Init failed: " << SDL_GetError() << "\n";
        return 1;
    }
    SDL_Window *win = SDL_CreateWindow("Rendering to a texture!", SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);

    SDL_Renderer *renderer = SDL_CreateRenderer(win, -1,
        SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);

    //Put your own bmp image here
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

    //Make a target texture to render too
    SDL_Texture *texTarget = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
        SDL_TEXTUREACCESS_TARGET, WIN_WIDTH, WIN_HEIGHT);
    
    //Now render to the texture
    SDL_SetRenderTarget(renderer, texTarget);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 100);
    SDL_RenderClear(renderer);
    //Detach the texture
    SDL_SetRenderTarget(renderer, NULL);
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 0);
    SDL_RenderClear(renderer);

    //Now render the texture target to our screen, but upside down
    for(int i=0; i<255; i++) {
        SDL_RenderClear(renderer);
        SDL_RenderCopyEx(renderer, texTarget, NULL, NULL, i, NULL, SDL_FLIP_VERTICAL);
        SDL_RenderPresent(renderer);

        SDL_Delay(10);
    }

    SDL_DestroyTexture(texTarget);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(win);
    SDL_Quit();
    return 0;
}

Solution

  • Use SDL_SetTextureBlendMode on the texture, not SDL_SetRenderDrawBlendMode.

    SDL_SetTextureBlendMode(texTarget, SDL_BLENDMODE_BLEND);
    

    The wiki for SDL_SetRenderDrawBlendMode says:

    Set the blend mode used for drawing operations (Fill and Line).

    Drawing operations are SDL_RenderDrawLine and such.

    On the other hand, SDL_RenderCopy says:

    The texture is blended with the destination based on its blend mode set with SDL_SetTextureBlendMode().