首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >texture2d资源在directx11中的读取

texture2d资源在directx11中的读取
EN

Game Development用户
提问于 2019-08-29 16:55:54
回答 1查看 293关注 0票数 1

嗨^^我正在尝试读取资源中的数据,我以前做得很好,没有任何问题。但突然间它就不起作用了。

  1. 首先,我创建了包含数据的不可变资源,这里是XMFLOAT4(1,1,1,1)
  2. 接下来,我创建了用于阅读的分阶段资源。
  3. 最后,我调用map/unmap读取数据并将其存储到outputArr中。
代码语言:javascript
运行
复制
//(all HRESULT checked already)
    int WIDTH = 10, HEIGHT = 2;

    ID3D11Texture2D* resource; // create texture------------------------------
    D3D11_TEXTURE2D_DESC texDesc;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    texDesc.Usage = D3D11_USAGE_IMMUTABLE;
    texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    texDesc.Width = WIDTH;
    texDesc.Height = HEIGHT;
    texDesc.CPUAccessFlags = 0;
    texDesc.ArraySize = 1;
    texDesc.MipLevels = 1;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.MiscFlags = 0;

    XMFLOAT4* initValues = new XMFLOAT4[WIDTH * HEIGHT];
    for (int i = 0; i < WIDTH * HEIGHT; ++i) {
        initValues[i] = XMFLOAT4(1,1,1,1);
    }
    D3D11_SUBRESOURCE_DATA data;
    data.pSysMem = initValues;
    data.SysMemPitch = sizeof(XMFLOAT4)*WIDTH;
    data.SysMemSlicePitch = 0;
    device->CreateTexture2D(
        &texDesc,
        &data,
        &resource);

    ID3D11Texture2D* staging; // create texture for reading --------------------
    D3D11_TEXTURE2D_DESC stgDesc;
    stgDesc.BindFlags = 0;
    stgDesc.Usage = D3D11_USAGE_STAGING;
    stgDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    stgDesc.Width = WIDTH;
    stgDesc.Height = HEIGHT;
    stgDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    stgDesc.ArraySize = 1;
    stgDesc.MipLevels = 1;
    stgDesc.SampleDesc.Count = 1;
    stgDesc.SampleDesc.Quality = 0;
    stgDesc.MiscFlags = 0;
    device->CreateTexture2D(
        &stgDesc,
        nullptr,
        &staging);

    XMFLOAT4* outputArr = new XMFLOAT4[WIDTH*HEIGHT]; // READ-------------------
    dContext->CopyResource(staging, resource);
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
    dContext->Map(staging, 0, D3D11_MAP_READ, 0, &mappedResource);

    outputArr = reinterpret_cast<XMFLOAT4*>(mappedResource.pData);
    std::vector<XMFLOAT4> testV;
    for (int y = 0; y < HEIGHT; ++y)
    {
        for (int x = 0; x < WIDTH; ++x)
        {
            int idx = y * WIDTH + x;

            testV.push_back(outputArr[idx]);
        }
    }

    dContext->Unmap(staging, 0);

结果是,只有当WIDTH是16的倍数时(HEIGHT在这里似乎并不重要),它才能很好地将数据复制到数组的所有元素中,否则它只将0填充到数组中,直到下一个16个元素。

例如,如果宽度/高度为10/2,则outputArr的前10个元素将有适当的数据,接下来的6个元素只有0,接下来的10个元素包含数据,6个元素包含0,依此类推。

我在处理资源方面没有任何问题。还在挣扎。只是我的假设是,在我错过的资源宽度中,可能会有特定的对齐。或者在我的过程中犯了愚蠢的错误。

希望任何人都能从这个问题中找到点什么。谢谢

EN

回答 1

Game Development用户

回答已采纳

发布于 2019-08-30 03:06:02

我已经找到了解决办法。它看起来很漂亮。

testV.push_back(outputArr[idx])应该被编辑成

testV.push_back(((XMFLOAT4*)((char*)mappedResource.pData + (y* mappedResource.RowPitch) + (x*sizeof(XMFLOAT4))))->y)

我第一次想到,当我用xmfloat4制作WIDTH * HEIGHT时,它的尺寸将是16*WIDTH*HEIGHT。但这是错误的!里面有一些自动填充物。所以实际大小应该是(16*WIDTH + padding)*HEIGHT。我不知道为什么,只是猜测因为纹理可以覆盖很多不同的类型,所以它会自动为类型做不同的填充?也许吧

如果有人知道原因,请告诉我。

谢谢

票数 1
EN
页面原文内容由Game Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://gamedev.stackexchange.com/questions/175067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档