問題描述
使用 HLSL 變量分配 struct C++ (Assign struct C++ with HLSL variable)
我才開始使用 DirectX,所以我遇到了這個問題:
我正在嘗試將一個 c++ 結構推送/發送/分配到/進入/使用具有 HLSL 變量的與來自 C++ 的結構相同的數據類型。
在 C++ 中:
struct Light
{
Light() {
ZeroMemory(this, sizeof(Light));
}
D3DXVECTOR3 LightPos;
float ID;
};
Light L1;
/.../
ID3D10EffectVariable* L1Var = NULL;
/.../
L1Var = Effect‑>GetVariableByName("L1")‑>AsVector();
/.../
L1Var‑>SetRawValue(&L1, 0, sizeof(Light));
HLSL 代碼:
struct Light {
float3 LightPos;
float ID;
};
Light L1;
我正在嘗試將結構從 C++ 發送到“L1”在 HLSL 中,但我不確定 HLSL 中 L1 類型的正確性。這段代碼正在工作,但我在 L1 中的整個參數也得到了 0...我不知道如何解決這個問題,我用谷歌搜索了 5 個小時沒有結果...請幫助。
感謝您的幫助。
參考解法
方法 1:
First if you are new to DirectX programming, I'd suggest not investing in DirectX 10. You should use DirectX 11 as it's far better supported, has a lot more relevant utility code, and is supported on every platform that supports DirectX 10. Furthermore, you are using legacy D3DX math, so again you should definitely move to a more modern development environment. There's very few reasons to use the legacy DirectX SDK today. See this blog post and MSDN for the background here. You will find DirectX Tool Kit and it's tutorials a good starting point. If you really want to stick with the Effect system, see Effects 11.
Keep in mind that HLSL Constant Buffers use packing and alignment in subtly different ways than standard C/C++ structures. You get more intuitive behavior if you stick with 4‑vector structures where possible instead of using 3‑vector versions. In theory your C/C++ and HLSL structures are a 'match' packing the data into a single 4‑vector, but various compiler settings and packing rules might throw that off. See Packing Rules for Constant Variables. A good way to verify that is to use static_assert
:
static_assert(sizeof(L1) == 16, "CB/struct mismatch");
The problem is most likely your usage of the effect system. L1Var
is probably a dummy variable due to a failed lookup, so your SetRawValue
isn't going to do anything. From the snippet of HLSL you've provided, it's not clear to me that your L1
HLSL variable is even a constant buffer. Try some debug code:
auto tempVar = Effect‑>GetVariableByName("L1");
if ( tempVar‑>IsValid() )
{
D3DX10_EFFECT_VARIABLE_DESC desc={0};
tempVar‑>GetDesc(desc);
OutputDebugStringA(desc.Name); // Set a breakpoint here and look at desc
OutputDebugStringA("\n");
}
else
{
OutputDebugStringA("L1 is not valid!\n");
}
(by Misa Gu、Chuck Walbourn)