Directx Direct3D11:翻转ID3D11Texture2D

Directx Direct3D11:翻转ID3D11Texture2D,directx,direct3d,direct3d11,Directx,Direct3d,Direct3d11,我执行Direct3D后缓冲区的捕获。当我下载像素时,图像帧沿其垂直轴翻转。在复制资源时,或在创建目标ID3D11Texture2D时,是否可以“告诉”D3D翻转帧 我是这样做的: 将帧缓冲区复制到其中的纹理如下所示: D3D11_TEXTURE2D_DESC description = { desc.BufferDesc.Width, desc.BufferDesc.Height, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM

我执行Direct3D后缓冲区的捕获。当我下载像素时,图像帧沿其垂直轴翻转。在复制资源时,或在创建目标
ID3D11Texture2D
时,是否可以“告诉”D3D翻转帧

我是这样做的:

将帧缓冲区复制到其中的纹理如下所示:

    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
     //...

这会导致框架内容为空。

所有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;
}
auto ptr=reinterpret\u cast(resource.pData)
+(desc.BufferDesc.Height-1)*resource.RowPitch;
for(无符号整数y=0;y
有关使用Direct3D资源的许多示例,请参见


使用D3D11_USAGE_DEAFULT创建纹理,CPUAccessFlags=0,BindFlags=D3D11_BIND_SHADER_RESOURCE。CopyResource是交换链的backbuffer。使用D3D11_BIND_RENDER_TARGET创建另一个纹理。将其设置为渲染目标,设置像素着色器并使用第一个纹理绘制翻转的四边形。现在,您应该能够将第二个纹理复制到您现在使用的暂存纹理。这应该比使用CPU复制翻转的图像数据更快。但是,此解决方案将占用GPU上的更多资源,并且可能很难在挂钩中设置

不要忘记检查那些返回非
void的函数的
HRESULT
值。您当前假定它始终有效。使用
成功
失败
,或者类似的东西。@ChuckWalbourn实际上一直在做这件事。为了简单起见,这里删除了一个基于多钩子的老项目示例:不知道是否真的对你有帮助…你想对图像数据做什么,以及你如何意识到它被翻转了?你把图像数据复制到hbitmap了吗?HBitmap自底向上存储图像数据。如果您要复制图像数据以显示它,那么按照与Y相反的顺序复制它不会花费太多。@MichaelIV关于您的更新部分,MSDN docs for
ID3D11DeviceContext::CopySubresourceRegion()
声明“空框将导致不可操作。如果顶部值大于或等于底部值,或[…]则框为空。”“。这不是一个选择。我需要的副本是非常快的。我寻找一种方法来做翻转驱动程序或GPU侧。我会强调它在我的问题。如果backbuffer有D3D11_绑定_着色器_资源标志,那么第一个副本可以省略。
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;
}