Получение данных ID3D11Texture2D для отправки по сети

Я изменяю пример api дублирования рабочего стола любезно предоставлено Microsoft захватить экран и отправить обновления по сети моему приложению. Я знаю, как на самом деле отправить данные; Моя проблема заключается в получении данных из объекта ID3D11Texture2D.

ID3D11Texture2D* m_AcquiredDesktopImage;
IDXGIResource* desktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;

// Get new frame
HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &desktopResource);

// QI for IDXGIResource
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&m_AcquiredDesktopImage));

На данный момент, я думаю, что обновления экрана в m_AcquiredDesktopImage, Мне нужно передать эти данные по проводам (максимально эффективно).

Этот ответ кажется, на правильном пути, но я новичок в программировании Windows, поэтому мне нужна дополнительная помощь.

Это единственное решение, которое я могу себе представить, используя IDXGIObject::GetPrivateData

3

Решение

Личные данные — это совсем не то, что вы ищете. Они здесь только для прикрепления пользовательских значений к объектам d3d.

Когда у вас есть ID3D11Texture2D объект, с которого нужно считывать изображение обратно, необходимо создать второй в промежуточном пуле памяти из ID3D11Device (получить оригинальное описание, изменить пул и удалить привязку).

Затем вам нужно использовать ID3D11DeviceContext скопировать текстуру в вашу промежуточную, используя CopyResource, Тогда вы можете использовать контекст Map а также Unmap API для чтения изображения.

2

Другие решения

Я получил хорошую ссылку, которая делает это .. Ищите метод SaveTextureToBmp

[...]

// map the texture
ComPtr<ID3D11Texture2D> mappedTexture;
D3D11_MAPPED_SUBRESOURCE mapInfo;
mapInfo.RowPitch;
hr = d3dContext->Map(
Texture,
0,  // Subresource
D3D11_MAP_READ,
0,  // MapFlags
&mapInfo);

if (FAILED(hr)) {
// If we failed to map the texture, copy it to a staging resource
if (hr == E_INVALIDARG) {
D3D11_TEXTURE2D_DESC desc2;
desc2.Width = desc.Width;
desc2.Height = desc.Height;
desc2.MipLevels = desc.MipLevels;
desc2.ArraySize = desc.ArraySize;
desc2.Format = desc.Format;
desc2.SampleDesc = desc.SampleDesc;
desc2.Usage = D3D11_USAGE_STAGING;
desc2.BindFlags = 0;
desc2.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc2.MiscFlags = 0;

ComPtr<ID3D11Texture2D> stagingTexture;
hr = d3dDevice->CreateTexture2D(&desc2, nullptr, &stagingTexture);
if (FAILED(hr)) {
throw MyException::Make(hr, L"Failed to create staging texture");
}

// copy the texture to a staging resource
d3dContext->CopyResource(stagingTexture.Get(), Texture);

// now, map the staging resource
hr = d3dContext->Map(
stagingTexture.Get(),
0,
D3D11_MAP_READ,
0,
&mapInfo);
if (FAILED(hr)) {
throw MyException::Make(hr, L"Failed to map staging texture");
}

mappedTexture = std::move(stagingTexture);
} else {
throw MyException::Make(hr, L"Failed to map texture.");
}
} else {
mappedTexture = Texture;
}
auto unmapResource = Finally([&] {
d3dContext->Unmap(mappedTexture.Get(), 0);
});

[...]

hr = frameEncode->WritePixels(
desc.Height,
mapInfo.RowPitch,
desc.Height * mapInfo.RowPitch,
reinterpret_cast<BYTE*>(mapInfo.pData));
if (FAILED(hr)) {
throw MyException::Make(hr, L"frameEncode->WritePixels(...) failed.");
}
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector