恒定缓冲区DirectX 11

时间:2014-12-01 22:04:46

标签: c++ shader directx-11 hlsl

在HLSL D3D11中我的CBuffer没有更新真的很沮丧,初始值在应用程序启动时设置但是更新是不行,使用UpdateSubResource,也尝试了ID3D11DeviceContext :: Map& ID3D11DeviceContext ::取消映射。

注意:使用D3D11_USAGE_DYNAMIC& D3D11_CPU_ACCESS_WRITE。

我的ID3D11Buffer(常量缓冲区)在查询大小时只返回4个字节....听起来像是问题的一部分

struct VS_CBUFFER_DATA
{
    XMFLOAT4X4 world;
    XMFLOAT4X4 view;
    XMFLOAT4X4 projection;

    VS_CBUFFER_DATA()
    {
        XMStoreFloat4x4(&world, DirectX::XMMatrixIdentity());
        XMStoreFloat4x4(&view, DirectX::XMMatrixIdentity());
        XMStoreFloat4x4(&projection, DirectX::XMMatrixIdentity());
    }
};

D3D11_BUFFER_DESC cbufferDesc;
memset(&cbufferDesc, 0, sizeof(cbufferDesc));

cbufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER
cbufferDesc.Usage = D3D11_USAGE_DYNAMIC;
cbufferDesc.ByteWidth = sizeof(m_CBufferData);
cbufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbufferDesc.MiscFlags = 0;
cbufferDesc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA subdata;
memset(&subdata, 0, sizeof(subdata));

subdata.pSysMem = &m_CBufferData;

if (FAILED(pRendererTemp->CreateBuffer(cbufferDesc
{
    OutputDebugString("Failed to create CBuffer!")
    goto failed;
}

void Cube::UpdateViewProjection(__in const Renderer* pRenderer, __in const    XMFLOAT4X4   &view, __in const XMFLOAT4X4 &proj)
{
    D3D11_MAPPED_SUBRESOURCE mappedSubResource;
    memset(&mappedSubResource, 0, sizeof(mappedSubResource));

    if (SUCCEEDED(pRenderer->GetDevContext()->Map(m_pCBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE,  0, &mappedSubResource))) 
    {
        Primitive::UpdateViewProjection(NULL, view, proj);
        VS_CBUFFER_DATA* cbData = (VS_CBUFFER_DATA*)&mappedSubResource.pData;

        memcpy(cbData, &m_CBufferData, sizeof(cbData));
        pRenderer->GetDevContext()->Unmap(m_pCBuffer, 0);
        SetBuffers(pRenderer);
    }
}

// SHADER.vsh
cbuffer cbMatrixBuffer : register(b0)
{
    float4x4 world;
    float4x4 view;
    float4x4 projection;
};

2 个答案:

答案 0 :(得分:2)

您的问题出在memcpy。这一行:

memcpy(cbData, &m_CBufferData, sizeof(cbData));

正在复制一个等于VS_CBUFFER_DATA指针大小的字节数,该指针在32位系统上是4个字节(x64上为8个字节)。代码应为:

memcpy(cbData, &m_CBufferData, sizeof(VS_CBUFFER_DATA));

将复制48个字节的数据而不是4/8(无论sizeof(void*)评估为何)。

一般情况下,避免使用sizeof来查询数组的大小,特别是避免使用指针(除非你需要它)。

答案 1 :(得分:0)

好的,我用反射来检查缓冲区大小的准确性,问题结果如下:

VS_CBUFFER_DATA * cbData =(VS_CBUFFER_DATA *)& mappedSubResource.pData;

我省略了它,只使用了memcpy和从反射查询返回的缓冲区大小。

感谢你们的帮助。