Category Archives: Direct2D

Direct2D Library

MFC Support for Windows Animation

Let’s say we have to make a slide show presentation using Cross Fade effect. If the target system is Windows 10, that’s quite easy because Direct2D offers built-in Cross Fade effect.

Cross Fade effect example

Further we can set a timer to periodically change m_dWeight value from 0.0f to 1.0f. So far, so good but a better solution is to use Windows Animation interfaces that allow to implement animations that are smooth, natural, and interactive. Moreover, MFC offers wrapper classes that can make programmer’s life much more easier than in case of direct using COM interfaces.

Using MFC support for animation

To use MFC support for animation do the following:

  1. first of all we need an object of type CAnimationController which is the key class that manages animations;
  2. call CAnimationController::SetRelatedWnd in order to establish a window that will receive WM_PAINT message when animation manager status has changed or animation timer has been updated;
  3. call CAnimationController::EnableAnimationTimerEventHandler;
  4. add an animation object, in our case of type CAnimationValue as long as we only need an “animated” FLOAT to set cross-fade weight property; here is a list of MFC animation object classes defined in afxanimationcontroller.h
    • CAnimationValue
    • CAnimationPoint
    • CAnimationSize
    • CAnimationColor
    • CAnimationRect
  5. add transition(s) to animation object; here is a list of transition MFC classes:
    • CAccelerateDecelerateTransition
    • CConstantTransition
    • CCubicTransition
    • CDiscreteTransition
    • CInstantaneousTransition
    • CLinearTransition
    • CLinearTransitionFromSpeed
    • CSmoothStopTransition
    • CParabolicTransitionFromAcceleration
    • CReversalTransition
    • CSinusoidalTransitionFromRange
    • CSinusoidalTransitionFromVelocity
    • CSinusoidalTransitionFromVelocity
  6. uncomment the line containing m_spAnimCrossFadeWeightValue->GetValue(m_dWeight) in the previous example;
  7. finally, call CAnimationController::AnimateGroup.

Here is some sample code:

More details can be found in the attached demo project.

Demo project

Download: MFC Support for Animation Demo.zip (12)

Cross Fade Effect with Animation 1

Cross Fade Effect with Animation 1

Cross Fade Effect with Animation 2

Cross Fade Effect with Animation 2

Cross Fade Effect with Animation 3

Cross Fade Effect with Animation 3

Resources and related articles

MFC Support for Direct2D – Part 7: Saving to files

Once have enabled Direct2D support in an MFC application, there is no sweat to load an image from a file, by using one of CD2DBitmap constructors.
Unfortunately, we cannot find a CD2DBitmap method to save it into a image file (something similar to CImage::Save or Gdiplus::Image::Save).
No problem, we can try to do it ourselves. Here is an example:

Create and use a WIC bitmap render target

Looks good although it can be refactorized and/or can be improved for saving multiple frames, metadata and so on. However, it’s a problem: if the Direct2D bitmap (pBitmap) has been created in the window’s render target, EndDraw returns D2DERR_WRONG_RESOURCE_DOMAIN error (the resource was realized on the wrong render target). That is because CWnd::EnableD2DSupport creates a render target of type D2D1_RENDER_TARGET_TYPE_DEFAULT and as stated in the documentation, it cannot share its resources with another render targets. So, let’s replace EnableD2DSupport call with a call to another one (let’s say it EnableD2DSoftwareSupport).

Replace CWnd::EnableD2DSupport

More details can be found in the demo application attached below. Just to note that forcing software rendering for window’s render target leads in performance penalty but generally, we can live with that until finding a better solution. :)

Demo application

The demo application is a simple image viewer using MFC support for Direct2D and WIC to load/save images from/into into files.
DownloadSave Direct2D bitmap in a file - Demo.zip (76)

Resources and related articles

MFC Support for Direct2D – Part 6: Composite Effects

We can combine two or more images and/or effects by using the composite effect. Here is an example.

Drawing shadows using Direct2D composite effects

Demo project

Download: Composite Effect Demo.zip (222)
You can set the amount of blur and the color as well as the distance of the shadow.

Composite Effect Demo

Composite Effect Demo

Resources and related articles

MFC Support for DirectWrite – Part 11: About Trimming Again

In a previous article, I showed how to trim a text which overflows the layout box. In the example presented there, the ellipsis is added at the end of truncated text. But if, let’s say, we have to show a long path and file name, it is not meaningful if the file name is not displayed. No problem, this can be easily resolved if have a look at DWRITE_TRIMMING structure which passed to IDWriteTextFormat::SetTrimming. The second parameter is a character code used as delimiter and the third one is the delimiter count. The text is preserved from the end until is found the delimiter which coresponds to delimiter count. For example, if the delimiter is backslash and the delimiter count is 2, a text like “e:\Articles\MFC Support for DirectWrite\DirectWrite Trimming Demo\D2DStaticCtrl.cpp” may be displayed as follows “e:\Articles…\DirectWrite Trimming Demo\D2DStaticCtrl.cpp”.

An example of trimming by using a delimiter

Demo project

Download: DirectWrite Trimming Demo.zip (257)
The demo project is a simple MFC application which demonstrate how to trim text rendered with DirectWrite. You can choose the granularity, the delimiter and the delimiter count and see what is displayed.

DirectWrite Trimming Demo

DirectWrite Trimming Demo

Resources and related articles

MFC Support for Direct2D – Part 5: Interoperability with GDI

There are two ways to combine Direct2D with Windows GDI API in the same application:

  1. Drawing Direct2D content to a GDI device context
  2. Drawing GDI content to a Direct2D GDI-compatible render target

Let’s see each one!

Drawing Direct2D content to a GDI device context

For this purpose, use ID2D1DCRenderTarget instead of ID2D1HwndRenderTarget interface. If using MFC shipped with Visual Studio 2015 or newer, then CDCRenderTarget wrapper class makes the programmer life easier. Here are the steps:

  1. In the WM_CREATE message handler call CWnd::EnableD2DSupport passing TRUE as second parameter. This way, the MFC framework creates a CDCRenderTarget instead of a CHwndRenderTarget object.
  2. Map AFX_WM_DRAW2D registered messge.

  3. Finally, get the CDCRenderTarget* passed by MFC framework in LPARAM and enjoy.

Drawing GDI content to a Direct2D GDI-compatible render target

So far, MFC has not a wrapper class for ID2D1GdiInteropRenderTarget interface. Also, CWnd::EnableD2DSupport creates a CHwndRenderTarget which is not GDI-compatible. So, we must do it ourselves. Here is the sample code:

Demo projects

Download: Direct2D and GDI Interop Demo.zip (394)

The Visual C++ solution attached here has two simple projects showing the both Direct2D and GDI interoperatibily methods listed above.

Direct2D and GDI Interop - Demo Application

Direct2D and GDI Interop – Demo Application

 

Notes

  • can be observed that Direct2D drawing quality is higher than GDI drawing, because Direct2D is capable of rendering with antialiasing;
  • given the first note, my opinion is that GDI drawing has no much sense once using Direct2D but never know…

Resources and related articles

MFC Support for Direct2D – Part 4: Built-in Effects

Direct2D has built-in support for image processing like changing brightness or contrast, blurring, creating drop shadows, and so on. Basically, we can use for this purpose the CreateEffect and DrawImage methods of ID2D1DeviceContext interface. So far, there is no MFC wrapper class for ID2D1DeviceContext but that’s not so big issue. Once having a valid ID2D1RenderTarget instance (wrapped in CRenderTarget class) we can easily get the ID2D1DeviceContext interface by calling QueryInterface. No sweat!

Getting ID2D1DeviceContext interface in an MFC application

Or, a little bit easier, use CComQIPtr which calls QueryInterface for you.

Drawing an image using the Gaussian Blur built-in effect

Here is an example:

Just note that you should additionally include d2d1_1.h header and link your project to dxguid.lib. More details can be found in the attached demo project.

The demo project

Download: Gaussian Blur Effect demo.zip (379)

Gaussian Blur Effect - Demo Project

Notes

Resources and related articles

MFC Support for DirectWrite – Part 10: Outlined Text

In a previous article, I showed the basics of custom text rendering with DirectWrite (see MFC Support for DirectWrite – Part 7: A Step to Custom Rendering). So far so good but it just mimics the default text rendering. Let’s now modify the overridden IDWriteTextRenderer::DrawGlyphRun in order to draw outlined text.

Overridden IDWriteTextRenderer::DrawGlyphRun implementation

A method for drawing outlined text

Basically, the steps where the following:

  1. if pClientDrawingContext parameter is null then perform the default drawing;
  2. otherwhise, call _DrawOutlinedGlyphRun pasing an object that contains the brushes for text outline and fill (COutlinedTextEffect);
  3. create a path geometry (CD2DPathGeometry);
  4. instantiate a geometry sink that is used to populate the path geometry (CD2DGeometrySink);
  5. get IDWriteFontFace interface from DWRITE_GLYPH_RUN structure;
  6. call IDWriteFontFace::GetGlyphRunOutline, passing a bunch of parameters, most of them contained in DWRITE_GLYPH_RUN structure plus our geometry sink;
  7. close the geometry sink;
  8. translate the render target according to the glyph run baseline origin (baselineOriginX and baselineOriginY parameters of DrawGlyphRun);
  9. finally, call CRenderTarget::DrawGeometry and CRenderTarget::FillGeometry and…
  10. …do not forget to restore the initial render target transform.

You can find more details in the demo application attached here. Also you can have a look in the related articles mentioned at the bottom of this page.

Demo project

The demo project draws outlined text in order to make it readable over any background image.
DownloadOutlined Text Demo.zip (388)

Outlined Text demo project

Outlined Text demo project

Resources and related articles