我想将我的电影渲染软件从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绘图也可以正常工作。
答案 0 :(得分: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);
答案 1 :(得分:1)
关于使用GDI渲染有一个肮脏的小秘密:它总是会破坏alpha通道。您使用它绘制的任何内容都会将该区域中的alpha值设置为零。我怀疑这是因为它从来没有设计用于alpha通道或任何类型的合成。它被设计为直接渲染到屏幕和不存在alpha通道的打印机。