为什么我的D3D11常量缓冲区中WrapUV布尔值无法正常更新?
D3D11常量缓冲区布尔值无法更新问题解决方案
问题根因
问题本质是C++与HLSL的bool类型大小不匹配,加上结构体填充字节的不确定性共同导致的:
- HLSL中
bool类型固定占用4字节内存,只要这4字节中存在非0值,就会被判定为TRUE - 标准C中
bool类型默认仅占用1字节,你的C结构体中bool WrapUV后面会自动补3个字节的对齐填充,这部分填充字节的值是未初始化的随机值 - 你将整个结构体拷贝到常量缓冲区时,HLSL读取
WrapUV字段时会把bool本身的1字节 + 后面3字节随机填充当作一个完整的4字节bool值,几乎必然会出现非0值,所以始终返回TRUE;而前面的float Alpha大小和两边对齐完全匹配,所以更新正常。
可行解决方案
任选一种即可:
- 方案1:将C端
WrapUV的类型替换为32位整型,保证与HLSL端大小完全匹配,赋值时用0代表false,非0代表true
修改后的C结构体示例:
struct PSMaterialTransform { float Alpha; uint32_t WrapUV; // 也可替换为Win32 BOOL类型 XMFLOAT2 padding; } static m_PSMaterialTransformDesc;
- 方案2:将两端
WrapUV的类型统一改为float,用0.0f代表false,1.0f代表true,也可规避类型不匹配问题 - 方案3:如果不想修改字段类型,也可以在赋值后手动清空C++结构体中
WrapUV后面的3个填充字节,不过可维护性较差,更推荐上面两种方案。
内容的提问来源于stack exchange,提问作者Stark
相关产品推荐
相关产品推荐

