为结构体C++分配HLSL变量
Assign struct C++ with HLSL variable
我刚开始使用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");
}
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 执行函数时导致崩溃的变量
- 为结构体C++分配HLSL变量