title: SDL2: How to deal with transparency?
body: <p>I'm experimenting SDL2 and I encounter a case I cannot manage correctly when I draw on an intermediate transparent texture.</p>
  
  <p>The images I'm attempting to blend:</p>
  
  <ol>
  <li><a href="https://i.stack.imgur.com/HWGmT.png" rel="nofollow noreferrer" title="img_w_A_channel">img_w_A_channel</a></li>
  <li>Some solid black color with an alpha of: <code>255</code>, <code>128</code>, or <code>0</code></li>
  <li><a href="https://i.imgur.com/VGWGAu5.png" rel="nofollow noreferrer" title="window bg">window bg</a> which is optional.</li>
  </ol>
  
  <p>So if I represent this as layers it's as follow</p>
  
  <pre><code>img_w_A_channel    img_w_A_channel    img_w_A_channel    img_w_A_channel
                      solid_texture    half_transparent   transparent_texture
     window               window            window            window
  </code></pre>
  
  <ul>
  <li>On the left, I render the image directly on the window.  </li>
  <li><code>solid_texture</code> means a black colored intermediate texture with <code>alpha=255</code> where I draw the image in then I draw the texture on the window.  </li>
  <li><code>half_transparent</code> means a black colored intermediate texture with <code>alpha=128</code> where I draw the image in then I draw the texture on the window.  </li>
  <li><code>transparent_texture</code>means a black colored intermediate texture with <code>alpha=0</code> where I draw the image in then I draw the texture on the window.  </li>
  </ul>
  
  <p>So think about the intermediate texture as a container I want to draw in. So as the window can have a background texture like here, <code>SDL_BLENDMODE_NONE</code> is not an option for the intermediate texture.  </p>
  
  <p>And the result is:</p>
  
  <p><a href="https://i.imgur.com/YtqI3Xc.png" rel="nofollow noreferrer"><img src="https://i.imgur.com/YtqI3Xc.png" alt="enter image description here"></a></p>
  
  <p>As you can see the first and second image (drawn on a solid intermediate texture are identical.
  The third and fourth image (drawn on semi-transparent and transparent intermediate texture) are not identical.  </p>
  
  <p>The problem is with the image on the right. I want the result to match the image on the left. i.e. being able to draw in a transparent container and get the same result as drawing directly on the window.</p>
  
  <p>My full test code is:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdbool.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;SDL2/SDL.h&gt;
  #include &lt;SDL2/SDL_image.h&gt;
  
  SDL_Window *window = NULL;
  SDL_Renderer *renderer = NULL;
  SDL_Texture *background = NULL;
  SDL_Texture *image = NULL;
  SDL_Surface* surface = NULL;
  
  SDL_Rect dst = {20, 20, 100, 100};
  
  #define SOLID 255
  #define HALF_TRANSPARENT 128
  #define TRANSPARENT 0
  
  SDL_Texture * renderImageInATexture(SDL_Texture *image, Uint8 transparency) {
  
      // Create an intermediate texture
      SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 200, 200);
      SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
      SDL_SetRenderTarget(renderer, texture);
  
      // Paint it
      SDL_SetRenderDrawColor(renderer, (Uint8) 0, (Uint8) 0, (Uint8) 0,(Uint8) transparency);
      SDL_RenderClear(renderer);
  
      // Render the image in intermediate texture
      SDL_SetRenderTarget(renderer, texture);
      SDL_RenderCopy( renderer, image, NULL, &amp;dst );
  
      SDL_SetRenderTarget(renderer, NULL);
      return texture;
  }
  
  int main(char *argc, char **argv) {
  
      SDL_Init( SDL_INIT_VIDEO);
  
       window = SDL_CreateWindow("Win", SDL_WINDOWPOS_UNDEFINED, 
                                 SDL_WINDOWPOS_UNDEFINED,
                             800, 200, SDL_WINDOW_SHOWN);
  
      // So we can save into pngs to check the value
      renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
  
  
      SDL_SetRenderTarget(renderer, NULL);
  
      // Fill the window with a texture for fun (doesn't change anything on the problem) can be removed ....
      surface = IMG_Load( "./carbone.png" );
      background = SDL_CreateTextureFromSurface( renderer, surface );
      SDL_FreeSurface( surface );
      // draw background in main display
      SDL_RenderCopy( renderer, background, NULL, NULL );
      // .... until here
  
      surface = IMG_Load( "./image.png" );
      image = SDL_CreateTextureFromSurface( renderer, surface );
      SDL_FreeSurface( surface );
      // draw imagein main display
      SDL_RenderCopy( renderer, image, NULL, &amp;dst );
  
      SDL_Texture *texture = renderImageInATexture(image, SOLID);
      // render intermediate texture in main display
      SDL_Rect dstTexture = {200, 0, 200, 200};
      SDL_RenderCopy( renderer, texture, NULL, &amp;dstTexture );
  
      SDL_Texture *texture2 = renderImageInATexture(image, HALF_TRANSPARENT);
      // render intermediate texture2 in main display
      SDL_Rect dstTexture2 = {400, 0, 200, 200};
      SDL_RenderCopy( renderer, texture2, NULL, &amp;dstTexture2 );
  
      SDL_Texture *texture3 = renderImageInATexture(image, TRANSPARENT);
      // render intermediate texture3 in main display
      SDL_Rect dstTexture3 = {600, 0, 200, 200};
      SDL_RenderCopy( renderer, texture3, NULL, &amp;dstTexture3 );
  
  
      SDL_RenderPresent(renderer);
  
      SDL_Delay(10000);
  
      SDL_DestroyTexture(image);
      SDL_DestroyTexture(bakcground); // only if you use a background
      SDL_DestroyRenderer(renderer);
      SDL_DestroyWindow(window);
      SDL_Quit();
  
  }
  </code></pre>
  
  <p>And to build it:  </p>
  
  <pre><code>cc main.c -lSDL2 -lSDL2_image
  </code></pre>
  
  <p>Built with SDL 2.0.8 but it doesn't matter.</p>
  
  <p>Any idea to fix this problem?</p>
  
  <p>** EDIT **</p>
  
  <p>So I modified my <code>renderImageInATexture()</code> function according to @aram's answer replacing:</p>
  
  <pre><code>SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
  </code></pre>
  
  <p>by:</p>
  
  <pre><code>    SDL_BlendMode mode = SDL_ComposeCustomBlendMode(1, 1, 
                                                      SDL_BLENDOPERATION_ADD,
                                                      1, 1, 
                                                      SDL_BLENDOPERATION_ADD);
      SDL_SetTextureBlendMode(texture, mode);
  </code></pre>
  
  <p>I also changed my initialization directly in my previous code above to be able to save my screen as proposed by @aram. But I had to use a <code>SDL_RENDERER_ACCELERATED</code> to prevent a <code>not supported operation</code>on <code>SDL_ComposeCustomBlendMode()</code> call. 
  Anyway, I get a <code>Surface doesn't have a colorkey</code> message. Is it a problem?</p>
  
  <p>But it seems it's still that <code>SDL_ComposeCustomBlendMode()</code> not the solution.<br>
  First I though that background image was not important because from my tests, I was getting the same result with or without it.<br>
  Unfortunately, if @aram's answer gives me the same result as when I render my image in a solid intermediate texture:
  <a href="https://i.stack.imgur.com/eApLo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eApLo.png" alt="enter image description here"></a></p>