无法使用 D3D12 渲染三角形

Can't render a triangle with D3D12

我想用 D3D12 渲染一个三角形,但它不起作用。我遵循了 Microsoft 的 Direct 3D 编程指南。

我可以清除渲染目标视图,在输出中我变成了 COMMAND_LIST_DRAW_VERTEX_BUFFER_TOO_SMALL 警告(DrawInstanced:输入顶点槽 0 处的顶点缓冲区不够大,无法满足 Draw*() 调用的预期遍历...) 每一帧。所以我的想法是,问题出在顶点,应对顶点。

这是我的代码:

struct Vertex {
    float x;
    float y;
};

const Vertex vertices[] = {
    { 0.0f, 0.5f },
    { 0.5f, -0.5f },
    { -0.5f, -0.5f }
};

const UINT vertexBufferSize = sizeof(vertices);

// Create and load the vertex buffers
// I'm using an upload heap, because I can't find any solution about a default heap.
CD3DX12_HEAP_PROPERTIES vertexBufferHeapProperties(D3D12_HEAP_TYPE_UPLOAD/*D3D12_HEAP_TYPE_DEFAULT*/);
auto vertexBufferResourceDesc = CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize);

THROW_IF_FAILED(m_pDevice->CreateCommittedResource(
    &vertexBufferHeapProperties,
    D3D12_HEAP_FLAG_NONE,
    &vertexBufferResourceDesc,
    D3D12_RESOURCE_STATE_GENERIC_READ/*D3D12_RESOURCE_STATE_COPY_SOURCE*/,
    nullptr,
    IID_PPV_ARGS(&m_pVertexBuffer)
));

// Copy the vertex data to the vertex buffer
UINT8* pVertexDataBegin;
CD3DX12_RANGE readRange(0, 0);
THROW_IF_FAILED(m_pVertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
memcpy(pVertexDataBegin, vertices, sizeof(vertices));
m_pVertexBuffer->Unmap(0, nullptr);

// Create the vertex buffer views
m_vertexBufferView.BufferLocation = m_pVertexBuffer->GetGPUVirtualAddress();
m_vertexBufferView.SizeInBytes = sizeof(Vertex);
m_vertexBufferView.StrideInBytes = vertexBufferSize;

在输入布局中,我使用 DXGI_FORMAT_R32G32_FLOAT 和 D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA 作为位置。

并且在 PopulateCommandList 函数中:

const float clearColor[] = { 0.6f, 0.7f, 0.9f, 1.0f };
m_pCommandList->ClearRenderTargetView(renderTargetViewHandle, clearColor, 0, 0);
m_pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_pCommandList->IASetVertexBuffers(0, 1, &m_vertexBufferView);
m_pCommandList->DrawInstanced(3, 1, 0, 0);

应该是

m_vertexBufferView.BufferLocation = m_pVertexBuffer->GetGPUVirtualAddress();
m_vertexBufferView.SizeInBytes = vertexBufferSize;
m_vertexBufferView.StrideInBytes = sizeof(Vertex);

而不是

m_vertexBufferView.BufferLocation = m_pVertexBuffer->GetGPUVirtualAddress();
m_vertexBufferView.SizeInBytes = sizeof(Vertex);
m_vertexBufferView.StrideInBytes = vertexBufferSize;