无法在Direct3D 11

时间:2017-10-31 07:54:53

标签: directx textures directx-11 direct3d direct3d11

我试图在系统内存中生成一个表示R8G8B8A8纹理的简单数组,然后将该纹理传输到GPU内存。

首先,我分配一个数组并用所需的绿色数据填充它:

    frame.width = 3;
    frame.height = 1;
    auto components = 4;
    auto length = components * frame.width * frame.height;
    frame.data = new uint8_t[length];

    frame.data[0 + 0 * frame.width] = 0;  frame.data[1 + 0 * frame.width] = 255;  frame.data[2 + 0 * frame.width] = 0;  frame.data[3 + 0 * frame.width] = 255;
    frame.data[0 + 1 * frame.width] = 0;  frame.data[1 + 1 * frame.width] = 255;  frame.data[2 + 1 * frame.width] = 0;  frame.data[3 + 1 * frame.width] = 255;
    frame.data[0 + 2 * frame.width] = 0;  frame.data[1 + 2 * frame.width] = 255;  frame.data[2 + 2 * frame.width] = 0;  frame.data[3 + 2 * frame.width] = 255;

然后,我创建纹理对象并将其设置为像素着色器资源:

    D3D11_TEXTURE2D_DESC textureDescription;

    textureDescription.Width = frame.width;
    textureDescription.Height = frame.height;

    textureDescription.MipLevels = textureDescription.ArraySize = 1;
    textureDescription.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    textureDescription.SampleDesc.Count = 1;
    textureDescription.SampleDesc.Quality = 0; 
    textureDescription.Usage = D3D11_USAGE_DYNAMIC;
    textureDescription.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    textureDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    textureDescription.MiscFlags = 0;


    D3D11_SUBRESOURCE_DATA initialTextureData;
    initialTextureData.pSysMem = frame.data;
    initialTextureData.SysMemPitch = frame.width * components;
    initialTextureData.SysMemSlicePitch = 0;

    DX_CHECK(m_device->CreateTexture2D(&textureDescription, &initialTextureData, &m_texture));
    DX_CHECK(m_device->CreateShaderResourceView(m_texture, NULL, &m_textureView));
    m_context->PSSetShaderResources(0, 1, &m_textureView);

我的期望是GPU内存将包含3x1绿色纹理,并且每个纹素在alpha chanel中将具有1.0f。但是,情况并非如此,可以通过Visual Studio图形调试器检查加载的纹理对象来查看:

enter image description here

有人可以解释发生了什么吗?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

让我们来看看你的数组寻址方案(索引会随你提供的尺寸而减少):

frame.data[0] = 0;  frame.data[1] = 255;  frame.data[2] = 0;  frame.data[3] = 255;
frame.data[3] = 0;  frame.data[4] = 255;  frame.data[5] = 0;  frame.data[6] = 255;
frame.data[6] = 0;  frame.data[7] = 255;  frame.data[8] = 0;  frame.data[9] = 255;

重新订购,我们得到

data[ 0] = 0                  B pixel 1
data[ 1] = 255                G pixel 1
data[ 2] = 0                  R pixel 1
data[ 3] = 0  (overwritten)   A pixel 1
data[ 4] = 255                  pixel 2
data[ 5] = 0
data[ 6] = 0
data[ 7] = 255
data[ 8] = 0                    pixel 3
data[ 9] = 255
data[10] = undefined
data[11] = undefined

如您所见,这正是您的调试器向您显示的数据。

所以你只需要修改你的地址方案。正确的公式是:

index = component + x * components + y * pitch,

您使用

定义了密集包装
pitch = width * components

为了得到这个公式,您只需要考虑在增加其中一个变量时必须跳过多少个索引。例如。当你增加当前组件时,你只需要进一步输入一个条目(因为所有组件都紧挨着彼此)。另一方面,如果增加y坐标,则需要跳过与行中一样多的条目(这称为音高,即图像的宽度乘以密集包装的组件数量)。