铸造自定义矩阵浮动*
Casting custom Matrix to float*
所以我断断续续地编写自己的物理引擎已经有一段时间了,最近我开始设置DirectX渲染,而不是用OpenGL硬编码渲染。现在,在最后,我遇到了一些我无法理解的非常奇怪的行为。
为了将矩阵传递给着色器以绘制内容,可以调用一个使用const float*
的函数,而执行此操作的典型方法是将D3DXMATRIX
强制转换传递给float*
。D3DXMATRIX
和强制转换运算符声明为:
typedef struct D3DXMATRIX : public D3DMATRIX
{
...
operator FLOAT* ();
operator CONST FLOAT* () const;
....
} D3DXMATRIX, *LPD3DMATRIX;
并且CCD_ 5被声明为:
typedef struct _D3DMATRIX {
union {
struct {
float __11, _12, _13, _14;
float __21, _22, _23, _24;
float __31, _32, _33, _34;
float __41, _42, _43, _44;
};
float m[4][4];
};
} D3DMATRIX;
在不同的文件(D3DX10math.inl)中,这两个铸造运算符定义为:
D3DX10INLINE
D3DXMATRIX::operator FLOAT* ()
{
return (FLOAT *) &_11;
}
D3DX10INLINE
D3DXMATRIX::operator CONST FLOAT* () const
{
return (CONST FLOAT *) &_11;
}
CONST
和FLOAT
关键字在minwindef.h
中定义,D3DX10INLINE
在D3DX10.h中定义为:
#ifndef CONST
#define CONST const
#endif
....
typedef float FLOAT;
....
#define D3DX10INLINE __forceline
对我描述的函数的调用很简单:
D3DXMATRIX m;
foo->SetMatrix((float*)&m);
在我的整个引擎中,我一直在使用我自己的Matrix
类,当我试图将它传递到上面的函数而不是D3DXMATRIX
时,它会发送不正确的数据。我的Matrix
类(似乎)以与D3DXMATRIX
相同的方式定义,但拒绝以相同的方式工作。这是我的矩阵类(或相关部分):
class Matrix {
public:
....
operator float* ();
operator const float* () const;
....
private:
union {
struct {
float _00, _01, _02, _03;
float _10, _11, _12, _13;
float _20, _21, _22, _23;
float _30, _31, _32, _33;
};
float m[4][4];
}
};
功能定义为:
__forceinline
Matrix::operator float* ()
{
return (float *) &_00;
}
__forceinline
Matrix::operator const float* () const
{
return (const float *) &_00;
}
我已经尝试在CPP文件、头文件和类定义中定义运算符,无论是否使用inline
和__forceinline
,但没有什么能使它工作。我想我可以将每个矩阵中的所有数据复制到D3DXMATRIX
,但这会浪费大量的时间/操作,应该无关紧要。最大的问题是,我一辈子都无法弄清楚为什么一切都会这样。我不知道为什么。
为了确保数据被传递到DirectX函数中,我设置了一个测试函数,这样我就可以调试它,并查看传递的确切值:
void Test(const float *a, const float *b)
{
bool result[16] = {false};
float aa[16], bb[16];
for(unsigned int i = 0; i < 16; ++i)
{
result[i] = a[i] == b[i];
aa[i] = a[i];
bb[i] = b[i];
}
}
例如,如果我传入一个D3DXMATRIX
,其中16个浮点中的每个浮点的值为1-16
,作为第一个参数,其中一个矩阵的值与b
相同,则aa
将填充值1-16
,但bb
将={0.0, 1.875, 0.0, 2.0, 0.0, 2.125, 0.0, 2.5, 0.0, 2.315, 0.0, 2.375, 0.0, 2.4375, 0.0, 2.5}
所以。。。有人知道为什么这个代码会这样做吗?
您实际上使用operator float*
不正确。
D3DXMATRIX m;
foo->SetMatrix((float*)&m);
在这里,您可以将m
的地址转换为float*
。这不是调用operator float
,它只是一个reinterpret_cast
(编译器应该对此发出警告)。但幸运的是,D3DMATRIX
不包含任何其他成员,一开始也没有填充,所以一切都正常。
如果Matrix
在其_00
之前包含其他数据成员,或者不是标准布局,则这种转换可能产生不确定的结果。
所以底线是,你应该做
foo->SetMatrix((float*)m);
或者只是
foo->SetMatrix(m);
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 如何正确实现和访问运算符的各种自定义枚举器
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 自定义先决条件对移动分配运算符有效吗
- 使用VS Code和CMake Tools运行自定义命令
- 如何创建从Maya(或类似程序)到虚幻引擎的自定义数据导出插件
- std::ranges::elements_view,用于自定义类似元组的数据
- 跟随整数索引列表的自定义类迭代器
- 参数化自定义CMake工具链
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 如何在自定义类中启用'auto loops'?
- 使用QJsEngine在Qt中注册自定义类型
- Qt自定义QPush按钮未显示在布局上
- 自定义对象的dlib序列化在gcc中失败
- 自定义创建QFuture
- 如何在QT中的自定义视频小工具t上绘制矩形