gpt4 book ai didi

indices - DirectX 12 索引缓冲区

转载 作者:行者123 更新时间:2023-12-02 04:15:32 28 4
gpt4 key购买 nike

我是 DirectX 12 的新手,正在尝试在 DX 上渲染网格。到目前为止,我成功地从 obj 和 fbx 文件中检索顶点和索引,并使用模板通用窗口项目在 DX 12 上渲染所有顶点。但是,我遇到了索引缓冲区的一些问题,因为三角形列表的渲染结果完全不正确,尤其是当输入网格很大(数十万个顶点)时。基本上,索引数据被写成一个指针数组,看起来是正确的。使用线列表基元拓扑,渲染结果如下图所示。 Line list primitive topology rendering result

我想知道是否有人可以给出任何代码中可能出错的建议。对于 IBV 设置,我使用的是模板项目中的确切代码。提前感谢您的帮助。

更新:数据为使用FBX SDK获取的obj文件数据。我确认了 obj 网格信息和检索到的数据,它们是精确匹配的。所以我认为数据文件是正确的。此外,对于IBV设置传入的数据,如缓冲区字节大小,也是正确的。对于代码,它来自 VS DX 12 模板通用 windows 项目,如下所示。非常感谢您的帮助。

        // Create the index buffer resource in the GPU's default heap and copy index data into it using the upload heap.
// The upload resource must not be released until after the GPU has finished using it.
Microsoft::WRL::ComPtr<ID3D12Resource> indexBufferUpload;

//CD3DX12_RESOURCE_DESC indexBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(indexBufferSize);
DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(defaultHeapProperties),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(indexBufferSize),
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&m_indexBuffer)));

DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(indexBufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&indexBufferUpload)));

m_indexBuffer->SetName(L"Index Buffer Resource");
indexBufferUpload->SetName(L"Index Buffer Upload Resource");


// Upload the index buffer to the GPU.
{
D3D12_SUBRESOURCE_DATA indexData = {0};

//indexData.pData = cubeIndices;
indexData.pData = reinterpret_cast<BYTE*>(cubeIndices);
indexData.RowPitch = indexBufferSize;
indexData.SlicePitch = indexData.RowPitch;

UpdateSubresources(m_commandList.Get(), m_indexBuffer.Get(), indexBufferUpload.Get(), 0, 0, 1, &indexData);

CD3DX12_RESOURCE_BARRIER indexBufferResourceBarrier =
CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_INDEX_BUFFER);

//CD3DX12_RESOURCE_BARRIER indexBufferResourceBarrier =
// CD3DX12_RESOURCE_BARRIER::Transition(m_indexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
m_commandList->ResourceBarrier(1, &indexBufferResourceBarrier);
}

// Create a descriptor heap for the constant buffers.
{
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
heapDesc.NumDescriptors = DX::c_frameCount;
heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
// This flag indicates that this descriptor heap can be bound to the pipeline and that descriptors contained in it can be referenced by a root table.
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
DX::ThrowIfFailed(d3dDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&m_cbvHeap)));

m_cbvHeap->SetName(L"Constant Buffer View Descriptor Heap");
}

CD3DX12_RESOURCE_DESC constantBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(DX::c_frameCount * c_alignedConstantBufferSize);
DX::ThrowIfFailed(d3dDevice->CreateCommittedResource(
&uploadHeapProperties,
D3D12_HEAP_FLAG_NONE,
&constantBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_constantBuffer)));

m_constantBuffer->SetName(L"Constant Buffer");

// Create constant buffer views to access the upload buffer.
D3D12_GPU_VIRTUAL_ADDRESS cbvGpuAddress = m_constantBuffer->GetGPUVirtualAddress();
CD3DX12_CPU_DESCRIPTOR_HANDLE cbvCpuHandle(m_cbvHeap->GetCPUDescriptorHandleForHeapStart());
m_cbvDescriptorSize = d3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

for (int n = 0; n < DX::c_frameCount; n++)
{
D3D12_CONSTANT_BUFFER_VIEW_DESC desc;
desc.BufferLocation = cbvGpuAddress;
desc.SizeInBytes = c_alignedConstantBufferSize;
d3dDevice->CreateConstantBufferView(&desc, cbvCpuHandle);

cbvGpuAddress += desc.SizeInBytes;
cbvCpuHandle.Offset(m_cbvDescriptorSize);
}

// Map the constant buffers.
DX::ThrowIfFailed(m_constantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&m_mappedConstantBuffer)));
ZeroMemory(m_mappedConstantBuffer, DX::c_frameCount * c_alignedConstantBufferSize);
// We don't unmap this until the app closes. Keeping things mapped for the lifetime of the resource is okay.

// Close the command list and execute it to begin the vertex/index buffer copy into the GPU's default heap.
DX::ThrowIfFailed(m_commandList->Close());
ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
m_deviceResources->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

// Create vertex/index buffer views.
m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
m_vertexBufferView.StrideInBytes = sizeof(VertexPositionColorTexture);
m_vertexBufferView.SizeInBytes = sizeof(*cubeVertices) * m_VertexNumber;

m_indexBufferView.BufferLocation = m_indexBuffer->GetGPUVirtualAddress();
m_indexBufferView.SizeInBytes = sizeof(*cubeIndices) * m_VertxIndicesNumber;
m_indexBufferView.Format = DXGI_FORMAT_R16_UINT;

// Wait for the command list to finish executing; the vertex/index buffers need to be uploaded to the GPU before the upload resources go out of scope.
m_deviceResources->WaitForGpu();

最佳答案

我实际上和 Michael 一起工作,所以我知道这个问题的答案:)。我会把它张贴在这里,供偶然发现这篇文章的人使用。

当有超过 140000 个索引时,问题确实是使用 16 位(unsigned short)索引。最大 unsigned short 为 65535。解决方案是使用格式为 DXGI_FORMAT_R32_UINT 的 32 位索引(unsigned int)。

关于indices - DirectX 12 索引缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34024007/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com