I want to port my movie rendering software from DirectDraw to Direct2D. Because of compatibility issues, GDI rendering needs to be done on top of the image. To optimize performance I want to implement some kind of backbuffer mechanism, but there seems to be a problem with the alpha channel information, all GDI drawing appears somehow transparent.
I create a ID2D1HwndRenderTarget for my window handle and and a ID2D1Bitmap to copy the images to. The pixelformat of the bitmap is DXGI_FORMAT_B8G8R8A8_UNORM, the alpha mode is D2D1_ALPHA_MODE_IGNORE. The HwdRenderTarget is GDI compatible, so my render function looks somehow like this:
HwdRenderTarget.BeginDraw;
HwdRenderTarget.DrawBitMap(myBitMap);
HwdRenderTarget.GetDC(dc);
... do GDI drawing here ...
HwdRenderTarget.ReleaseDC();
HwdRenderTarget.EndDraw;
This version works perfectly fine: the GDI objects draw with solid colors, DrawTextEx-Text has a transparent background.
To optimize performance, I want to do the GDI drawing in a "backbuffer", so it only needs to be done when something changes. Otherwise I just can render the cached bitmap. The bitmap is empty and transparent, so only the objects drawn should be visible.
So I create a CompatibleRenderTarget ID2D1BitmapRenderTarget, alpha mode is D2D1_ALPHA_MODE_PREMULTIPLIED:
HwdRenderTarget.CreateCompatibleRenderTarget(nil, nil, nil, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, CompatibleRenderTarget);
Now I do the GDI rendering in the CompatibleRenderTarget:
CompatibleRenderTarget.BeginDraw;
if Supports(CompatibleRenderTarget, ID2D1GdiInteropRenderTarget, GdiInteropRenderTarget) then
begin
GdiInteropRenderTarget.GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, dc);
... do GDI drawing here ...
GdiInteropRenderTarget.ReleaseDC(fDstSize);
end;
GdiInteropRenderTarget := nil;
CompatibleRenderTarget.EndDraw;
CompatibleRenderTarget.GetBitmap(BackBuffer); // save the bitmap for drawing
and my render function now looks like this:
HwdRenderTarget.BeginDraw;
HwdRenderTarget.DrawBitMap(myBitMap);
HwdRenderTarget.DrawBitmap(BackBuffer);
HwdRenderTarget.EndDraw;
The problem now is, that all GDI drawing is somehow transparent and the degree of transparency depends on the values of the underlying image pixels. Dark text appears dark on a dark image background but becomes white on a white background. But alpha channel is not used in GDI and myBitmap also has no alpha information.
So where does the alpha information come from? Anyone has an idea? Thanks in advance!
Btw, using Direct2D drawing on the CompatibleRenderTarget also works fine.