Color Cube

立方体の各面に色を設定して描画します。

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

プロジェクトの説明

  1. 立方体の各面に色を設定して、X軸とY軸で回転しながら描画します。
    法線ベクトルを設定しているので、ライトで照らすと影ができて立体的に描画されます。
    Main.h で定義されている「頂点座標の構造体」に Color を追加します。
    struct VertexPosition
    {
        DirectX::XMFLOAT3 pos;
        DirectX::XMFLOAT3 norm;
        DirectX::XMFLOAT4 color;
    };
    
  2. Model.cpp の InputLayout の定義も頂点データの形式に合わせて修正します。
        const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 
        };
    
  3. Model.cpp の頂点座標を VertexPosition 構造体を使って定義します。
    XMFLOAT4 が色の設定で、面ごとに異なる色を設定しています。
        VertexPosition cubeVertices[] = 
        {
            { XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3( 0.5f, 0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, 0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
            { XMFLOAT3( 0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
            { XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
    
            { XMFLOAT3(0.5f,  0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3(0.5f,  0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3(0.5f, -0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f,  0.5f,  0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f,  0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3( 0.5f,  0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
    
            { XMFLOAT3( 0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
            { XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
        };
    
  4. モデルの頂点 Index の定義です。
    三角形ポリゴンを組み合わせて立方体のモデルを定義します。
        unsigned short modelIndices[] = 
        {
            0, 1, 2,      0, 2, 3,
            4, 5, 6,      4, 6, 7,
            8, 9, 10,     8, 10, 11,
            12, 13, 14,   12, 14, 15,
            16, 17, 18,   16, 18, 19,
            20, 21, 22,   20, 22, 23
        };
    
  5. モデルは、Y軸とX軸の周期をずらして回転してみました。
    このようにすると、モデルの全ての面を確認することが出来ます。
    法線ベクトルを設定しているので、影ができて立体的に見えるでしょう。
        XMStoreFloat4x4(&m_constantBufferData.model, 
            XMMatrixTranspose(XMMatrixRotationY(timeTotal*XM_PIDIV4) * XMMatrixRotationX(timeTotal*1.5f*XM_PIDIV4)));
    
  6. Shader は頂点データの形式に合ったものを使用しなければなりません。
    SimplePixelShader.hlsl です。
    Shader の説明は Direct3D 9 での HLSL シェーダーの記述 を参照して下さい。
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float4 color : COLOR;
    };
    
    float4 main(PixelShaderInput input) : SV_TARGET
    {
        float3 lightDirection = normalize(float3(1, -1, 0));
        float lightMagnitude = 0.8f * saturate(dot( input.norm, -lightDirection)) + 0.2f;
        return input.color * lightMagnitude;
    }
    
  7. SimpleVertexShader.hlsl です。
    cbuffer ModelViewProjectionConstantBuffer : register(b0)
    {
        matrix model;
        matrix view;
        matrix projection;
    };
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float3 norm : NORMAL;
        float4 color : COLOR;
    };
    
    struct VertexShaderOutput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float4 color : COLOR;
    };
    
    VertexShaderOutput main(VertexShaderInput input)
    {
        VertexShaderOutput output;
        float4 pos = float4(input.pos, 1.0f);
    
        // Transform the vertex position into projected space.
        pos = mul(pos, model);
        pos = mul(pos, view);
        pos = mul(pos, projection);
        output.pos = pos;
    
        float4 norm = float4(normalize(input.norm), 0.0f);
        norm = mul(norm, model);
        output.norm = normalize(norm.xyz);
        output.color = input.color;
        return output;
    }
    
  8. DirectX9 でも 頂点座標の Index を使って BOX を描画する を掲載しています。
    DirectX10 でも 立方体を回転しながら描画する を掲載しています。

超初心者のプログラム入門(DirectX Store)