【DirectX11】【学习笔记(7)】变换

这一节我们学习如何用矩阵变换,对场景中的物体进行实时的变换。

DirectX中的变换,我们用xna数学库里的XMMATRIX类型。

缩放矩阵

XNA已经提供了构建相应矩阵的函数

XMMATRIX XMMatrixScaling
(
    FLOAT ScaleX,    // x=axis scale
    FLOAT ScaleY,     // y-axis scale
    FLOAT ScaleZ    // z-axis scale
)

缩放矩阵如下

    [S1, 0, 0, 0]
S = [ 0,S2, 0, 0]
    [ 0, 0,S3, 0]
    [ 0, 0, 0, 1]

旋转矩阵

因为旋转矩阵有沿着三个不同坐标轴的旋转。

函数分别如下

//沿着X轴
     [ 1,      0,     0, 0]
Rx = [ 0, cos(r),sin(r), 0]
     [ 0,-sin(r),cos(r), 0]
     [ 0,      0,     0, 1]
 
XMMATRIX XMMatrixRotationX(
         FLOAT Angle    //Rotation angle in radians
)
//沿着Y轴
     [cos(r), 0,-sin(r), 0]
Ry = [   0,   1,   0,    0]
     [sin(r), 0, cos(r), 0]
     [   0,   0,   0,    1]
 
XMMATRIX XMMatrixRotationY(
         FLOAT Angle    //Rotation angle in radians
)
//沿着Z轴
     [ cos(r),sin(r), 0, 0]
Rz = [-sin(r),cos(r), 0, 0]
     [      0,     0, 1, 0]
     [      0,     0, 0, 1]
    
XMMATRIX XMMatrixRotationZ(
         FLOAT Angle    //Rotation angle in radians
)

当我们想沿着一个特定的轴转动时可以调用函数:

XMMATRIX XMMatrixRotationAxis(
         XMVECTOR Axis,    //Vector describing the axis of rotation
         FLOAT Angle    //Rotation angle in radians
)

平移矩阵

    [ 1, 0, 0, 0]
T = [ 0, 1, 0, 0]
    [ 0, 0, 1, 0]
    [mx,my,mz, 1]

XMMATRIX XMMatrixTranslation(
         FLOAT OffsetX,    // Units translated on the x-axis
         FLOAT OffsetY,    // Units translated on the y-axis
         FLOAT OffsetZ    // Units translated on the z-axis
)

变换结合

把不同的变换矩阵按照顺序相乘,(最先的变换在最右边)

Global Declarations

为了实现变换,我们要先声明几个矩阵变量

XMMATRIX cube1World;
XMMATRIX cube2World;

XMMATRIX Rotation;
XMMATRIX Scale;
XMMATRIX Translation;
float rot = 0.01f;

The Cube

因为我们现在要做旋转变换了,所以从现在开始,我们就开始绘制正方体

首先更改索引缓存大小

indexBufferDesc.ByteWidth = sizeof(DWORD) * 12 * 3;

一共6个面,每个面两个三角形

然后更改顶点缓存大小

vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 8;

记得要把顶点数据也改掉!

然后更新上一节中设置的摄像机位置,这样视角会更好

camPosition = XMVectorSet( 0.0f, 3.0f, -8.0f, 0.0f );

Update Scene

接下来我们就在更新函数中,设定我们的旋转,平移,缩放矩阵,这里我们设置两个世界矩阵,因为要对两个正方体进行变换

void UpdateScene()
{
    //Keep the cubes rotating
    rot += .0005f;
    if(rot > 6.28f)
        rot = 0.0f;

    //Reset cube1World
    cube1World = XMMatrixIdentity();

    //Define cube1's world space matrix
    XMVECTOR rotaxis = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
    Rotation = XMMatrixRotationAxis( rotaxis, rot);
    Translation = XMMatrixTranslation( 0.0f, 0.0f, 4.0f );

    //Set cube1's world space using the transformations
    cube1World = Translation * Rotation;

    //Reset cube2World
    cube2World = XMMatrixIdentity();

    //Define cube2's world space matrix
    Rotation = XMMatrixRotationAxis( rotaxis, -rot);
    Scale = XMMatrixScaling( 1.3f, 1.3f, 1.3f );

    //Set cube2's world space matrix
    cube2World = Rotation * Scale;
}

更新好矩阵之后我们就需要在渲染的时候把矩阵传输给EffectFile中的矩阵。

然后调用devicecontext中的drawindexed方法来绘图(以下的每个函数之前都有写过,这里不再赘述)

void DrawScene()
{
    //Clear our backbuffer
    float bgColor[4] = {(0.0f, 0.0f, 0.0f, 0.0f)};
    d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor);

    //Refresh the Depth/Stencil view
    d3d11DevCon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

    ///**************new**************
    //Set the WVP matrix and send it to the constant buffer in effect file
    WVP = cube1World * camView * camProjection;
    cbPerObj.WVP = XMMatrixTranspose(WVP);    
    d3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
    d3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );

    //Draw the first cube
    d3d11DevCon->DrawIndexed( 36, 0, 0 );

    WVP = cube2World * camView * camProjection;
    cbPerObj.WVP = XMMatrixTranspose(WVP);    
    d3d11DevCon->UpdateSubresource( cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0 );
    d3d11DevCon->VSSetConstantBuffers( 0, 1, &cbPerObjectBuffer );

    //Draw the second cube
    d3d11DevCon->DrawIndexed( 36, 0, 0 );
    ///**************new**************

    //Present the backbuffer to the screen
    SwapChain->Present(0, 0);
}

这样我们就能看到一个完好的在世界中旋转的两个正方体。我们的场景终于动起来拉!

本节内容就到这里拉。

本节内容代码可以在我的Github找到,

游戏开发路途遥远,但我相信只要坚持,总能到达彼岸!

如果我的文章对于你学习DirectX11有点帮助,欢迎评论给出建议,让我们一起学习进步!

                                                                                               ———————— 小明 2018.12.2 14.17

 

 

 

 

你可能感兴趣的:(Directx11)