5

我想将我的电影渲染软件从 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 绘图也可以正常工作。

4

2 回答 2

2

我有同样的问题。以下对我有用(您需要使用 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);
于 2011-06-14T23:12:12.630 回答
1

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

于 2012-02-22T17:57:11.477 回答