DX12龍書第6章習題

1. 前端

{
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TANGENT",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TEXTURE",  0, DXGI_FORMAT_R32G32_FLOAT,    0, 36, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "TEXTURE",  1, DXGI_FORMAT_R32G32_FLOAT,    0, 44, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR",    0, DXGI_FORMAT_R8G8B8A8_SINT,   0, 52, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
};

 

2.c++

先是一些準備性的東西,這樣描述不太直覺,可是有利於你找到代碼位置。架構

在BoxApp.cpp的前端,先把這個結構改了:ide

//struct Vertex
//{
//    XMFLOAT3 Pos;
//    XMFLOAT4 Color;
//};

//change end
struct VPosData
{
    XMFLOAT3 Pos;
};

struct VColorData
{
    XMFLOAT4 Color;
};

而後是 D3D12_INPUT_ELEMENT_DESC對象改成:函數

mInputLayout =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } //change end
    };

在應用裏有一個幾何體類MeshGeometryui

這個類是用來記錄渲染集合體數據的,還有輔助建立buffer的數據和方法,這些都要修改:this

//Microsoft::WRL::ComPtr<ID3DBlob> VertexBufferCPU = nullptr;
    //change end
    Microsoft::WRL::ComPtr<ID3DBlob> VertexPosBufferCPU = nullptr;
    Microsoft::WRL::ComPtr<ID3DBlob> VertexColorBufferCPU = nullptr;
//Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferGPU = nullptr;
    //change end
    Microsoft::WRL::ComPtr<ID3D12Resource> VertexPosBufferGPU = nullptr;
    Microsoft::WRL::ComPtr<ID3D12Resource> VertexColorBufferGPU = nullptr;
//Microsoft::WRL::ComPtr<ID3D12Resource> VertexBufferUploader = nullptr;
    //change end
    Microsoft::WRL::ComPtr<ID3D12Resource> VertexPosBufferUploader = nullptr;
    Microsoft::WRL::ComPtr<ID3D12Resource> VertexColorBufferUploader = nullptr;
// Data about the buffers.
    //UINT VertexByteStride = 0;
    //UINT VertexBufferByteSize = 0;
    //change end
    UINT VertexPosByteStride = 0;
    UINT VertexPosBufferByteSize = 0;
    UINT VertexColorByteStride = 0;
    UINT VertexColorBufferByteSize = 0;

//D3D12_VERTEX_BUFFER_VIEW VertexBufferView()const
    //{
    //    D3D12_VERTEX_BUFFER_VIEW vbv;
    //    vbv.BufferLocation = VertexBufferGPU->GetGPUVirtualAddress();
    //    vbv.StrideInBytes = VertexByteStride;
    //    vbv.SizeInBytes = VertexBufferByteSize;


    //    return vbv;
    //}
    //change end
    D3D12_VERTEX_BUFFER_VIEW VertexPosBufferView()const
    {
        D3D12_VERTEX_BUFFER_VIEW vbv;
        vbv.BufferLocation = VertexPosBufferGPU->GetGPUVirtualAddress();
        vbv.StrideInBytes = VertexPosByteStride;
        vbv.SizeInBytes = VertexPosBufferByteSize;


        return vbv;
    }

    D3D12_VERTEX_BUFFER_VIEW VertexColorBufferView()const
    {
        D3D12_VERTEX_BUFFER_VIEW vbv;
        vbv.BufferLocation = VertexColorBufferGPU->GetGPUVirtualAddress();
        vbv.StrideInBytes = VertexColorByteStride;
        vbv.SizeInBytes = VertexColorBufferByteSize;


        return vbv;
    }
void DisposeUploaders()
    {
        //VertexBufferUploader = nullptr;
        //change end
        VertexPosBufferUploader = nullptr;
        VertexColorBufferUploader = nullptr;

        IndexBufferUploader = nullptr;
    }
這些描述輸入數據的結構處理完之後就是渲染流程裏的工做了,D3D12建立buffer的時候先是在主存裏建一個數據段,用於未來作碰撞檢測,拾取一類的功能,而後再在內存裏建buffer,並且這個buffer仍是很講究的,它是一個不能夠cpu隨便修改的內存,那爲了保持這個buffer和cpu的隔離,它還要建箇中間內存叫作上傳緩衝器。那下面就改這三個地方:

這段實際上是準備一些基礎數據的,給咱們說的第二和第三個地方用spa

//const UINT vbByteSize = (UINT)vertices.size() * sizeof(Vertex);
    //change end
    const UINT vpbByteSize = (UINT)verticesPos.size() * sizeof(VPosData);
    const UINT vcbByteSize = (UINT)verticesColor.size() * sizeof(VColorData);

下面一段就是主存的數據段,之因此叫CPUBlob是爲了指明它是給CPU用的設計

//ThrowIfFailed(D3DCreateBlob(vbByteSize, &mBoxGeo->VertexBufferCPU));
    //CopyMemory(mBoxGeo->VertexBufferCPU->GetBufferPointer(), vertices.data(), vbByteSize);
    //change end
    ThrowIfFailed(D3DCreateBlob(vpbByteSize, &mBoxGeo->VertexPosBufferCPU));
    CopyMemory(mBoxGeo->VertexPosBufferCPU->GetBufferPointer(), verticesPos.data(), vpbByteSize);
    ThrowIfFailed(D3DCreateBlob(vcbByteSize, &mBoxGeo->VertexColorBufferCPU));
    CopyMemory(mBoxGeo->VertexColorBufferCPU->GetBufferPointer(), verticesColor.data(), vcbByteSize);

下面這段糅合了uploadbuffer和最終的vertexbuffer:3d

//mBoxGeo->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
    //    mCommandList.Get(), vertices.data(), vbByteSize, mBoxGeo->VertexBufferUploader);
    //change end
    mBoxGeo->VertexPosBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
        mCommandList.Get(), verticesPos.data(), vpbByteSize, mBoxGeo->VertexPosBufferUploader);
    mBoxGeo->VertexColorBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
        mCommandList.Get(), verticesColor.data(), vcbByteSize, mBoxGeo->VertexColorBufferUploader);

以上就是構建集合體及其數據的代碼,若是你渲染多集合體多物體的話,你還要注意修改那些集合體頂點位置在整個內存中的位置下標:

//mBoxGeo->VertexByteStride = sizeof(Vertex);
    //mBoxGeo->VertexBufferByteSize = vbByteSize;
    //change end
    mBoxGeo->VertexPosByteStride = sizeof(VPosData);
    mBoxGeo->VertexPosBufferByteSize = vpbByteSize;
    mBoxGeo->VertexColorByteStride = sizeof(VColorData);
    mBoxGeo->VertexColorBufferByteSize = vcbByteSize;

而後就到了真正的Draw階段,將buffer設置到渲染pipleline

//mCommandList->IASetVertexBuffers(0, 1, &mBoxGeo->VertexBufferView());
    //change end
    mCommandList->IASetVertexBuffers(0, 1, &mBoxGeo->VertexPosBufferView());
    mCommandList->IASetVertexBuffers(1, 1, &mBoxGeo->VertexColorBufferView());

以上都準備好之後就輸入大家的數據吧,個人數據是hardcore進代碼的,很是ugly:

//  std::array<Vertex, 8> vertices =
  //  {
  //      Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
        //Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        //Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
        //Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
  //  };
    //change end
    std::array<VPosData,8> verticesPos = 
    {
        VPosData({ XMFLOAT3(-1.0f, -1.0f, -1.0f) }),
        VPosData({ XMFLOAT3(-1.0f, +1.0f, -1.0f) }),
        VPosData({ XMFLOAT3(+1.0f, +1.0f, -1.0f) }),
        VPosData({ XMFLOAT3(+1.0f, -1.0f, -1.0f) }),
        VPosData({ XMFLOAT3(-1.0f, -1.0f, +1.0f) }),
        VPosData({ XMFLOAT3(-1.0f, +1.0f, +1.0f) }),
        VPosData({ XMFLOAT3(+1.0f, +1.0f, +1.0f) }),
        VPosData({ XMFLOAT3(+1.0f, -1.0f, +1.0f) })
    };

    std::array<VColorData,8> verticesColor =
    {
        VColorData({ XMFLOAT4(Colors::White) }),
        VColorData({ XMFLOAT4(Colors::Black) }),
        VColorData({ XMFLOAT4(Colors::Red)  }),
        VColorData({ XMFLOAT4(Colors::Green) }),
        VColorData({ XMFLOAT4(Colors::Blue) }),
        VColorData({ XMFLOAT4(Colors::Yellow) }),
        VColorData({ XMFLOAT4(Colors::Cyan)  }),
        VColorData({ XMFLOAT4(Colors::Magenta) })
    };

而後從新編譯,運行一下就能夠了。

3.

這道題還用示例代碼進行修改吧

原來的存儲點位置和顏色的隊列改爲這樣:

std::array<Vertex, 49> vertices =
    {
        Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) })
        ,//add end
        //a point list
        Vertex({ XMFLOAT3(-4.0f, -4.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(-3.0f,  0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(-2.0f, -3.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3( 0.0f,  0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3( 1.0f, -2.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3( 3.0f,  0.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3( 5.0f, -2.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3( 7.0f,  1.0f, 2.0f), XMFLOAT4(Colors::Red) }),
        //a point strip
        Vertex({ XMFLOAT3(-4.0f, -4.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(-3.0f,  0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(-2.0f, -3.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(0.0f,  0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(1.0f, -2.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(3.0f,  0.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(5.0f, -2.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(7.0f,  1.0f, 3.0f), XMFLOAT4(Colors::Green) }),
        //a line list
        Vertex({ XMFLOAT3(-4.0f, -4.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(-3.0f,  0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(-2.0f, -3.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(0.0f,  0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(1.0f, -2.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(3.0f,  0.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(5.0f, -2.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(7.0f,  1.0f, 4.0f), XMFLOAT4(Colors::Blue) }),
        //a triangle strip
        Vertex({ XMFLOAT3(-4.0f, -4.0f, 5.0f), XMFLOAT4(Colors::White) }),
        Vertex({ XMFLOAT3(-3.0f,  0.0f, 5.0f), XMFLOAT4(Colors::Black) }),
        Vertex({ XMFLOAT3(-2.0f, -3.0f, 5.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(0.0f,   0.0f, 5.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(1.0f,  -2.0f, 5.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(3.0f,   0.0f, 5.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(5.0f,  -2.0f, 5.0f), XMFLOAT4(Colors::Cyan) }),
        Vertex({ XMFLOAT3(7.0f,   1.0f, 5.0f), XMFLOAT4(Colors::Magenta) }),
        //a point list
        Vertex({ XMFLOAT3(-4.0f, -4.0f, 6.0f), XMFLOAT4(Colors::White) }),
        Vertex({ XMFLOAT3(-3.0f,  0.0f, 6.0f), XMFLOAT4(Colors::White) }),
        Vertex({ XMFLOAT3(-2.0f, -3.0f, 6.0f), XMFLOAT4(Colors::White) }),
 
        Vertex({ XMFLOAT3(0.0f,   0.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(3.0f,   0.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(1.0f,  -2.0f, 6.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(5.0f,  -2.0f, 6.0f), XMFLOAT4(Colors::Magenta) }),
        Vertex({ XMFLOAT3(7.0f,   1.0f, 6.0f), XMFLOAT4(Colors::Magenta) }),
        Vertex({ XMFLOAT3(8.0f,   0.0f, 6.0f), XMFLOAT4(Colors::Magenta) })
    };
沿用它的機制,把子幾何體存儲起來
SubmeshGeometry submesh;
    submesh.IndexCount = (UINT)indices.size();
    submesh.StartIndexLocation = 0;
    submesh.BaseVertexLocation = 0;
    //add end
    //a point list
    SubmeshGeometry submesh1;
    submesh1.VertexCount = 8;
    //submesh.StartIndexLocation = 0;
    submesh1.BaseVertexLocation = 8;

    //a line strip
    SubmeshGeometry submesh2;
    submesh2.VertexCount = 8;
    //submesh.StartIndexLocation = 0;
    submesh2.BaseVertexLocation = 16;

    //a line list
    SubmeshGeometry submesh3;
    submesh3.VertexCount = 8;
    //submesh.StartIndexLocation = 0;
    submesh3.BaseVertexLocation = 24;

    //a triangle strip
    SubmeshGeometry submesh4;
    submesh4.VertexCount = 8;
    //submesh.StartIndexLocation = 0;
    submesh4.BaseVertexLocation = 32;

    //a triangle list
    SubmeshGeometry submesh5;
    submesh5.VertexCount = 9;
    //submesh.StartIndexLocation = 0;
    submesh5.BaseVertexLocation = 40;

    mBoxGeo->DrawArgs["box"] = submesh;
    //add end
    mBoxGeo->DrawArgs["pointlist"] = submesh1;
    mBoxGeo->DrawArgs["linestrip"] = submesh2;
    mBoxGeo->DrawArgs["linelist"] = submesh3;
    mBoxGeo->DrawArgs["trianglestrip"] = submesh4;
    mBoxGeo->DrawArgs["trianglelist"] = submesh5;

添加集合體的時候要注意幾何體類已經修改了,爲了調用drawinstanced方便:

struct SubmeshGeometry
{
    //add end
    UINT VertexCount = 0;
    UINT IndexCount = 0;
    UINT StartIndexLocation = 0;
    INT BaseVertexLocation = 0;

    // Bounding box of the geometry defined by this submesh. 
    // This is used in later chapters of the book.
    DirectX::BoundingBox Bounds;
};

Draw函數裏改用ID3D12GraphicsCommandList::DrawInstanced:

mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    mCommandList->SetGraphicsRootDescriptorTable(0, mCbvHeap->GetGPUDescriptorHandleForHeapStart());

    mCommandList->DrawIndexedInstanced(
        mBoxGeo->DrawArgs["box"].IndexCount, 
        1, 0, 0, 0);
    //add end
    mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
    mCommandList->DrawInstanced(
        mBoxGeo->DrawArgs["pointlist"].VertexCount,
        1, mBoxGeo->DrawArgs["pointlist"].BaseVertexLocation, 0);

    mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
    mCommandList->DrawInstanced(
        mBoxGeo->DrawArgs["linestrip"].VertexCount,
        1, mBoxGeo->DrawArgs["linestrip"].BaseVertexLocation, 0);

    mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
    mCommandList->DrawInstanced(
        mBoxGeo->DrawArgs["linelist"].VertexCount,
        1, mBoxGeo->DrawArgs["linelist"].BaseVertexLocation, 0);

    mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
    mCommandList->DrawInstanced(
        mBoxGeo->DrawArgs["trianglestrip"].VertexCount,
        1, mBoxGeo->DrawArgs["trianglestrip"].BaseVertexLocation, 0);

    mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    mCommandList->DrawInstanced(
        mBoxGeo->DrawArgs["trianglelist"].VertexCount,
        1, mBoxGeo->DrawArgs["trianglelist"].BaseVertexLocation, 0);

4.

修改下幾何體數據就好了

mCommandList->DrawIndexedInstanced(
        mBoxGeo->DrawArgs["pyramid"].IndexCount, 
        1, 0, 0, 0);
std::array<Vertex, 5> vertices =
    {
        Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(0.0f, 0.412f, 0.0f), XMFLOAT4(Colors::Red) })
    };

    std::array<std::uint16_t, 18> indices =
    {
        // front face
        0, 4, 1,
        
        // back face
        3, 4, 2,

        // left face
        2, 4, 0,

        // right face
        1, 4, 3,

        // bottom face
        0, 1, 2,
        1, 3, 2
    };
mBoxGeo->DrawArgs["pyramid"] = submesh;

5,

在光柵化三步走裏最後一步就是頂點屬性插值,咱們像素點的值就取決於相鄰兩個定點的顏色,見196頁。

6.

我選用了最簡單的辦法,只是修改了c++和hlsl的constant buffer結構體的格式。

cbuffer cbPerObject : register(b0)
{
    float4x4 gWorldViewProj; 
    float gTime;
};

struct ObjectConstants
{
    XMFLOAT4X4 WorldViewProj = MathHelper::Identity4x4();
    float time;
};
而後你在調用update的時候別忘了給time賦值,代碼裏有現成的mTime可用:
objConstants.time = mTimer.TotalTime();

7.

它說要用world transformation讓兩個物體分開,這個我沒寫代碼,仍是hardcode進代碼了,要改數據buffer,還要改輔助集合體類的數據,最後是多draw個實體:

std::array<Vertex, 13> vertices =
    {
        Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::White) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Blue) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMFLOAT4(Colors::Magenta) }),
        Vertex({ XMFLOAT3(1.1f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Black) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMFLOAT4(Colors::Red) }),
        Vertex({ XMFLOAT3(+3.1f, -1.0f, -1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(1.1f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
        //Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Yellow) }),
        //Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMFLOAT4(Colors::Cyan) }),
        Vertex({ XMFLOAT3(+3.1f, -1.0f, +1.0f), XMFLOAT4(Colors::Green) }),
        Vertex({ XMFLOAT3(2.1f, 0.412f, 0.0f), XMFLOAT4(Colors::Red) })
    };

    std::array<std::uint16_t, 54> indices =
    {
        // front face
        0, 1, 2,
        0, 2, 3,

        // back face
        4, 6, 5,
        4, 7, 6,

        // left face
        4, 5, 1,
        4, 1, 0,

        // right face
        3, 2, 6,
        3, 6, 7,

        // top face
        1, 5, 6,
        1, 6, 2,

        // bottom face
        4, 0, 3,
        4, 3, 7,

        //pyramid
        0, 4, 1,

        // back face
        3, 4, 2,

        // left face
        2, 4, 0,

        // right face
        1, 4, 3,

        // bottom face
        0, 1, 2,
        1, 3, 2
    };
SubmeshGeometry submesh;
    submesh.IndexCount = 36;
    submesh.StartIndexLocation = 0;
    submesh.BaseVertexLocation = 0;

    //add end
    SubmeshGeometry submesh1;
    submesh1.IndexCount = 18;
    submesh1.StartIndexLocation = 36;
    submesh1.BaseVertexLocation = 8;

    mBoxGeo->DrawArgs["box"] = submesh;
    //add end
    mBoxGeo->DrawArgs["pyramid"] = submesh1;
mCommandList->DrawIndexedInstanced(
        mBoxGeo->DrawArgs["pyramid"].IndexCount,
        1, mBoxGeo->DrawArgs["pyramid"].StartIndexLocation, mBoxGeo->DrawArgs["pyramid"].BaseVertexLocation, 0);

    mCommandList->DrawIndexedInstanced(
        mBoxGeo->DrawArgs["box"].IndexCount,
        1, mBoxGeo->DrawArgs["box"].StartIndexLocation, mBoxGeo->DrawArgs["box"].BaseVertexLocation, 0);

8,9.

這兩道題都是在設置光柵化的時候修改光柵話描述結構的屬性,如今他們都被整合到PSO裏了,因此要到bulidPso那個函數裏,添加這麼兩行:

psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);
    //psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_WIREFRAME;
    psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_FRONT;
具體代碼還要改爲相應的標識符才能用,書上給的提示有錯誤,標識符是這個D3D12_CULL_MODE_FRONT和D3D12_CULL_MODE_NONE。

10.

書上把主要代碼的改變都列出來了,顏色轉換能夠直接寫:

Vertex({ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMCOLOR(Colors::White) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, -1.0f), XMCOLOR(Colors::Black) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, -1.0f), XMCOLOR(Colors::Red) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, -1.0f), XMCOLOR(Colors::Green) }),
        Vertex({ XMFLOAT3(-1.0f, -1.0f, +1.0f), XMCOLOR(Colors::Blue) }),
        Vertex({ XMFLOAT3(-1.0f, +1.0f, +1.0f), XMCOLOR(Colors::Yellow) }),
        Vertex({ XMFLOAT3(+1.0f, +1.0f, +1.0f), XMCOLOR(Colors::Cyan) }),
        Vertex({ XMFLOAT3(+1.0f, -1.0f, +1.0f), XMCOLOR(Colors::Magenta) })

會自動調用XMCOLOR類裏的loadfloat4函數

11.

a.在input layout description裏面有一項叫作AlignByteOffset,是它標定告終構體內子項的順序。但還有一項叫inputslot,若是想給這一項改不一樣的入口,就必須按着順序來,這種設計挺反人類的。

b.更不受影響了,它是按着SemanticName和Semantic Index的組合來查找位置的。

 

12.

viewport的設定在第四章講過,同時也要注意183也5.6.3.1關於投影窗口和backbuffer的長寬比不一致的時候,會出現拉伸。但如今的問題是咱們只是用了一半backbuffer,因此投影窗口的寬高比要和這一半的backbuffer保持一致。

13.

實際上在DX12裏ScissorEnable被取消了

D3D11_RASTERIZER_DESC structure:

typedef struct D3D11_RASTERIZER_DESC {
  D3D11_FILL_MODE FillMode;
  D3D11_CULL_MODE CullMode;
  BOOL            FrontCounterClockwise;
  INT             DepthBias;
  FLOAT           DepthBiasClamp;
  FLOAT           SlopeScaledDepthBias;
  BOOL            DepthClipEnable;
  BOOL            ScissorEnable;
  BOOL            MultisampleEnable;
  BOOL            AntialiasedLineEnable;
} D3D11_RASTERIZER_DESC;

D3D12_RASTERIZER_DESC structure:
typedef struct D3D12_RASTERIZER_DESC {
  D3D12_FILL_MODE                       FillMode;
  D3D12_CULL_MODE                       CullMode;
  BOOL                                  FrontCounterClockwise;
  INT                                   DepthBias;
  FLOAT                                 DepthBiasClamp;
  FLOAT                                 SlopeScaledDepthBias;
  BOOL                                  DepthClipEnable;
  BOOL                                  MultisampleEnable;
  BOOL                                  AntialiasedLineEnable;
  UINT                                  ForcedSampleCount;
  D3D12_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster;
} D3D12_RASTERIZER_DESC;

默認狀況下scissor test已經打開了。其實在龍書11上沒有什麼描寫,由於 那時仍是初版DX11,後來又有寫變更,出現了11.1,通常來講11.一、11.2應該只是指的一些新加的特性,不會在基礎流程上作太多變化,奈何11.1其實從新設計了渲染主要的架構,只是儘可能保持接口和以前保持一致,而DX12的時候就完全放開了。然而這個變化的細節仍是沒有找到,繼續關注吧。

14.

這個寫法就多了,好比:

pin.Color = (pin.Color + cos(gTime));

15.

看附錄B裏有。

相關文章
相關標籤/搜索