Beginners Direct X (7)

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, 
    &center,                  /*缩放中心*/
    0,
    &scale                  /*缩放*/, 
    &center                /*旋转中心*/,
    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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324860961&siteId=291194637