DirectX9 AlphaBlend with multiple surfaces / textures

307 Views Asked by At

im currently writing a 2D window framework (gui engine). Every control (window, button, panels, ..) is painted on a seperate surface. These surfaces are merged together, after all controls in the tree are painted.

For example (window contains panel and button 3, panel contains button 1 and button 2):

  • Paint Window
    • Paint Panel
      • Paint Button 1
      • Merge Button 1 surface with Panel surface
      • Paint Button 2
      • Merge Button 2 surface with Panel surface
    • Paint Button 3
    • Merge Button 3 surface with Panel surface
  • Merge Panel surface with Window surface

Our problem is the correct alpha blend calculation while merging the surfaces. We tried different configurations, but the alpha values did behave "strange" for all of them. The biggest problem are alpha holes (fully transparent pixels, even if the top level surface (window) is nearly opaque).

Device->SetRenderState (D3DRS_ALPHABLENDENABLE,          1                   );
Device->SetRenderState (D3DRS_BLENDOP,                   D3DBLENDOP_ADD      );
Device->SetRenderState (D3DRS_SRCBLEND,                  D3DBLEND_SRCALPHA   );
Device->SetRenderState (D3DRS_DESTBLEND,                 D3DBLEND_INVSRCALPHA);

As a quick fix, we are currently using the following render states:

Device->SetRenderState (D3DRS_ALPHABLENDENABLE,          1                   );
Device->SetRenderState (D3DRS_BLENDOP,                   D3DBLENDOP_ADD      );
Device->SetRenderState (D3DRS_SEPARATEALPHABLENDENABLE,  1                   );
Device->SetRenderState (D3DRS_SRCBLEND,                  D3DBLEND_SRCALPHA   );
Device->SetRenderState (D3DRS_DESTBLEND,                 D3DBLEND_INVSRCALPHA);
Device->SetRenderState (D3DRS_SRCBLENDALPHA,             D3DBLEND_ONE        );
Device->SetRenderState (D3DRS_DESTBLENDALPHA,            D3DBLEND_ONE        );

But these are obviously incorrect, because the alpha values of two overlaying controls are added (making two 127 alpha controls fully opaque).

Is it possible to blend the surfaces like this:

A = AlphaValue * (ParentAlphaBlend / 255);

Best regards Zacherl

0

There are 0 best solutions below