2015-12-27 1 views
1

Je bricole avec DirectX 12 et j'ai frappé un mur en essayant de dessiner un "damier". J'ai beaucoup cherché sur le net, donc toute aide/pointeur sera appréciée.Dessiner plusieurs objets dans D3D12

Dans D3D11, le code de travail est le suivant.

auto context = m_deviceResources->GetD3DDeviceContext(); 

for (int i = -10; i < 10; i++) 
{ 
    for (int j = -10; j < 10; j++) 
    { 
     // perform translation 
     XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixTranslation(i, j, 0.0f))); 
     context->UpdateSubresource(
      m_constantBuffer.Get(), 
      0, 
      NULL, 
      &m_constantBufferData, 
      0, 
      0 
      ); 

     // shaders, etc... 

     // draw the square 
     context->DrawIndexed(
      m_indexCount, 
      0, 
      0 
      ); 
    } 
} 

En D3D12, j'ai essayé de faire la même chose, mais il semble être d'effectuer la traduction dans le monde, comme tous les carrés sont au même endroit.

bool Sample3DSceneRenderer::Render() 
{ 
    if (!m_loadingComplete) 
    { 
     return false; 
    } 

    DX::ThrowIfFailed(m_deviceResources->GetCommandAllocator()->Reset()); 

    DX::ThrowIfFailed(m_commandList->Reset(m_deviceResources->GetCommandAllocator(), m_pipelineState.Get())); 


    PIXBeginEvent(m_commandList.Get(), 0, L"Draw the objects"); 
    { 
     m_commandList->SetGraphicsRootSignature(m_rootSignature.Get()); 
     ID3D12DescriptorHeap* ppHeaps[] = { m_cbvHeap.Get() }; 
     m_commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); 

     CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle(m_cbvHeap->GetGPUDescriptorHandleForHeapStart(), m_deviceResources->GetCurrentFrameIndex(), m_cbvDescriptorSize); 
     m_commandList->SetGraphicsRootDescriptorTable(0, gpuHandle); 

     D3D12_VIEWPORT viewport = m_deviceResources->GetScreenViewport(); 
     m_commandList->RSSetViewports(1, &viewport); 
     m_commandList->RSSetScissorRects(1, &m_scissorRect); 

     CD3DX12_RESOURCE_BARRIER renderTargetResourceBarrier = 
      CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); 
     m_commandList->ResourceBarrier(1, &renderTargetResourceBarrier); 

     D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = m_deviceResources->GetRenderTargetView(); 
     D3D12_CPU_DESCRIPTOR_HANDLE depthStencilView = m_deviceResources->GetDepthStencilView(); 
     m_commandList->ClearRenderTargetView(renderTargetView, m_colors.Get_background(), 0, nullptr); 
     m_commandList->ClearDepthStencilView(depthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); 


     m_commandList->OMSetRenderTargets(1, &renderTargetView, false, &depthStencilView); 

     m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 
     m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView); 
     m_commandList->IASetIndexBuffer(&m_indexBufferView); 


     for (float i = -10.0f; i < 10.0f; i++) 
     { 
      for (float j = -10.0f; j < 10.0f; j++) 
      { 
       // as far as I know, this is how I should perform the translation 
       XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixTranslation(i, j, 0.0f))); 

       UINT8* destination = m_mappedConstantBuffer + (m_deviceResources->GetCurrentFrameIndex() * c_alignedConstantBufferSize); 
       memcpy(destination, &m_constantBufferData, sizeof(m_constantBufferData)); 

       m_commandList->DrawIndexedInstanced(6, 1, 0, 0, 0); 
      } 
     } 

     CD3DX12_RESOURCE_BARRIER presentResourceBarrier = 
      CD3DX12_RESOURCE_BARRIER::Transition(m_deviceResources->GetRenderTarget(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); 
     m_commandList->ResourceBarrier(1, &presentResourceBarrier); 
    } 
    PIXEndEvent(m_commandList.Get()); 

    DX::ThrowIfFailed(m_commandList->Close()); 

    ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; 
    m_deviceResources->GetCommandQueue()->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); 

    return true; 
} 

Merci, Chelsey

Répondre

2

Vous écrivez simplement votre matrice de translation à la même partie de la mémoire pour chaque copie du modèle. Puisque le GPU n'a même pas commencé à dessiner le premier modèle au moment où vous avez fini d'écrire la matrice de traduction pour le dernier, le seul endroit où l'un de ces modèles va dessiner est à la place de la dernière matrice de traduction écrite.

Vous devez écrire chaque matrice dans un emplacement distinct et distinct en mémoire et vous assurer qu'elles ne sont pas remplacées par quoi que ce soit d'autre tant que le GPU n'a pas fini de dessiner les modèles. Le fait d'appeler DrawIndexedInstanced n'indique pas immédiatement au GPU de dessiner quoi que ce soit, il ajoute simplement une commande à une liste de commandes pour dessiner l'objet à un moment donné dans le futur. Si vous n'êtes pas familier avec la nature asynchrone des API graphiques et l'exécution du GPU, vous devriez probablement en lire un peu plus sur son fonctionnement.