1

我是direct3d 编程的新手,我一直在构建一个简单的Windows 应用程序,用d3d12 依次显示4 个图像。我对 D3D12 架构有基本的了解,到目前为止,我已经创建了四个命令分配器 (backb buffer size = 4)、一个命令列表、一个命令队列、描述符堆和一个栅栏。我还使用 WIC 从文件中加载了我的图像。我知道我必须以某种方式将图像纹理数据作为资源。虽然那部分还不清楚,但我想澄清一下如何从 d3d12 中加载的图像中制作纹理。

4

1 回答 1

5

DirectX-Graphics-Samples GitHub reproD3D12HelloTexture上的示例演示了 Direct3D 12 纹理上传的基础知识。

ComPtr<ID3D12Resource> textureUploadHeap;

// Create the texture.
{
    // Describe and create a Texture2D.
    D3D12_RESOURCE_DESC textureDesc = {};
    textureDesc.MipLevels = 1;
    textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    textureDesc.Width = TextureWidth;
    textureDesc.Height = TextureHeight;
    textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    textureDesc.DepthOrArraySize = 1;
    textureDesc.SampleDesc.Count = 1;
    textureDesc.SampleDesc.Quality = 0;
    textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

    ThrowIfFailed(m_device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
        D3D12_HEAP_FLAG_NONE,
        &textureDesc,
        D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr,
        IID_PPV_ARGS(&m_texture)));

    const UINT64 uploadBufferSize = GetRequiredIntermediateSize(m_texture.Get(), 0, 1);

    // Create the GPU upload buffer.
    ThrowIfFailed(m_device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
        D3D12_HEAP_FLAG_NONE,
        &CD3DX12_RESOURCE_DESC::Buffer(uploadBufferSize),
        D3D12_RESOURCE_STATE_GENERIC_READ,
        nullptr,
        IID_PPV_ARGS(&textureUploadHeap)));

    // Copy data to the intermediate upload heap and then schedule a copy 
    // from the upload heap to the Texture2D.
    std::vector<UINT8> texture = GenerateTextureData();

    D3D12_SUBRESOURCE_DATA textureData = {};
    textureData.pData = &texture[0];
    textureData.RowPitch = TextureWidth * TexturePixelSize;
    textureData.SlicePitch = textureData.RowPitch * TextureHeight;

    UpdateSubresources(m_commandList.Get(), m_texture.Get(), textureUploadHeap.Get(), 0, 0, 1, &textureData);
    m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));

    // Describe and create a SRV for the texture.
    D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
    srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
    srvDesc.Format = textureDesc.Format;
    srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MipLevels = 1;
    m_device->CreateShaderResourceView(m_texture.Get(), &srvDesc, m_srvHeap->GetCPUDescriptorHandleForHeapStart());
}

它使用D3DX12.h C++ 仅内联实用程序头的UpdateSubresources辅助函数。

作为使用 Direct3D 12 而不是 Direct3D 11 的复杂性的示例,此代码仅在为像素着色器加载纹理时才能正常工作。如果将纹理用于顶点着色器或几何着色器,则它可能会崩溃。或者它可能会起作用。或者它有时可能会起作用,而其他时候则不起作用。这也只是在 Direct3D 12 中加载纹理的一种方式,甚至不是最有效的方式。

更新: DirectX12的 DirectX 工具包现已推出。看看DDSTextureLoaderWICTextureLoader

于 2016-02-23T06:04:51.087 回答