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 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);[download id="73"] pRenderTarget->SetTransform(translationMatrix); // Draw the image at (m_fXAxis, m_fYAxis) coordinates pRenderTarget->DrawBitmap(m_pImageBitmap, rcDraw); }
Someone can say: “Why applying 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 an overkill. No mention the case of the other transform types (scale, rotation and skew)…
Demo application
Download: Direct2DTranslationDemo.zip (12)
Resources and related articles
- Transforms (Direct2D) | Microsoft Docs
- CRenderTarget Class | Microsoft Docs
- Matrix3x2F class (d2d1helper.h) | Microsoft Docs
- Direct2D | codexpert blog
(to be continued)