title: DirectX alpha masking
body: <p>I'm working on a game using DirectX 9. Here's what I'm trying to do:</p>
  
  <p>After the scene is rendered, on top of it I want to render few sprites: a black cover on entire scene and a few sprites, which are masks showing where the cover should have holes. So far I tried messing with blend mode but with no luck. My code setting it up looks like this:</p>
  
  <pre><code>D3DD-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  D3DD-&gt;SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  </code></pre>
  
  <p>I guess the best way would be to multiply each sprites alpha, but according to <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb172508%28v=vs.85%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/windows/desktop/bb172508%28v=vs.85%29.aspx</a> no such mode is supported. Is There another way to do this?</p>
  
  <pre><code>edit
  </code></pre>
  
  <p>Following Nico Schertler's answer, here's the code I came up with:</p>
  
  <pre><code>LPDIRECT3DTEXTURE9      pRenderTexture;
  LPDIRECT3DSURFACE9      pRenderSurface,
                          pBackBuffer;
  
  // create texture
  D3DD-&gt;CreateTexture(1024,
                      1024,
                      1,
                      D3DUSAGE_RENDERTARGET,
                      D3DFMT_R5G6B5,
                      D3DPOOL_DEFAULT,
                      &amp;pRenderTexture,
                      NULL);
  
  pRenderTexture-&gt;GetSurfaceLevel(0,&amp;pRenderSurface);
  
  // store old render target - back buffer
  D3DD-&gt;GetRenderTarget(0,&amp;pBackBuffer);
  
  // set new render target - texture
  D3DD-&gt;SetRenderTarget(0,pRenderSurface);
  
  //clear texture to opaque black
  D3DD-&gt;Clear(0,
              NULL,
              D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
              D3DCOLOR_XRGB(0,0,0),
              32.0f,
              0);
  
  // set blending
  D3DD-&gt;SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
  D3DD-&gt;SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
  D3DD-&gt;SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ZERO);
  D3DD-&gt;SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_SRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
  
  //// now I render hole sprites the usual way
  
  // restore back buffe as render target
  D3DD-&gt;SetRenderTarget(0,pBackBuffer);
  
  // restore blending
  D3DD-&gt;SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_SRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
  D3DD-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
  
  ulong color = ulong(-1);
  Vertex2D v[4];
  
  v[0] = Vertex2D(0, 0, 0);
  v[1] = Vertex2D(1023, 0, 0);
  v[3] = Vertex2D(1023, 1023, 0);
  v[2] = Vertex2D(0, 1023, 0);
  
  D3DD-&gt;SetTexture(0, pRenderTexture);
  D3DD-&gt;SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
  D3DD-&gt;DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(Vertex2D));
  
  D3DD-&gt;SetTexture(0, NULL);
  
  // release used resources
  pRenderTexture-&gt;Release();
  pRenderSurface-&gt;Release();
  pBackBuffer-&gt;Release();
  </code></pre>
  
  <p>Unfortunatelly, the app crashes when restoring the old render target. Any advice?</p>