ムービー レンダリング ソフトウェアを DirectDraw から Direct2D に移植したいと考えています。互換性の問題のため、GDI レンダリングは画像の上で行う必要があります。パフォーマンスを最適化するために、何らかのバックバッファ メカニズムを実装したいと考えていますが、アルファ チャネル情報に問題があるようです。すべての GDI 描画は何らかの形で透明に見えます。
ウィンドウ ハンドル用のID2D1HwndRenderTargetと、イメージのコピー先の ID2D1Bitmap を作成します。ビットマップのピクセル形式はDXGI_FORMAT_B8G8R8A8_UNORMで、アルファ モードはD2D1_ALPHA_MODE_IGNOREです。HwdRenderTarget は GDI と互換性があるため、レンダリング関数は次のようになります。
HwdRenderTarget.BeginDraw;
HwdRenderTarget.DrawBitMap(myBitMap);
HwdRenderTarget.GetDC(dc);
... do GDI drawing here ...
HwdRenderTarget.ReleaseDC();
HwdRenderTarget.EndDraw;
このバージョンは問題なく動作します。GDI オブジェクトは単色で描画され、DrawTextEx-Text の背景は透明です。
パフォーマンスを最適化するために、「バックバッファー」で GDI 描画を実行したいので、何かが変更されたときにのみ実行する必要があります。それ以外の場合は、キャッシュされたビットマップをレンダリングできます。ビットマップは空で透明なので、描画されたオブジェクトだけが表示されます。
だから私は CompatibleRenderTarget ID2D1BitmapRenderTargetを作成し、アルファモードはD2D1_ALPHA_MODE_PREMULTIPLIEDです:
HwdRenderTarget.CreateCompatibleRenderTarget(nil, nil, nil, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, CompatibleRenderTarget);
次に、CompatibleRenderTarget で GDI レンダリングを行います。
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
私のレンダー関数は次のようになります。
HwdRenderTarget.BeginDraw;
HwdRenderTarget.DrawBitMap(myBitMap);
HwdRenderTarget.DrawBitmap(BackBuffer);
HwdRenderTarget.EndDraw;
問題は、すべての GDI 描画が何とか透明であり、透明度が下にある画像ピクセルの値に依存することです。暗いテキストは、暗い画像の背景では暗く表示されますが、白い背景では白くなります。ただし、アルファ チャネルは GDI では使用されず、myBitmap にもアルファ情報はありません。
では、アルファ情報はどこから来るのでしょうか? 誰にもアイデアがありますか?前もって感謝します!
ちなみに、CompatibleRenderTarget で Direct2D 描画を使用しても問題なく動作します。