2014-12-01 113 views
2

讓我的CBuffer在HLSL中變得非常沮喪D3D11沒有更新,初始值在應用程序啓動時設置,但更新是NoGo,使用UpdateSubResource,也嘗試過ID3D11DeviceContext :: Map & ID3D11DeviceContext :: UnMap。Constant Buffer DirectX 11

注意:使用D3D11_USAGE_DYNAMIC設置CBuffer & 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; 
}; 
+0

因此,經過另一次仔細觀察,似乎當我「映射」資源時,常量緩衝區指針的值沒有得到更新。 – Sixjac 2014-12-01 22:25:09

+0

如果您正在更新整個CB,請使用「 D3D11_MAP_WRITE_DISCARD''。另外,你在哪裏設置常量緩衝區來使用? 「VS_CBUFFER_DATA」的結構定義在哪裏? – 2014-12-02 08:02:43

+0

嗨查克,是的,我一直這樣做,我的場景就消失了,VS_CBUFFER_DATA是3個XMFLOAT4X4的w,v&p矩陣16字節對齊。我通過UpdateSubResource更新了世界矩陣。乾杯 – Sixjac 2014-12-02 08:57:26

回答

0

好的,我使用反射來檢查緩衝區的大小的精確度,該問題被證明是下面的行:

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

我省略了它,只是使用了memcpy和從反射查詢返回的緩衝區的大小。

感謝您的幫助,雖然傢伙。

1

你的問題是在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來查詢數組的大小,尤其是避免使用指針(除非您需要)。

+0

斑點!請注意,你可以使用''memcpy(cbData,&m_CBufferData,sizeof(* cbData));''但我認爲memcpy(cbData,&m_CBufferData,sizeof(VS_CBUFFER_DATA));''選項更清晰。 – 2014-12-02 19:34:12

+0

是的,謝謝你,大小的事情正在進行,因爲當我取消資源的訪問衝突時,CBuffer被設置爲相同的大小,所以不知道什麼是... – Sixjac 2014-12-03 01:22:22