Tutorial-04

Tutorial-04

Tutorial-04 の立方体の描画に挑戦します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

Tutorial04

  1. Tutorial04 のプロジェクトは、立方体のモデルを定義して回転しながら描画するものです。
    結論から先に述べると Visual Studio 2005 では動きませんでした。
    Visual Studio 2008 以上を使うと問題なく動くので念のため。
  2. XMFLOAT3 などは DirectX11 から使われ始めた3Dレンダリングのデータ形式で xnamath.h で定義されています。
    DirectX11 の頂点座標と3Dレンダリングデータの定義です。
    まず目に付くのが Eye, At, Up などの定義が三次元座標から四次元座標?に変わっていることです。
    それに伴い、3D関係の関数が大幅に修正されたことが予想されます。
    また 16Bit ⇒ 32Bit ⇒ 64Bit に対応するするための修正もされているようです。
    struct SimpleVertex
    {
        XMFLOAT3 Pos;
        XMFLOAT4 Color;
    };
    
    struct ConstantBuffer
    {
        XMMATRIX mWorld;
        XMMATRIX mView;
        XMMATRIX mProjection;
    };
    
    XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f );
    XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
    
  3. 従来の頂点座標と3Dレンダリングデータの定義です。
    struct SimpleVertex
    {
        D3DXVECTOR3 Pos;
        D3DXVECTOR4 Color;
    };
    
    D3DXMATRIX      g_World;
    D3DXMATRIX      g_View;
    D3DXMATRIX      g_Projection;
    
    D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f );
    D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
    D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
    
  4. xnamath.h を元に必要な部分だけを抽出して、エラーが無くなるまで改造した xnamathw.h です。
    //Module Name:    xnamathw.h
    #include <d3dx10math.h>
    
    #define XM_PI               3.141592654f
    #define XM_2PI              6.283185307f
    #define XM_1DIVPI           0.318309886f
    #define XM_1DIV2PI          0.159154943f
    #define XM_PIDIV2           1.570796327f
    #define XM_PIDIV4           0.785398163f
    
    // 2D Vector; 32 bit floating point components
    typedef struct _XMFLOAT2
    {
        FLOAT x;
        FLOAT y;
    
        _XMFLOAT2() {};
        _XMFLOAT2(FLOAT _x, FLOAT _y) : x(_x), y(_y) {};
        _XMFLOAT2(CONST FLOAT *pArray);
    
        _XMFLOAT2& operator= (CONST _XMFLOAT2& Float2);
    
    } XMFLOAT2;
    
    // 3D Vector; 32 bit floating point components
    typedef struct _XMFLOAT3
    {
        FLOAT x;
        FLOAT y;
        FLOAT z;
    
        _XMFLOAT3() {};
        _XMFLOAT3(FLOAT _x, FLOAT _y, FLOAT _z) : x(_x), y(_y), z(_z) {};
        _XMFLOAT3(CONST FLOAT *pArray);
    
        _XMFLOAT3& operator= (CONST _XMFLOAT3& Float3);
    
    } XMFLOAT3;
    
    // 4D Vector; 32 bit floating point components
    typedef struct _XMFLOAT4
    {
        FLOAT x;
        FLOAT y;
        FLOAT z;
        FLOAT w;
    
        _XMFLOAT4() {};
        _XMFLOAT4(FLOAT _x, FLOAT _y, FLOAT _z, FLOAT _w) : x(_x), y(_y), z(_z), w(_w) {};
        _XMFLOAT4(CONST FLOAT *pArray);
    
        _XMFLOAT4& operator= (CONST _XMFLOAT4& Float4);
    
    } XMFLOAT4;
    
    typedef struct __vector4
    {
        union
        {
            float        vector4_f32[4];
    
            struct
            {
                FLOAT x;
                FLOAT y;
                FLOAT z;
                FLOAT w;
            } _float4;
            FLOAT v[4];
        };
    } __vector4;
    
    typedef __vector4 XMVECTOR;
    typedef const XMVECTOR FXMVECTOR;
    
    typedef struct _XMMATRIX
    {
        union
        {
            XMVECTOR r[4];
            struct
            {
                FLOAT _11, _12, _13, _14;
                FLOAT _21, _22, _23, _24;
                FLOAT _31, _32, _33, _34;
                FLOAT _41, _42, _43, _44;
            } float16;
            FLOAT m[4][4];
        };
    
        _XMMATRIX() {};
        //_XMMATRIX(FXMVECTOR R0, FXMVECTOR R1, FXMVECTOR R2, CXMVECTOR R3);
        _XMMATRIX(FLOAT m00, FLOAT m01, FLOAT m02, FLOAT m03,
                  FLOAT m10, FLOAT m11, FLOAT m12, FLOAT m13,
                  FLOAT m20, FLOAT m21, FLOAT m22, FLOAT m23,
                  FLOAT m30, FLOAT m31, FLOAT m32, FLOAT m33);
        _XMMATRIX(CONST FLOAT *pArray);
    
        FLOAT       operator() (UINT Row, UINT Column) CONST { return m[Row][Column]; }
        FLOAT&      operator() (UINT Row, UINT Column) { return m[Row][Column]; }
    
        _XMMATRIX&  operator*= (CONST _XMMATRIX& M);
        _XMMATRIX   operator* (CONST _XMMATRIX& M) CONST;
    
    } XMMATRIX;
    
    typedef const XMVECTOR FXMVECTOR;
    typedef const XMMATRIX CXMMATRIX;
    
    // XMVECTOR -> D3DXVECTOR3
    D3DXVECTOR3 toD3DXVECTOR3(XMVECTOR xvect)
    {   D3DXVECTOR3 dvect;
        dvect.x = xvect.v[0];
        dvect.y = xvect.v[1];
        dvect.z = xvect.v[2];
        return dvect;
    }
    
    // D3DXMATRIX -> XMMATRIX
    XMMATRIX  toXMATRIX(D3DXMATRIX dmat)
    {   XMMATRIX    xmat;
        for(int i=0; i<4; i++)
        {   for(int j=0; j<4; j++)
                xmat.m[i][j] = dmat.m[i][j];
        }
        return xmat;
    }
    
    // VectorSet
    XMVECTOR    XMVectorSet(FLOAT x, FLOAT y, FLOAT z, FLOAT w)
    {
        XMVECTOR    xvect;
        xvect.v[0] = x;
        xvect.v[1] = y;
        xvect.v[2] = z;
        xvect.v[3] = w;
        return xvect;
    }
    
    // XMMATRIX = Identity
    XMMATRIX    XMMatrixIdentity()
    {
        XMMATRIX    xmat;
        for(int i=0; i<4; i++)
        {   for(int j=0; j<4; j++)
                xmat.m[i][j] = 0.0f;
            xmat.m[i][i] = 1.0f;    
        }
        return xmat;
    }
    
    // LookAtLH
    XMMATRIX    XMMatrixLookAtLH(FXMVECTOR EyePosition, FXMVECTOR FocusPosition, FXMVECTOR UpDirection)
    {
        D3DXMATRIX  dmat;
        D3DXVECTOR3 eye;
        D3DXVECTOR3 at;
        D3DXVECTOR3 up;
        XMMATRIX    xmat;
        
        eye = toD3DXVECTOR3(EyePosition);
        at = toD3DXVECTOR3(FocusPosition);
        up = toD3DXVECTOR3(UpDirection);
        D3DXMatrixLookAtLH( &dmat, &eye, &at, &up );
        xmat = toXMATRIX(dmat);
        return xmat;
    }
    
    // PerspectiveFovLH
    XMMATRIX    XMMatrixPerspectiveFovLH(FLOAT FovAngleY, FLOAT AspectHByW, FLOAT NearZ, FLOAT FarZ)
    {
        D3DXMATRIX  dmat;
        XMMATRIX    xmat;
        D3DXMatrixPerspectiveFovLH(&dmat, FovAngleY, AspectHByW, NearZ, FarZ);
        xmat = toXMATRIX(dmat);
        return xmat;
    }
    
    // RotationY
    XMMATRIX    XMMatrixRotationY(FLOAT Angle)
    {
        D3DXMATRIX  dmat;
        XMMATRIX    xmat;
        D3DXMatrixIdentity( &dmat );
        D3DXMatrixRotationY( &dmat, Angle );
        xmat = toXMATRIX(dmat);
        return xmat;
    }
    //XMMATRIX        XMMatrixTranspose(CXMMATRIX M);
    
    XMMatrixTranspose() は使わなくてもそのまま代入することが出来ます。
  5. 一応コンパイルエラーが無くなって立方体が描画されることを期待したのですが、空のウインドウしか表示されません。 (^_^;)
    原因は描画関係にあるようです。
    DirectX11 の描画です。
        g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    
        ConstantBuffer cb;
        cb.mWorld = XMMatrixTranspose( g_World );
        cb.mView = XMMatrixTranspose( g_View );
        cb.mProjection = XMMatrixTranspose( g_Projection );
        g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 );
    
        g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
        g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pConstantBuffer );
        g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
        g_pImmediateContext->DrawIndexed( 36, 0, 0 );
    
        g_pSwapChain->Present( 0, 0 );
    
    従来の描画です。
        g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
    
        g_pWorldVariable->SetMatrix( ( float* )&g_World );
        g_pViewVariable->SetMatrix( ( float* )&g_View );
        g_pProjectionVariable->SetMatrix( ( float* )&g_Projection );
    
        D3D10_TECHNIQUE_DESC techDesc;
        g_pTechnique->GetDesc( &techDesc );
        for( UINT p = 0; p < techDesc.Passes; ++p )
        {
            g_pTechnique->GetPassByIndex( p )->Apply( 0 );
            g_pd3dDevice->DrawIndexed( 36, 0, 0 );
        }
    
        g_pSwapChain->Present( 0, 0 );
    
  6. DirectX9(X10) と DirectX11 の間には大きな違いがあるようです。
    これ以上追及する意味が無いので、DirectX11 は Visual Studio 2008 以上を使うものとしておきましょう。

超初心者のプログラム入門(DirectX10 game program)