5

ムービー レンダリング ソフトウェアを 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 描画を使用しても問題なく動作します。

4

2 に答える 2

2

私も同じ問題を抱えていました。以下は私にとってはうまくいきました(D2D1_ALPHA_MODE_PREMULTIPLIEDではなく、D2D1_ALPHA_MODE_IGNOREを使用してレンダーターゲットを作成する必要があります)。

ID2D1HwndRenderTarget* pRenderTarget; // render target created sometime earlier

D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
    DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE);

ID2D1BitmapRenderTarget* pOffscreenRT = NULL;
pRenderTarget->CreateCompatibleRenderTarget(NULL, NULL, &pixelFormat,
    D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &pOffscreenRT);
于 2011-06-14T23:12:12.630 に答える
1

GDI を使用したレンダリングにはちょっとした秘密があります。それは常にアルファ チャネルを破壊します。それを使用して描画すると、その領域のアルファ値がゼロに設定されます。これは、アルファ チャネルやあらゆるタイプの合成で動作するように設計されていないためだと思われます。アルファチャンネルが存在しない画面やプリンターに直接レンダリングするように設計されています。

于 2012-02-22T17:57:11.477 に答える