C++ 通过DirectX12工具包绘制球体

C++ 通过DirectX12工具包绘制球体,c++,directx-12,directxtk,C++,Directx 12,Directxtk,我在尝试绘制球体时遇到三个问题: 球体在某些角度有毛刺: 不知道如何将颜色应用于球体 无法同时绘制两个球体-仅显示一个球体 代码。呈现: void Game::Render() { if (m_timer.GetFrameCount() == 0) { return; } m_deviceResources->Prepare(); Clear(); auto commandList = m_deviceResources->GetCommandList(); PIXBeginE

我在尝试绘制球体时遇到三个问题:

  • 球体在某些角度有毛刺:
  • 不知道如何将颜色应用于球体
  • 无法同时绘制两个球体-仅显示一个球体 代码。呈现:

    void Game::Render()
    {
    if (m_timer.GetFrameCount() == 0)
    {
    return;
    }
    
    m_deviceResources->Prepare();
    Clear();
    
    auto commandList = m_deviceResources->GetCommandList();
    PIXBeginEvent(commandList, PIX_COLOR_DEFAULT, L"Render");
    
    auto commandList2 = m_deviceResources->GetCommandList();
    PIXBeginEvent(commandList2, PIX_COLOR_DEFAULT, L"Draw Sphere");
    
    m_shapeEffect->Apply(m_deviceResources->GetCommandList());
    
    for (int i(0); i < vsphere; i++)
    {
    m_shapeEffect->SetWorld(d3dsphere[i]->world);
    d3dsphere[i]->Draw(commandList2);
    }
    
    PIXEndEvent(commandList2);
    PIXEndEvent(commandList);
    PIXBeginEvent(m_deviceResources->GetCommandQueue(), PIX_COLOR_DEFAULT, L"Present");
    m_deviceResources->Present();
    m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue());
    PIXEndEvent(m_deviceResources->GetCommandQueue());
    }
    
    如果我认为球体半径(以及我场景中的所有东西)非常小(~10^-6),可能会很有用

    由于未知的原因,most中的示例代码与我通过NuGet软件包安装的头不兼容-我在方法中有不同的构造函数和参数。我认为问题在于我使用的是Visual Studio 15,但Microsoft建议至少使用17(有两个不同的DirectX12TK NuGet软件包—一个用于VS15,另一个用于VS17及以上版本)。这很奇怪


    我通过更改渲染中的代码解决了第三个问题:

    for(int i(0);i<vsphere;i++)
    {
    m_shapeEffect->SetMatrices(d3dsphere->world, m_view, m_projection);
    m_shapeEffect->Apply(m_deviceResources->GetCommandList());
    d3dsphere[i]->Draw();
    }
    
    for(int i(0);等三坐标(d3dsphere->world,m_视图,m_投影);
    m_shapeEffect->Apply(m_deviceResources->GetCommandList());
    d3dsphere[i]->Draw();
    }
    

    我使用的DirectX12TK NuGet软件包版本是
    2019.12.17.1

    这里,您告诉管道状态对象您正在使用
    VertexPositionColor
    ,并且需要逐顶点颜色:

    EffectPipelineStateDescription pd(
    &VertexPositionColor::InputLayout,
    CommonStates::Opaque,
    CommonStates::DepthNone,
    CommonStates::CullNone,
    rtState,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
    m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::VertexColor, pd);
    
    但是你告诉顶点着色器它是:

    const D3D12_INPUT_ELEMENT_DESC VertexPositionColor::InputElements[] =
    {
        { "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR",       0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
    };
    
    将您的基本效果更改为:

    EffectPipelineStateDescription pd(
    &GeometricPrimitive::VertexType::InputLayout,
    CommonStates::Opaque,
    CommonStates::DepthNone,
    CommonStates::CullNone,
    rtState,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
    m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::None, pd);
    
    支持Visual Studio 2015的DirectX DX12工具包的最新版本是。2019年12月和2020年4月之间的功能或API差异非常小,因此我不确定您为什么认为wiki过时。您使用的是什么NuGet软件包和版本


    您使用的是哪个特定的NuGet软件包?您的设备资源构造函数的参数是什么?在我看来深度缓冲区设置得不正确。为什么这里有多个commandList变量?@ChuckWalbourn,可能是因为我理解错误,但它起作用了,所以我没有更改它。我应该只有一个吗?让su在同一个项目中,您只有一个:
    directxtk12_desktop_2015
    directxtk12_desktop_2017
    directxtk12_uwp
    。同时确保您没有使用
    directxtk_desktop_2015
    directxtk_desktop_2015
    ,或
    directxtk_uwp
    (即DX11版本)@ChuckWalbourn我指的是commandList。我安装了
    directxtk12_desktop_2015
    version
    2019.12.17.1
    ,这是我项目中唯一的NuGet软件包。我打开“软件包”直接检查了它谢谢,为了得到反馈,我编辑了我的答案。在画了几个球体之后,我同意深度缓冲区设置错误,所以应该如何设置?我也不知道如何使用自定义颜色(而不是纹理)制作球体了解了,如何设置深度缓冲区,自定义颜色如何?更新了答案并提供了详细信息。还将此示例添加到和的
    geometricsprimitive
    wiki中。
    struct VertexPositionNormalTexture
    {
        XMFLOAT3 position;
        XMFLOAT3 normal;
        XMFLOAT2 textureCoordinate;
    }
    
    const D3D12_INPUT_ELEMENT_DESC VertexPositionColor::InputElements[] =
    {
        { "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
        { "COLOR",       0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
    };
    
    EffectPipelineStateDescription pd(
    &GeometricPrimitive::VertexType::InputLayout,
    CommonStates::Opaque,
    CommonStates::DepthNone,
    CommonStates::CullNone,
    rtState,
    D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
    m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::None, pd);
    
    D3D12_VERTEX_BUFFER_VIEW m_vertexBufferView;
    D3D12_INDEX_BUFFER_VIEW m_indexBufferView;
    
    UINT m_indexCount;
    
    Microsoft::WRL::ComPtr<ID3D12Resource> m_vertexBuffer;
    Microsoft::WRL::ComPtr<ID3D12Resource> m_indexBuffer;
    
    // Create shape data
    std::vector<VertexPositionNormalTexture> vertices;
    std::vector<uint16_t> indices;
    GeometricPrimitive::CreateSphere(vertices, indices);
    
    std::vector<VertexPositionColor> newVerts;
    newVerts.reserve(vertices.size());
    for (auto it : vertices)
    {
        VertexPositionColor v;
        v.position = it.position;
        v.color = XMFLOAT4(it.normal.x, it.normal.y, it.normal.z, 1.f);
        newVerts.emplace_back(v);
    }
    
    // Place data on upload heap
    size_t vsize = newVerts.size() * sizeof(VertexPositionColor);
    SharedGraphicsResource vb = GraphicsMemory::Get().Allocate(vsize);
    memcpy(vb.Memory(), newVerts.data(), vsize);
    
    size_t isize = indices.size() * sizeof(uint16_t);
    SharedGraphicsResource ib = GraphicsMemory::Get().Allocate(isize);
    memcpy(ib.Memory(), indices.data(), isize);
    
    // You can render directly from the 'upload' heap or as shown here create static IB/VB resources
    ResourceUploadBatch resourceUpload(device);
    resourceUpload.Begin();
    
    CD3DX12_HEAP_PROPERTIES heapProperties(D3D12_HEAP_TYPE_DEFAULT);
    
    auto vdesc = CD3DX12_RESOURCE_DESC::Buffer(vsize);
    auto idesc = CD3DX12_RESOURCE_DESC::Buffer(isize);
    
    DX::ThrowIfFailed(device->CreateCommittedResource(
        &heapProperties, D3D12_HEAP_FLAG_NONE, &vdesc, D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr, IID_PPV_ARGS(m_vertexBuffer.GetAddressOf())));
    
    DX::ThrowIfFailed(device->CreateCommittedResource(
        &heapProperties, D3D12_HEAP_FLAG_NONE, &idesc, D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr, IID_PPV_ARGS(m_indexBuffer.GetAddressOf())));
    
    resourceUpload.Upload(m_vertexBuffer.Get(), vb);
    resourceUpload.Upload(m_indexBuffer.Get(), ib);
    
    resourceUpload.Transition(m_vertexBuffer.Get(),
        D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
    resourceUpload.Transition(m_indexBuffer.Get(),
        D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER);
    
    auto uploadResourcesFinished = resourceUpload.End(m_deviceResources->GetCommandQueue());
    uploadResourcesFinished.wait();
    
    // Create matching effect for new vertex layout
    EffectPipelineStateDescription psd(
        &VertexPositionColor::InputLayout,
        CommonStates::Opaque,
        CommonStates::DepthDefault,
        CommonStates::CullNone,
       rtState);
    
    m_shapeEffect = std::make_unique<BasicEffect>(device, EffectFlags::VertexColor, psd);
    
    // Set up buffer views
    m_vertexBufferView = { m_vertexBuffer->GetGPUVirtualAddress(), UINT(vsize), sizeof(VertexPositionColor) };
    m_indexBufferView = { m_indexBuffer->GetGPUVirtualAddress(), UINT(isize), DXGI_FORMAT_R16_UINT };
    
    m_indexCount = UINT(indices.size());
    
    m_shapeEffect->Apply(commandList);
    
    commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
    commandList->IASetIndexBuffer(&m_indexBufferView);
    commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    
    commandList->DrawIndexedInstanced(m_indexCount, 1, 0, 0, 0);