簡體   English   中英

常量緩沖區DirectX 11

[英]Constant Buffer DirectX 11

真正讓HLSL D3D11中的CBuffer感到沮喪的是不更新,在應用程序啟動時設置了初始值,但是更新是不行的,使用UpdateSubResource,還嘗試了ID3D11DeviceContext :: Map和ID3D11DeviceContext :: UnMap。

注意:使用D3D11_USAGE_DYNAMIC和D3D11_CPU_ACCESS_WRITE設置CBuffer。

我的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;
};

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

好的,我使用反射來檢查緩沖區大小的准確性,問題出在以下代碼行:

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

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

謝謝你們的幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM