5

I need to create a transparent bitmap using Direct2D and draw, by using my device context, on it.

ID2D1DeviceContext1* d2dContext = ...
ID2D1Bitmap* pBitmap;

d2dContext->CreateBitmap(
    bitmapSize,
    nullptr,
    0,
    D2D1::BitmapProperties1(
        D2D1_BITMAP_OPTIONS_TARGET,
        D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpiX, dpiY),
    &pBitmap);

d2dContext->BeginDraw();
d2dContext->SetTarget(pBitmap);
d2dContext->Clear(D2D1::ColorF(0, 0));
d2dContext->DrawLine(...);
hr = d2dContext->EndDraw();

Unfortunately I am not able to create any transparent bitmaps. I tried with several pixel format combinations, including D2D1_ALPHA_MODE_STRAIGHT, but without succeeding.

Is there any solution?

Nick
  • 10,309
  • 21
  • 97
  • 201
  • How do you know that the image is not transparent? – Nico Schertler Oct 06 '16 at 23:51
  • @NicoSchertler Because I draw the background of my render target before creating the bitmap. And only after I draw this new bitmap over everything else, without clearing the render target. And I can see that the new bitmap covers everything below. – Nick Oct 07 '16 at 06:51
  • Then maybe it has something to do with how you draw it. Is alpha-blending enabled? Can you draw transparent bitmaps in general? – Nico Schertler Oct 07 '16 at 12:05
  • @NicoSchertler I draw the bitmap I by using the `DrawBitmap` method of my `ID2D1DeviceContext1`. The procedure is: 1) I draw several shapes on my target 2) I change the target to the bitmap (created with alpha mode) 3) I draw several shapes on the bitmap 4) I change the target to the original one 5) I draw the bitmap How can I enable alpha blending? No I can't draw transparent bitmaps in general (please be more specific). – Nick Oct 07 '16 at 13:08
  • I just know that you have to specify blending explicitly in D3D. Not sure how it is in D2D. The `DrawBitmap` method has an opacity parameter. Try to reduce opacity and see if the result changes. – Nico Schertler Oct 07 '16 at 15:59

2 Answers2

2

Good news Nick: You are creating transparent bitmaps, however the reason why you are not seeing your expected results has to do with window creation. Kenny Kerr demonstrated proper layered window creation with Direct2D back in 2009 here.

Since then much has changed with respect to windows rendering, with Win8 and Win10 using a composition engine, and allowing developers access to the DirectComposition API. As a result, Kenny Kerr provided an updated article in 2014 on the topic.

My recent projects required Win7 support, so I personally stick with pure Direct2D.

EDIT: And of course ensure your render target is properly created. Hope this helps.

Jeff
  • 2,495
  • 18
  • 38
0

Here is what I do in Sciter when I need to create cached rendering (bitmap) :

ID2D1RenderTarget* src = ...
d2d::asset<ID2D1BitmapRenderTarget> dst = nullptr;

// creating temp surface - compatible render target:
src->CreateCompatibleRenderTarget(sz,dst.target());

dst->BeginDraw();
dst->Clear(init_color);

... drawing on that temp surface ...
dst->EndDraw();

d2d::asset<ID2D1Bitmap> dst_bmp;
hr = dst->GetBitmap(il->d2d_bmp.target());

return dst_bmp;

This method delegates bitmap creation to the ID2D1RenderTarget and so that bitmap will always be compatible with source. The code is used with transparent init_color's mostly.

I wouldn't use SetTarget() as it is not clear what it does with clips, etc.

c-smile
  • 26,734
  • 7
  • 59
  • 86