Используйте массив текстур в качестве цели рендеринга поверхности Direct2D.

Я пытаюсь создать массив текстур Direct3D 11, содержащий несколько страниц текста, отрисованных с помощью DirectWrite и Direct2D. Предположим, что layout содержит IDWriteTextLayout для отдельных страниц, тогда я пытаюсь сделать следующее:

{
    D3D11_TEXTURE2D_DESC desc;
    ::ZeroMemory(&desc, sizeof(desc));
    desc.ArraySize = static_cast<UINT>(layouts.size());
    desc.BindFlags = D3D11_BIND_RENDER_TARGET;
    desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    desc.Height = height;
    desc.MipLevels = 1;
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.Width = width;

    auto hr = this->_d3dDevice->CreateTexture2D(&desc, nullptr, &retval.Texture);
    if (FAILED(hr)) {
        throw std::system_error(hr, com_category());
    }
}

for (auto &l : layouts) {
    ATL::CComPtr<IDXGISurface> surface;

    {
        auto hr = retval.Texture->QueryInterface(&surface);
        if (FAILED(hr)) {
             // The code fails here with E_NOINTERFACE "No such interface supported."
             throw std::system_error(hr, com_category());
        }
    }

    // Go on creating the RT from 'surface'.
}

Проблема в том, что код дает сбой в указанной строке, где я пытаюсь получить интерфейс IDXGISurface из ID3D11Texture2D, если имеется более одной страницы (desc.ArraySize > 1). В конце концов я нашел в документации (https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nn-dxgi-idxgisurface), что это сделано по дизайну:

Если 2D-текстура [...] не состоит из массива текстур, QueryInterface завершается успешно и возвращает указатель на указатель интерфейса IDXGISurface. В противном случае QueryInterface завершается ошибкой и не возвращает указатель на IDXGISurface.

Есть ли другой способ получить отдельные поверхности DXGI в массиве текстур, чтобы рисовать их одну за другой с помощью Direct2D?


person Christoph    schedule 14.06.2020    source источник


Ответы (1)


Поскольку я не смог найти никакого способа обращения с подповерхностями, я создаю промежуточную текстуру с одним слоем для рендеринга и копирую результат в массив текстур, используя ID3D11DeviceContext::CopySubresourceRegion.

person Christoph    schedule 20.06.2020