在 Windows 应用商店应用中映射 Direct3D11 中的动态缓冲区

Mapping a dynamic buffer in Direct3D11 in a Windows Store App

本文关键字:应用 动态缓冲区 Direct3D11 映射 Windows      更新时间:2023-10-16

我正在尝试在 Direct3D11 中创建实例化几何图形,当我尝试更新实例缓冲区时,ID3D11DeviceContext1->Map()调用失败并出现非常有用的"参数无效"错误。

缓冲区声明为成员变量:

Microsoft::WRL::ComPtr<ID3D11Buffer> m_instanceBuffer;

然后我创建它(成功):

D3D11_BUFFER_DESC instanceDesc;
ZeroMemory(&instanceDesc, sizeof(D3D11_BUFFER_DESC));
instanceDesc.Usage = D3D11_USAGE_DYNAMIC;
instanceDesc.ByteWidth = sizeof(InstanceData) * MAX_INSTANCE_COUNT;
instanceDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
instanceDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
instanceDesc.MiscFlags = 0;
instanceDesc.StructureByteStride = 0;
DX::ThrowIfFailed(d3dDevice->CreateBuffer(&instanceDesc, NULL, &m_instanceBuffer));

但是,当我尝试映射它时:

D3D11_MAPPED_SUBRESOURCE inst;
DX::ThrowIfFailed(d3dContext->Map(m_instanceBuffer.Get(), 0, D3D11_MAP_WRITE, 0, &inst));

映射调用失败,并显示 E_INVALIDARG 。 没有什么NULL不正确的,这是我的第一个D3D应用程序之一,我目前不知道下一步该怎么做才能追踪它。 我想我一定是错误地创建了缓冲区,但我看不出如何。 任何意见将不胜感激。

因为缓冲区是用D3D11_USAGE_DYNAMIC创建的,所以它必须用D3D_MAP_WRITE_DISCARD(或D3D_MAP_WRITE_NO_OVERWRITE映射,但这不适合我的应用程序)。

当我尝试为着色器创建缓冲区时,我遇到了同样的问题。在createBuffer它总是会给我E_INVALIDARG.我的项目的问题是,我忘记将所有属性对齐到 16 字节。下面是一个示例:

struct TessellationBufferType
{
    float tessellationAmount; //4bytes
    D3DXVECTOR3 cameraPosition; //12bytes
};

如果您没有得到 16,请添加一个额外的变量(例如填充)以对齐最多 16:

struct LightBufferType
{
    D3DXVECTOR4 ambientColor; //16
    D3DXVECTOR4 diffuseColor; //16
    D3DXVECTOR3 lightDirection; //12
    float padding; //4
};