2016-11-07 6 views
0

Ich arbeite an einem DirectX C++/CX (Universal Windows) -Projekt.So fügen Sie eine Variable zu einem Konstantspuffer hinzu

Ich bin übrigens nicht sehr vertraut mit DirectX11.

Mein Code basiert hauptsächlich auf den Beispielprojekten auf MSDN im Zusammenhang mit Rendering DirectX in UWP mit Swapchainpanels.

Jetzt wollte ich eine Float-Variable zum Shader hinzufügen. Ich glaube, das muss mit dem Konstantspuffer gemacht werden. Derzeit ist dies wie folgt (und arbeitet):

//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; 
}; 

Nun, wenn ich einen Schwimmer hinzufügen, es nicht mehr funktioniert. Es wirft eine Ausnahme, wenn ich den konstanten Puffer aktualisieren (die vor jedem Frame gerendert geschieht):

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

Die Ausnahme ist ein SEHException (so weit, wie ich finden kann, bedeutet dies sagen Sie mir nichts).

Ich bin stützen diese alle auf der folgenden Seite: https://msdn.microsoft.com/en-us/library/ff476896(v=vs.85).aspx

Kann mir jemand sagen, was mache ich falsch?

Antwort

2

Konstante Puffer haben eine Größe, die auf 16 Bytes ausgerichtet ist. Wenn Sie am Ende einen einzelnen Puffer hatten, blasen Sie tatsächlich die konstante Puffergröße um 16 auf, aber auf der Codepage bläst Ihre Struktur nur um 4. Was passiert Diese UpdateSubResource versucht, diese 12 zusätzlichen Bytes zu lesen und eine Speicherzugriffsverletzung zu erzeugen.

Sie sollten in der Lage sein, die Dinge zu beheben, indem die Polsterung Hinzufügen wie die

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

Sie können, um weitere Informationen über die Polsterung Regeln hier lesen: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx

+0

Wenn Ihre Argumentation ist richtig, und das ist die Kernproblem, dann wäre es einfacher und sicherer, ein 'XMFLOAT4X4A' anstelle des' XMFLOAT4X4's zu verwenden. Die Polsterung ist somit nicht mehr notwendig. – IInspectable

+0

@Intspectable Nicht wirklich, einige Regeln sind subtiler und können nicht mit der C++ - Sprache reproduziert werden, selbst wenn dies im OP-Fall der Fall wäre. Eine andere Lösung wäre, die korrekte Größe des Codeobjekts an "UpdateSubResource" zu liefern, aber dann würde die Debugschicht das Protokoll mit einer Warnung überfluten, dass Sie weniger als die Puffergröße hochladen (das ist in unserem Fall 100% sicher). – galop1n

+0

Danke, ja das behebt es. Ich weiß jetzt, dass sie das auf diesen msdn-Seiten sagen wollten (aber ich denke, sie hätten viel klarer sein können). Es wäre auch nützlich gewesen, wenn die Ausnahme nützliche Informationen enthalten würde. : | – Stef

Verwandte Themen