2011-01-05 5 views
4

Я хочу перенести свое программное обеспечение для рендеринга фильмов с DirectDraw на Direct2D. Из-за проблем с совместимостью, GDI рендеринг должен быть сделан поверх изображения. Чтобы оптимизировать производительность, я хочу реализовать какой-то механизм backbuffer, но, похоже, проблема с информацией о альфа-канале, все рисунки GDI выглядят как-то прозрачно.GDI-рендеринг для direct2D ID2D1BitmapRenderTarget всегда прозрачен

создать ID2D1HwndRenderTarget для моей оконной ручки и и ID2D1Bitmap скопировать изображения в. Пиксельный формат растрового изображения равен DXGI_FORMAT_B8G8R8A8_UNORM, альфа-режим - D2D1_ALPHA_MODE_IGNORE. HwdRenderTarget ИРГФ совместимы, поэтому мой визуализации функция выглядит как-то так:

HwdRenderTarget.BeginDraw; 
HwdRenderTarget.DrawBitMap(myBitMap); 
HwdRenderTarget.GetDC(dc); 

... do GDI drawing here ... 

HwdRenderTarget.ReleaseDC(); 
HwdRenderTarget.EndDraw; 

Эта версия отлично работает: ИРГФ объекты рисовать сплошные цвета, DrawTextEx-Text имеет прозрачный фон.

Чтобы оптимизировать производительность, я хочу сделать рисунок GDI в «backbuffer», поэтому его нужно делать только тогда, когда что-то меняется. В противном случае я просто смогу отобразить кэшированное растровое изображение. Растровое изображение пусто и прозрачно, поэтому только видимые объекты должны быть видимыми.

Так я создаю, альфа-режим CompatibleRenderTarget ID2D1BitmapRenderTarget является D2D1_ALPHA_MODE_PREMULTIPLIED:

HwdRenderTarget.CreateCompatibleRenderTarget(nil, nil, nil, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, CompatibleRenderTarget); 

Теперь я ИРГФ рендеринга в CompatibleRenderTarget:

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 также не имеет альфа-информации.

Итак, откуда появилась альфа-информация? У кого-то есть идея? Заранее спасибо!

Btw, используя Direct2D рисунок на CompatibleRenderTarget также отлично работает.

ответ

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

Существует грязный маленький секрет об рендеринге с GDI: он всегда будет сжимать альфа-канал. Все, что вы рисуете с ним, установит значения альфа-значений в этой области. Я подозреваю, что это потому, что оно никогда не предназначалось для работы с альфа-каналом или любым типом композитинга. Он был предназначен для непосредственного отображения на экране и принтерах, где альфа-каналов не существует.

Смежные вопросы