2015-12-01 10 views
1

Я новичок в DirectX 12 и пытается отобразить сетку на DX. До сих пор мне удалось получить вершины и индексы из файлов obj и fbx и отобразить все вершины на DX 12, используя проект универсального окна шаблона. Однако я столкнулся с некоторыми проблемами с буфером индексов, поскольку результат рендеринга списка треугольников полностью неверен, особенно когда входная сетка большая (сотни тысяч вершин). В основном данные индексов записываются как массив указателей, и это кажется правильным. С примитивной топологией списка строк результат рендеринга показан ниже. Line list primitive topology rendering resultDirectX 12 Index Buffer

Мне интересно, может ли кто-нибудь дать какое-либо предложение, где, возможно, ошибается код. Для настроек IBV я использую точные коды из проекта шаблона. Заранее благодарю за помощь.

Обновления: Данные представляют собой данные файла obj, полученные с помощью FBX SDK. Я подтвердил как информацию obj mesh, так и полученные данные, они были точно сопоставлены. Поэтому я считаю, что файл данных верен. Кроме того, для данных, передаваемых для установки IBV, таких как размер буфера, также верны. Для этого кода это был проект VSDX 12 универсальных окон, как показано ниже. Большое спасибо за помощь.

 // 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(); 
+0

Спасибо за предложение, и я только что обновил вопрос. –

+0

Вы предлагаете, что это идет не так после сотен тысяч вершин, что, конечно же, будет, если вы используете только 16-битные индексы, которые не могут превышать 65 535. Тем не менее, вам не ясно, если он сломается ниже 65535 вершин, не так ли? –

+0

Я использовал меньшую сетку (530 вершин и 992 лица), но проблема все еще существует. –

ответ

1

данные представляют собой данные файла obj, полученные с помощью FBX SDK. Я подтвердил как информацию obj mesh, так и полученные данные, они были точно сопоставлены. Поэтому я считаю, что файл данных верен. Кроме того, для данных, передаваемых для установки IBV, таких как размер буфера, также верны. Для этого кода это был проект VSDX 12 универсальных окон, как показано ниже. Большое спасибо за помощь.

 // 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(); 
+0

Это не ответ, так это больше информации? Если это так, вы должны отредактировать его в вопросе, а не публиковать его в качестве ответа. – Gimby

0

Я действительно работаю с Майклом, поэтому я знаю ответ на этот вопрос :). Я просто отправлю его сюда для того, чтобы люди спотыкались на этот пост.

Проблема заключалась в использовании 16-разрядных (без знаковых коротких) индексов, когда было более 140000 индексов. Максимальное значение без знака - 65535. В решении использовались 32-разрядные индексы (unsigned int) с форматом DXGI_FORMAT_R32_UINT.