MFC Support for Direct2D – Transforms (1)

Direct2D supports linear transforms like translation, scale, rotation, and skew.
If using MFC, we can apply transforms to render targets by calling CRenderTarget::SetTransform. Here is an example that shifts the render target 100 points on x-axis and 150 points on y-axis.

FLOAT X = 100.f, Y = 150.f;
D2D1_MATRIX_3X2_F matrix{ 1.f, 0.f, 0.f, 1.f, X, Y };
pRenderTarget->SetTransform(matrix);

It looks not very handy to fill the matrix structure, so Matrix3x2F utility class can make it easier.

 // ...
 D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation(X, Y);
 pRenderTarget->SetTransform(matrix);

Let’s begin to present each render target transform with a little bit less trivial examples.

Identity transform

Let’s say that we have to draw a picture in the default render target origin (top-left corner) and then, the same image moved at some x and y coordinates.
For the first image, call CRenderTarget::SetTransform with an identity matrix, in order to reset the render target transforms. That’s it, any object will be drawn with its unchanged position, shape, and size.

void CTranslationView::DrawImages(CRenderTarget* pRenderTarget)
{
    // Set the destination rectangle based on original bitimap  size 
    CD2DSizeF size = m_pImageBitmap->GetSize();
    CD2DRectF rcDraw(0, 0, size.width, size.height);
    
    // Apply the identity transform to the render target.
    D2D1_MATRIX_3X2_F identityMatrix = D2D1::Matrix3x2F::Identity();
    pRenderTarget->SetTransform(identityMatrix);
    // Draw the image at (0, 0) coordinates
    pRenderTarget->DrawBitmap(m_pImageBitmap, rcDraw, 0.25f);
    // ...
}

Translation transform

Now let’s complete the above code and draw the second image.

void CTranslationView::DrawImages(CRenderTarget* pRenderTarget)
{
    // ...
    // Apply the translation transform to the render target.
    D2D1_MATRIX_3X2_F translationMatrix = 
        D2D1::Matrix3x2F::Translation(m_fXAxis, m_fYAxis);
    pRenderTarget->SetTransform(translationMatrix);
    // Draw the image at (m_fXAxis, m_fYAxis) coordinates
    pRenderTarget->DrawBitmap(m_pImageBitmap, rcDraw);
}

Someone can say: “Why applying to render target transforms, while we can simply recalculate the destination drawing rectangle?” Well, in this simple case it’s easy to be done, but in the real programming world may be required to render much more complicated objects, and recalculating the drawing parameters may be overkill. No mention of the case of the other transform types (scale, rotation, and skew)…

Demo application

Download: Direct2DTranslationDemo.zip (184 downloads)

Direct2D Translation Demo
Direct2D Translation Demo

Resources and related articles

(to be continued)

Leave a Comment