Beginners Direct X (7)
- Rotation, scaling and translation of bitmaps
This article aims to realize the rotation, scaling and translation of bitmaps through the D3DXMatrixTransformation2D function, but the specific principle will be further discussed later.
1. Use
Here is the definition of the D3DXMatrixTransformation2D function:
D3DXMATRIX* D3DXMatrixTransformation2D(
_Inout_ D3DXMATRIX *pOut,
_In_ const D3DXVECTOR2 *pScalingCenter,
_In_ FLOAT pScalingRotation,
_In_ const D3DXVECTOR2 *pScaling,
_In_ const D3DXVECTOR2 *pRotationCenter,
_In_ FLOAT Rotation,
_In_ const D3DXVECTOR2 *pTranslation
);
The functions of each parameter are concise and clear. According to the parameters, the final transformation matrix can be calculated and stored in pOut . Note that this is a 2-dimensional function, so the transformation parameters are all two-dimensional. We need to define these in advance. parameters, like the following:
// 控制缩放比例
D3DXVECTOR2 scale(scaling, scaling);
// 控制平移
D3DXVECTOR2 trans((float)x, (float)y);
// 旋转中心
D3DXVECTOR2 scenter((float)width / 2, (float)height / 2);
Finally, pass it as a parameter to D3DXMatrixTransformation2D
D3DXMatrixTransformation2D(
&mat,
&scenter, /*缩放中心*/
0,
&scale /*缩放*/,
&scenter /*旋转中心*/,
rotation /*旋转度数,弧度*/,
&trans /*平移*/
);
In the end you can get a transformation matrix, just get it. But how do you make the renderer know to apply this transformation matrix when drawing? You can do as follows:
spriteobj->SetTransform(&mat);
2. Questions
I found a problem when I used it. When setting the zoom center or rotation center, it should be multiplied by a zoom amount, like the following:
D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height*scaling) / 2);
instead of
D3DXVECTOR2 scenter((float)width / 2, (float)height / 2);
Of course, if the bitmap is scaled at the same scale, it is possible to use scenter , because as long as it is scaled at the same scale, the center point will never change. But if the scaling is inconsistent, for example:
D3DXVECTOR2 scale(scaling, scaling + 2);
This means that the scaling in the y -direction is twice as long as the x -direction, and the center point is also shifted from its original position. In fact, in either case, it seems that it is always no problem to use the definition method of center to define the center point. But there is a problem here that I can't understand. The description of this problem is as follows:
Purpose : To realize the bitmap ( image ) displayed in the center of the window and rotated and scaled around its own center point .
The width and height of the bitmap are width and height respectively , the scaling value is scaling , and the translation variables in the x and y directions are x and y respectively.
// 控制缩放比例
D3DXVECTOR2 scale(scaling, scaling);
// 控制平移
D3DXVECTOR2 trans((float)x, (float)y);
// 旋转,缩放中心,会随放缩比例变化
D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height*scaling) / 2);
D3DXMATRIX mat;
D3DXMatrixTransformation2D(
&mat,
¢er, /*缩放中心*/
0,
&scale /*缩放*/,
¢er /*旋转中心*/,
rotation /*旋转度数*/,
&trans /*平移*/);
spriteobj->SetTransform(&mat);
//获取srcRect
// ...
spriteobj->Draw(image, &srcRect, NULL, NULL, color);
The above function is called with the following parameters, which are the code between Begin() and End() :
// rotate
r = timeGetTime() / 600.0f;
// scaling
s += scale;
if (s < 0.1f || s > 1.25f)
scale *= -1;
width = height = 512;
frame = 0;
columns = 1;
color = D3DCOLOR_XRGB(255,255,255);
Sprite_Transform_Draw(
sunflower, // => image
SCREENW / 2 - width / 2, // => x
SCREENH / 2 - height / 2, // => y (xy用于平移位图至屏幕窗口中心)
width, // => width
height, // => height
frame, // => ignore
columns, // => ignore
r, // => rotation
s, // => scale
color // => ignore
);
It seems that the sunflower can be rotated and scaled around the center , but this is not the case, and I don't know what the reason is, which makes me very confused. Because the actual result is not rotated and scaled around the center . I tried to comment out the scaling, that is to say, set s to 1. At this time, the bitmap stopped scaling, and the center of rotation is center , which is normal . But once s is set to an incrementing or decrementing variable (as written in the code), then the rotation and scaling center is not the real bitmap center.
Remark here, and I will continue to learn to see if I can find the answer to this question.