Let's say I have a gaussian blur effect ID2D1Effect *blur;
and I want to apply a bitmap to the effect to get a blured image. I can pass the bitmap to the effect using blur->SetInput(0, bitmap);
and get the output with blur->Get()
. Now I don't want to blur an image stored on disk, I want to blur the output that I created between renderTarget->BeginDraw()
and renderTarget->EndDraw()
. My first idea was to get a bitmap of the output, but I could find neither a function for retrieving the already rendered output nor find a way to apply an effect to the renderTarget instead of a loaded bitmap.
Little example:
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
How can I blur the rectangle in this example?
EDIT (Thanks to enhzflep):
I can obtain the already rendered output as a bitmap with following snippet:
ID2D1BitmapRenderTarget *bitmapRenderTarget;
hwndRenderTarget->CreateCompatibleRenderTarget(&bitmapRenderTarget);
ID2D1Bitmap *bitmap;
bitmapRenderTarget->GetBitmap(&bitmap);
In my code I already tested it by obtaining a bitmap, drawing on it and finally draw this bitmap onto the hwndRenderTarget
and it worked. Before drawing the bitmap back to the hwndRenderTarget
I want to apply an effect to it (e.g. gaussian blur). But this leads to the next problem (I don't know if I should open a new topic, so I post it here): An ID2D1Effect
interface can only be instantiated from an instance of ID2D1DeviceContext
which is only available for Windows 8. I cannot imagine that Microsoft restricts ID2D1Effect
to Windows 8, so there have to be another way. Does anyone know another way of instatiating an ID2D1Effect
interface?
EDIT 2:
I also posted this question on MSDN and finally got an answer. I had to install the Platform Update for Win7 SP1 (KB2670838) and the Win8 SDK (also works on Win7) in order to use Win8 headers on Win7.
(Final solution below as answer)
Here is my final solution. It's simpler than I though it's gonna be:
// 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();