为结构体C++分配HLSL变量

Assign struct C++ with HLSL variable

本文关键字:HLSL 变量 分配 C++ 结构体      更新时间:2023-10-16

我刚开始使用DirectX,所以我遇到了这个问题:

我正在尝试将HLSL变量中的一个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++发送到HLSL中的"L1",但我不确定HLSL中L1类型的正确性。这个代码是有效的,但我在L1中的整个参数也得到了0…我不知道如何解决这个问题,我在谷歌上搜索了5个小时,没有结果。。。请帮忙。

谢谢你的帮助。

首先,如果您是DirectX编程的新手,我建议不要投资DirectX 10。您应该使用DirectX 11,因为它得到了更好的支持,有更多相关的实用程序代码,并且在所有支持DirectX 10的平台上都受到支持。此外,您使用的是传统的D3DX数学,因此您肯定应该再次转向更现代的开发环境。现在很少有理由使用传统的DirectX SDK。请参阅此博客文章和MSDN以获取此处的背景信息。你会发现DirectX工具包和它的教程是一个很好的起点。如果您真的想使用效果系统,请参见效果11。

请记住,HLSL常量缓冲区使用打包和对齐的方式与标准C/C++结构略有不同。如果你尽可能坚持使用4向量结构,而不是使用3向量版本,你会得到更直观的行为。理论上,您的C/C++和HLSL结构是将数据打包成单个4向量的"匹配"结构,但各种编译器设置和打包规则可能会使其失效。请参阅常量变量的打包规则。验证这一点的一个好方法是使用static_assert:

static_assert(sizeof(L1) == 16, "CB/struct mismatch");

问题很可能是你对效果系统的使用。由于查找失败,L1Var可能是一个伪变量,因此SetRawValue不会执行任何操作。从您提供的HLSL片段中,我不清楚您的L1 HLSL变量是否是一个常量缓冲区。尝试一些调试代码:

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");
}