2016-11-07 9 views
0

Я работаю над проектом Directx C++/CX (Universal Windows).Как добавить переменную в константубуфер

Я не так уж хорошо знаком с Directx11.

Мой код в основном основан на примерах проектов на MSDN, связанных с рендерингом directx в UWP с использованием swapchainpanels.

Теперь я хотел добавить переменную float в шейдер. Я считаю, что это нужно делать с помощью константного буфера. В настоящее время это выглядит следующим образом (и работает):

//c++: 
struct ModelViewProjectionConstantBuffer 
{ 
    DirectX::XMFLOAT4X4 model; 
    DirectX::XMFLOAT4X4 view; 
    DirectX::XMFLOAT4X4 projection; 
    //float distance; 
}; 

//hlsl: 
cbuffer ModelViewProjectionConstantBuffer : register(b0) 
{ 
    matrix model; 
    matrix view; 
    matrix projection; 
    //float distance; 
}; 

Теперь, когда я добавляю поплавок, он перестает работать. Он бросает исключение, когда я обновляю постоянный буфер (который происходит перед каждым оказанным кадром):

_d3dContext->UpdateSubresource(
    _constantBuffer.Get(), 
    0, 
    NULL, 
    &_constantBufferData, 
    0, 
    0 
); 

Исключения составляет SEHException (так, насколько я могу найти, это не говорит мне ничего).

Я основывая все это на следующей странице: https://msdn.microsoft.com/en-us/library/ff476896(v=vs.85).aspx

Может кто-нибудь сказать мне, что я делаю неправильно?

ответ

2

Постоянные буферы имеют размер, выровненный по 16 байт, когда у вас был единственный поплавок в конце, вы фактически увеличиваете размер постоянного буфера на 16, но на стороне кода ваша структура только раздувается на 4. Что происходит что UpdateSubResource попытается прочитать эти 12 дополнительных байтов и вызвать нарушение доступа к памяти.

Вы должны быть в состоянии исправить положение, добавив отступы как этот

struct ModelViewProjectionConstantBuffer 
{ 
    DirectX::XMFLOAT4X4 model; 
    DirectX::XMFLOAT4X4 view; 
    DirectX::XMFLOAT4X4 projection; 
    float distance; 
    float pad[3] 
}; 

Вы можете прочитать о правилах заполнения здесь для получения более подробной информации: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx

+0

Если ваше рассуждение правильно, и это основной проблемой было бы проще и безопаснее использовать «XMFLOAT4X4A» вместо 'XMFLOAT4X4'. Таким образом, отступы больше не нужны. – IInspectable

+0

@IInpectable Не совсем, некоторые правила более тонкие и не могут воспроизводиться с языком C++, даже если в случае OP это будет трюк. Другим решением было бы обеспечить правильный размер объекта кода для «UpdateSubResource», но тогда слой отладки наполнил бы журнал предупреждением о том, что вы загружаете меньше, чем размер cbuffer (что в нашем случае на 100% безопаснее). – galop1n

+0

Спасибо, да, это исправляет. Я понимаю, что это то, что они пытались сказать на этих страницах msdn (но я чувствую, что они могли быть намного понятнее). Было бы также полезно, если бы исключение содержало какую-либо полезную информацию. : | – Stef

 Смежные вопросы

  • Нет связанных вопросов^_^