从ID3D11资源读取像素

问题描述 投票:0回答:1

我已经将场景渲染为纹理(RTT,渲染为纹理)。在此过程中,渲染目标为prtv [ID3DRenderTargetView *],相应的纹理为ptextureRTV [ID3D11Resource *]。

现在,我想从鼠标所在的位置读取一个像素并发现错误。为了弄清楚错误的出处,我转向打印出纹理以查看其含义。

我创建D3D11_USAGE_STAGING资源ptextureStaging [ID3D11Resource *]并将ptextureRTV复制到ptextureStaging。然后,我映射ptextureStaing,使用其数据创建.ppm图像并取消映射。但是,该图像不是我想要的图像。.ppm image generated by myself

我也尝试使用SaveDDSTextureToFile将纹理存储到.dds图像中。它真的很好。 enter image description here

这是我的代码:

创建DDS图像(通过并更正):

DirectX::SaveDDSTextureToFile(pdx11_unit->pdevCon.Get(), ptextureRTV.Get(), L"Image/image.dds");

复制并映射:

RenderToTexture();//prepare texture
pdx11_unit->pdevCon->CopyResource(ptextureStaging.Get(), ptextureRTV.Get());//copy data to staing texutre
D3D11_MAPPED_SUBRESOURCE mappedResource;
ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
pdx11_unit->pdevCon->Map(ptextureStaging.Get(), 0, D3D11_MAP_READ, 0, &mappedResource);//map to cpu memory
_pixel *pdata = (_pixel*)mappedResource.pData;
//create .ppm image
ofstream image("Image/image.ppm", ios::out | ios::binary | ios::trunc);
image << "P3\n" << Win32Unit::realWidth << " " << Win32Unit::realHeight << "\n255\n";
for (int i = Win32Unit::realHeight - 1; i >= 0; i--)
{
    for (int j = 0; j < Win32Unit::realWidth; j++) {
        int ir = pdata[i*Win32Unit::realWidth + j].r;
        int ig = pdata[i*Win32Unit::realWidth + j].g;
        int ib = pdata[i*Win32Unit::realWidth + j].b;
        image << ir << ' ' << ig << ' ' << ib << '\n';
    }
}
pdx11_unit->pdevCon->Unmap(ptextureStaging.Get(), 0);
directx-11
1个回答
0
投票

我已经找到原因了。如果我现在具有大小为784x561的纹理并且想要读取(i,j)处的像素,则查询((_pixel *)mappedResource.pdata)[i * 784 + j]是错误的,因为被映射的资源的width = 800其实。此宽度等于mappingResouce.RowPitch / sizeof(_pixel)。因此,要将像素加载到CPU内存中,正确的代码是:

int slicePitch = Win32Unit::realHeight*Win32Unit::realWidth;
int rowCount = Win32Unit::realHeight;
int rowPitch = Win32Unit::realWidth;

std::unique_ptr<_pixel[]> pixels(new (std::nothrow) _pixel[slicePitch]);
_pixel* dptr = pixels.get();
_pixel* sptr = (_pixel*)mappedResource.pData;
for (int i = 0; i < rowCount; i++) {
    memcpy_s(dptr, rowPitch * sizeof(_pixel), sptr, rowPitch * sizeof(_pixel));
    dptr += rowPitch;
    sptr += mappedResource.RowPitch / sizeof(_pixel);
}
© www.soinside.com 2019 - 2024. All rights reserved.