Search code examples
directxdirect2d

How to set a outer geometry mask in d2d so d2d only draws outside that geometry


I am working on API which requires me set up a outer geometry mask on ID2D1Rendertarget such that any draw call after that only draws portion of drawings which lies outside this geometry.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd756675(v=vs.85).aspx explains how can we setup a inner geometry mask on ID2D1Rendertarget such that any draw call after that only draws portion of drawings which lies inside this geometry.I want to implement just opposite of that. Is this possible? Any help is deeply appreciated.


Solution

  • One way to do this is to subtract your geometry from a rectangle that fills the entire render target. Check out the MSDN page on combining geometries. I have a small code example below:

    ComPtr<ID2D1PathGeometry> invertedGeometry;
    ComPtr<ID2D1RectangleGeometry> rectangleGeometry;
    d2dFactory->CreateRectangleGeometry(
        { 0, 0, targetWidth, targetHeight }, 
        &rectangleGeometry
        );
    
    ComPtr<ID2D1GeometrySink> geometrySink;
    d2dFactory->CreatePathGeometry(&invertedGeometry);
    invertedGeometry->Open(&geometrySink);
    rectangleGeometry->CombineWithGeometry(
        pathGeometry.Get(), 
        D2D1_COMBINE_MODE_EXCLUDE, 
        D2D1::Matrix3x2F::Identity(), 
        geometrySink.Get()
        );
    geometrySink->Close();
    

    Use the inverted geometry as the geometric mask instead of the original path geometry.

    A second way to do this is to rasterize your geometry to a bitmap and use it as an opacity mask. You can flip the colors depending on whether or not you want the inside or outside to mask.