Direct3D11: перелистывание ID3D11Texture2D
Я выполняю захват заднего буфера Direct3D. Когда я загружаю пиксели, кадр изображения переворачивается вдоль его вертикальной оси. Можно ли "сказать" D3D перевернуть кадр при копировании ресурса или при создании цели ID3D11Texture2D
?
Вот как я это делаю:
Текстура, в которую я копирую буфер кадра, создается так:
D3D11_TEXTURE2D_DESC description =
{
desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1,
DXGI_FORMAT_R8G8B8A8_UNORM,
{ 1, 0 }, // DXGI_SAMPLE_DESC
D3D11_USAGE_STAGING,//transder from GPU to CPU
0, D3D11_CPU_ACCESS_READ, 0
};
D3D11_SUBRESOURCE_DATA data = { buffer, desc.BufferDesc.Width * PIXEL_SIZE, 0 };
device->CreateTexture2D(&description, &data, &pNewTexture);
Затем на каждом кадре я делаю:
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast< void** >(&pSurface));
pContext->CopyResource(pNewTexture, pSurface);
D3D11_MAPPED_SUBRESOURCE resource;
pContext->Map(pNewTexture, 0, D3D11_MAP_READ , 0, &resource);
//reading from resource.pData
//...
PS: у меня нет контроля над конвейером рендеринга. Я подключаю внешнее приложение с этим кодом. Кроме того, я не хочу связываться с пиксельным буфером на процессоре, как обратное копирование в цикле и т. Д. Низкая задержка копирования является высоким приоритетом.
ОБНОВИТЬ:
Я также попробовал это:
D3D11_BOX box;
box.left = 0;
box.right = desc.BufferDesc.Width;
box.top = desc.BufferDesc.Height;
box.bottom = 0;
box.front = 0;
box.back = 1;
pContext->CopySubresourceRegion(pNewTexture, 0, 0, 0, 0, pSurface, 0, &box);
Что заставляет фрейм быть пустым от его содержания.
2 ответа
Создайте текстуру с D3D11_USAGE_DEAFULT, с CPUAccessFlags=0 и BindFlags=D3D11_BIND_SHADER_RESOURCE. CopyResource к нему буфер буфера обмена. Создайте еще одну текстуру с помощью D3D11_BIND_RENDER_TARGET. Установите его как цель рендеринга, установите пиксельный шейдер и нарисуйте перевернутый квад, используя первую текстуру. Теперь вы сможете скопировать вторую текстуру в промежуточную текстуру, которую вы используете сейчас. Это должно быть быстрее, чем копирование данных перевернутого изображения с использованием процессора. Однако это решение потребует больше ресурсов на графическом процессоре и может быть сложным в настройке.
Все подключенные к Direct3D ресурсы должны обрабатываться построчно, так что просто переверните копию:
auto ptr = reinterpret_cast<const uint8_t>(resource.pData)
+ (desc.BufferDesc.Height - 1) * resource.RowPitch;
for(unsigned int y = 0; y < desc.BufferDesc.Height; ++y )
{
// do something with the data in ptr
// which is desc.BufferDesc.Width * BytesPerPixel(desc.Format) bytes
// i.e. DXGI_FORMAT_R8G8B8A8_UNORM would be desc.BufferDesc.Width * 4
ptr -= resource.RowPitch;
}
Для многих примеров работы с ресурсами Direct3D см. DirectXTex.