【问题标题】:GDI rendering to direct2D ID2D1BitmapRenderTarget is always transparentGDI 渲染到 direct2D ID2D1BitmapRenderTarget 始终是透明的
【发布时间】:2011-06-04 02:07:28
【问题描述】:

我想将我的电影渲染软件从 DirectDraw 移植到 Direct2D。由于兼容性问题,需要在图像之上进行 GDI 渲染。为了优化性能,我想实现某种后缓冲机制,但是 alpha 通道信息似乎有问题,所有 GDI 绘图都以某种方式透明

我为我的窗口句柄创建了一个 ID2D1HwndRenderTarget 并创建了一个 ID2D1Bitmap 来将图像复制到其中。位图的像素格式为DXGI_FORMAT_B8G8R8A8_UNORM,alpha模式为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 有透明背景。

为了优化性能,我想在“backbuffer”中进行 GDI 绘图,因此只需要在发生变化时进行。 否则我只能渲染缓存的位图。位图是空的和透明的,所以只有绘制的对象应该是可见的。

所以我创建了一个 CompatibleRenderTarget ID2D1BitmapRenderTarget,alpha 模式是 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 中不使用 alpha 通道,myBitmap 也没有 alpha 信息。

那么 alpha 信息从何而来?有人有想法吗?提前致谢!

顺便说一句,在 CompatibleRenderTarget 上使用 Direct2D 绘图也可以正常工作。

【问题讨论】:

    标签: transparency gdi direct2d rendertarget


    【解决方案1】:

    我遇到了同样的问题。以下对我有用(您需要使用 D2D1_ALPHA_MODE_IGNORE 创建渲染目标,而不是 D2D1_ALPHA_MODE_PREMULTIPLIED)。

    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);
    

    【讨论】:

      【解决方案2】:

      关于使用 GDI 渲染有一个肮脏的小秘密:它总是会破坏 Alpha 通道。您用它绘制的任何东西都会将该区域的 alpha 值设置为零。我怀疑这是因为它从未设计用于 Alpha 通道或任何类型的合成。它旨在直接渲染到不存在 Alpha 通道的屏幕和打印机。

      【讨论】:

        猜你喜欢
        • 2012-10-15
        • 2011-02-05
        • 2014-08-07
        • 1970-01-01
        • 1970-01-01
        • 2019-04-22
        • 2014-11-19
        • 2017-12-11
        • 1970-01-01
        相关资源
        最近更新 更多