将效果应用于输出而不是位图?

时间:2014-11-01 12:02:43

标签: c++ effects direct2d

假设我有一个高斯模糊效果ID2D1Effect *blur;,我想在效果上应用位图来获得模糊图像。我可以使用blur->SetInput(0, bitmap);将位图传递给效果,并使用blur->Get()获取输出。现在我不想模糊存储在磁盘上的图像,我想模糊我在renderTarget->BeginDraw()renderTarget->EndDraw()之间创建的输出。我的第一个想法是获取输出的位图,但我既没有找到用于检索已经渲染的输出的函数,也没有找到将效果应用于renderTarget而不是加载的位图的方法。

小例子:

ID2D1SolidColorBrush *brush;
ID2D1HwndRenderTarget *renderTarget; // Instantiated somewhere else in code

renderTarget->CreateSolidColorBrush(D2D1::ColorF(0.0f, 0.6f, 1.0f), &bush);

renderTarget->BeginDraw();
renderTarget->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f));
renderTarget->FillRectangle(D2D1::RectF(50.0f, 50.0f, 100.0f, 100.0f), brush);
// Apply gaussian blur?
renderTarget->EndDraw();

brush->Release();
// renderTarget gets released somewhere else

如何在此示例中模糊矩形?


编辑(感谢 enhzflep ):

我可以使用以下代码段获取已经渲染的输出作为位图:

ID2D1BitmapRenderTarget *bitmapRenderTarget;
hwndRenderTarget->CreateCompatibleRenderTarget(&bitmapRenderTarget);

ID2D1Bitmap *bitmap;
bitmapRenderTarget->GetBitmap(&bitmap);

在我的代码中,我已经通过获取位图,绘制它并最终将此位图绘制到hwndRenderTarget上来测试它并且它有效。在将位图绘制回hwndRenderTarget之前,我想对其应用效果(例如高斯模糊)。但这导致了下一个问题(我不知道是否应该打开一个新主题,所以我在这里发布):ID2D1Effect接口只能从ID2D1DeviceContext的实例实例化,这是ID2D1Effect的实例。仅适用于Windows 8.我无法想象Microsoft将ID2D1Effect限制为Windows 8,因此必须采用另一种方式。 是否有人知道另一种设置 {{1}} 界面的方式?


编辑2

我也在MSDN上发布了这个问题,最后得到了answer。我必须安装Platform Update for Win7 SP1 (KB2670838)Win8 SDK(也适用于Win7)才能在Win7上使用Win8标头。

(下面的最终解决方案作为答案)

1 个答案:

答案 0 :(得分:2)

这是我的最终解决方案。比我想象的要简单:

// Obtain already initialized ID2D1HwndRenderTarget
ID2D1HwndRenderTarget *hwndRenderTarget = Game::GetInstance()->gfx->hwndRenderTarget;

// COMs
ID2D1Bitmap *bitmap;
ID2D1BitmapRenderTarget *bitmapRenderTarget;
ID2D1DeviceContext *deviceContext;
ID2D1Effect *gaussianBlur;
ID2D1SolidColorBrush *solidColorBrush;

// Create bitmapRenderTarget
hwndRenderTarget->CreateCompatibleRenderTarget(&bitmapRenderTarget);

// Create solidColorBrush
bitmapRenderTarget->CreateSolidColorBrush(D2D1::ColorF(0.0f, 0.6f, 1.0f), &solidColorBrush);

// Draw onto bitmapRenderTarget
bitmapRenderTarget->BeginDraw();
bitmapRenderTarget->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f));
bitmapRenderTarget->FillEllipse(D2D1::Ellipse(D2D1::Point2F(400.0f, 300.0f), 100.0f, 100.0f), solidColorBrush);
bitmapRenderTarget->EndDraw();

// Obtain hwndRenderTarget's deviceContext
hwndRenderTarget->QueryInterface(&deviceContext);

// Create and apply gaussian blur
deviceContext->CreateEffect(CLSID_D2D1GaussianBlur, &gaussianBlur);

bitmapRenderTarget->GetBitmap(&bitmap);
gaussianBlur->SetInput(0, bitmap);
gaussianBlur->SetValue(D2D1_GAUSSIANBLUR_PROP_BORDER_MODE, D2D1_BORDER_MODE_SOFT);
gaussianBlur->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 5.0f);

// Draw resulting bitmap
deviceContext->DrawImage(
    gaussianBlur,
    D2D1_INTERPOLATION_MODE_LINEAR);

// Release
bitmap->Release();
bitmapRenderTarget->Release();
deviceContext->Release();
gaussianBlur->Release();
solidColorBrush->Release();