locked
Direct2d: Drop shadow for renderTarget->DrawGeometry

    Question

  • Hi,

    I'm writing C++ application with manipulating different geometry objects using Direct2D api.

    I need to add drop shadows to draw some paths(renderTarget->DrawGeomerty(..)) like in Javascript canvas (offsetX,offsetY,color, radius).

    How could I do it?

    Thank you,

    Alex

    Thursday, October 27, 2011 6:52 PM

Answers

  • Hi Alex,

    FYI, in the new win8 D2D, drawing to a bitmap and applying effects is not so complex. Because in the new model we have a DeviceContext that you can set bitmaps as targets to. So in order to achieve what you want, you would (in pseudocode):

    - myDC->CreateEffect(SHADOW, &myShadowEffect);

    - CreateBitmap(&temp)

    - myDC->SetTarget(temp)

    - myDC->BeginDraw(); myDC->Clear(transparentColor); myDC->FillGeometry(...); myDC->EndDraw();

    - myDC->SetTarget(outputBitmap)

    - myShadowEffect->SetInput(0, temp)

    - myDC->BeginDraw(); myDC->DrawImage(myShadowEffect); myDC->EndDraw();

    If you take out the lines that would have to be there either way, the difference is really a few lines of code. Having a DC that you can tie bitmaps to as targets makes it easier to do these kinds of things relative to using the various RenderTarget objects that had inherent surfaces.

    Hope this helps

    Thursday, March 1, 2012 12:47 AM
  • Direct2D is a low level library and doesn't have high level concepts such as drop shadows.  As Jer suggests, D2D provides the tools that you can use to generate one yourself.  You can draw a non-blurred shadow by translating the path to an offset and rendering it twice: once in a shadow colour and once normally.  ID2D1Effects affect images, not geometries, so they can't be directly used to blur out the paths, but you could render it into a Bitmap and then apply a blur effect to it.

    --Rob

    Thursday, October 27, 2011 11:59 PM
    Owner

All replies

  • Unsure if there is a built in way...but D2D now supports pixel shaders for custom effects.  I would apply a blur/desaturate effect to create the drop shadow, then copy the original on top of it.

    There is an example of Custom Effects in D2D here - http://code.msdn.microsoft.com/windowsapps/Direct2D-Image-Effects-2979be08

    It's the "Lesson4" example.

     

    -Jer

    Thursday, October 27, 2011 9:28 PM
  • Thank you, Jer.

     

    I installed and ran at example you've mentioned. It's about using effects in context->DrawImage, which really has parameter for effects.

    But I need to apply effect to DrawGeometry (esp. path) which has no such parameter.

    I'm novice in d2d, so sorry if I'm saying something stupid.  

    And I also could not find pixel shaders in d2d anywhere.

     

    Thanks,

    Alex


    Alex Kravtchenko
    Thursday, October 27, 2011 11:47 PM
  • Direct2D is a low level library and doesn't have high level concepts such as drop shadows.  As Jer suggests, D2D provides the tools that you can use to generate one yourself.  You can draw a non-blurred shadow by translating the path to an offset and rendering it twice: once in a shadow colour and once normally.  ID2D1Effects affect images, not geometries, so they can't be directly used to blur out the paths, but you could render it into a Bitmap and then apply a blur effect to it.

    --Rob

    Thursday, October 27, 2011 11:59 PM
    Owner
  • Thank you, Rob.

    I suspected that it will be not easy :-(

    The only hope was that this procedure is kinda general (e.g. draw text in d2d has it, and canvas  too).

    I doubted that those operations  use so complex approach (draw on bitmap, then apply effect, and draw on context...)  and hoped that I just missed something.

    --Alex

     


    Alex Kravtchenko
    Friday, October 28, 2011 12:54 AM
  • Hi Alex,

    FYI, in the new win8 D2D, drawing to a bitmap and applying effects is not so complex. Because in the new model we have a DeviceContext that you can set bitmaps as targets to. So in order to achieve what you want, you would (in pseudocode):

    - myDC->CreateEffect(SHADOW, &myShadowEffect);

    - CreateBitmap(&temp)

    - myDC->SetTarget(temp)

    - myDC->BeginDraw(); myDC->Clear(transparentColor); myDC->FillGeometry(...); myDC->EndDraw();

    - myDC->SetTarget(outputBitmap)

    - myShadowEffect->SetInput(0, temp)

    - myDC->BeginDraw(); myDC->DrawImage(myShadowEffect); myDC->EndDraw();

    If you take out the lines that would have to be there either way, the difference is really a few lines of code. Having a DC that you can tie bitmaps to as targets makes it easier to do these kinds of things relative to using the various RenderTarget objects that had inherent surfaces.

    Hope this helps

    Thursday, March 1, 2012 12:47 AM