DirectX::XMMATRIX 函数传递后乘法不正确 (C++)
DirectX::XMMATRIX Multiplication incorrect after function pass (C++)
我无法理解为什么将两个 DirectX 4x4 矩阵相乘时会得到不同的结果,这取决于乘法是否在 class 函数中执行。
以恒等矩阵为例,result1 和 result2 的值最终不同,使用以下代码。
#include <iostream>
#include <DirectXMath.h>
using namespace DirectX;
class Model {
public:
XMMATRIX MatrixMult(XMMATRIX test) {
XMMATRIX result = test * XMMatrixIdentity();
return result;
}
private:
};
int main() {
Model m;
XMMATRIX result1 = XMMatrixIdentity() * XMMatrixIdentity(); //returns identity
XMMATRIX result2 = m.MatrixMult(XMMatrixIdentity()); //doesn't return identity
int height = 4;
int width = 4;
//Output results
XMMATRIX results[2] = { result1, result2 };
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
if (j == 0) {
std::cout << XMVectorGetX(results[res].r[i]) << ' ';
}
else if (j == 1) {
std::cout << XMVectorGetY(results[res].r[i]) << ' ';
}
else if (j == 2) {
std::cout << XMVectorGetZ(results[res].r[i]) << ' ';
}
else if (j == 3) {
std::cout << XMVectorGetW(results[res].r[i]) << ' ';
}
}
std::cout << std::endl;
}
std::cout << "\n";
}
return 0;
}
其实在result2中看起来,预期的结果是从矩阵的第3行开始的? (下面的输出)
//result1
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
//result2
8.2597e-39 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
1 0 0 0
0 1 0 0
我知道通过将数组作为函数传递我正在制作它的副本,但我不认为这会对这里产生影响。
如有任何帮助,我们将不胜感激!
TL;DR:这是一个编译器错误,可能是由于 code-generation.
只有在使用 x86(32 位)编译器时才会出现奇怪的输出,而在使用 x64(64 位)本机编译器时不会出现。我尝试了几种不同的方法来输出结果,它们对于 x86 来说一直很奇怪,但对于 x64 来说是正确的。
它似乎发生在调试和发布(优化)配置中,以及 /fp:fast
和 /fp:precise
。
如果您使用 /arch:IA32
.
,x64 本机代码或 x86 不会不会发生这种情况
我能够用 VS 2017 (15.9.11) 和 VS 2019 (16.0.3) 重现同样的问题。
#include <iostream>
#include <stdio.h>
#include <DirectXMath.h>
using namespace DirectX;
class Model {
public:
XMMATRIX MatrixMult(XMMATRIX test) {
XMMATRIX result = test * XMMatrixIdentity();
return result;
}
private:
};
int main() {
Model m;
XMMATRIX result1 = XMMatrixIdentity() * XMMatrixIdentity(); //returns identity
XMMATRIX result2 = m.MatrixMult(XMMatrixIdentity()); //doesn't return identity
int height = 4;
int width = 4;
//Output results
#if 0
XMFLOAT4X4 mat[2];
XMStoreFloat4x4(&mat[0], result1);
XMStoreFloat4x4(&mat[1], result2);
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
printf("%f %f %f %f\n",
mat[res].m[i][0], mat[res].m[i][1], mat[res].m[i][2], mat[res].m[i][3]);
}
}
#elif 0
XMFLOAT4X4 mat[2];
XMStoreFloat4x4(&mat[0], result1);
XMStoreFloat4x4(&mat[1], result2);
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
std::cout << mat[res].m[i][j] << ' ';
}
std::cout << std::endl;
}
std::cout << "\n";
}
#else
XMMATRIX results[2] = { result1, result2 };
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
if (j == 0) {
std::cout << XMVectorGetX(results[res].r[i]) << ' ';
}
else if (j == 1) {
std::cout << XMVectorGetY(results[res].r[i]) << ' ';
}
else if (j == 2) {
std::cout << XMVectorGetZ(results[res].r[i]) << ' ';
}
else if (j == 3) {
std::cout << XMVectorGetW(results[res].r[i]) << ' ';
}
}
std::cout << std::endl;
}
std::cout << "\n";
}
#endif
return 0;
}
您应该使用帮助 -> 发送反馈 -> 报告问题... 来报告错误。请务必提及它适用于 VS 2017 和 VS 2019。
我无法理解为什么将两个 DirectX 4x4 矩阵相乘时会得到不同的结果,这取决于乘法是否在 class 函数中执行。
以恒等矩阵为例,result1 和 result2 的值最终不同,使用以下代码。
#include <iostream>
#include <DirectXMath.h>
using namespace DirectX;
class Model {
public:
XMMATRIX MatrixMult(XMMATRIX test) {
XMMATRIX result = test * XMMatrixIdentity();
return result;
}
private:
};
int main() {
Model m;
XMMATRIX result1 = XMMatrixIdentity() * XMMatrixIdentity(); //returns identity
XMMATRIX result2 = m.MatrixMult(XMMatrixIdentity()); //doesn't return identity
int height = 4;
int width = 4;
//Output results
XMMATRIX results[2] = { result1, result2 };
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
if (j == 0) {
std::cout << XMVectorGetX(results[res].r[i]) << ' ';
}
else if (j == 1) {
std::cout << XMVectorGetY(results[res].r[i]) << ' ';
}
else if (j == 2) {
std::cout << XMVectorGetZ(results[res].r[i]) << ' ';
}
else if (j == 3) {
std::cout << XMVectorGetW(results[res].r[i]) << ' ';
}
}
std::cout << std::endl;
}
std::cout << "\n";
}
return 0;
}
其实在result2中看起来,预期的结果是从矩阵的第3行开始的? (下面的输出)
//result1
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
//result2
8.2597e-39 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
1 0 0 0
0 1 0 0
我知道通过将数组作为函数传递我正在制作它的副本,但我不认为这会对这里产生影响。
如有任何帮助,我们将不胜感激!
TL;DR:这是一个编译器错误,可能是由于 code-generation.
只有在使用 x86(32 位)编译器时才会出现奇怪的输出,而在使用 x64(64 位)本机编译器时不会出现。我尝试了几种不同的方法来输出结果,它们对于 x86 来说一直很奇怪,但对于 x64 来说是正确的。
它似乎发生在调试和发布(优化)配置中,以及
/fp:fast
和/fp:precise
。如果您使用
/arch:IA32
. ,x64 本机代码或 x86 不会不会发生这种情况
我能够用 VS 2017 (15.9.11) 和 VS 2019 (16.0.3) 重现同样的问题。
#include <iostream>
#include <stdio.h>
#include <DirectXMath.h>
using namespace DirectX;
class Model {
public:
XMMATRIX MatrixMult(XMMATRIX test) {
XMMATRIX result = test * XMMatrixIdentity();
return result;
}
private:
};
int main() {
Model m;
XMMATRIX result1 = XMMatrixIdentity() * XMMatrixIdentity(); //returns identity
XMMATRIX result2 = m.MatrixMult(XMMatrixIdentity()); //doesn't return identity
int height = 4;
int width = 4;
//Output results
#if 0
XMFLOAT4X4 mat[2];
XMStoreFloat4x4(&mat[0], result1);
XMStoreFloat4x4(&mat[1], result2);
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
printf("%f %f %f %f\n",
mat[res].m[i][0], mat[res].m[i][1], mat[res].m[i][2], mat[res].m[i][3]);
}
}
#elif 0
XMFLOAT4X4 mat[2];
XMStoreFloat4x4(&mat[0], result1);
XMStoreFloat4x4(&mat[1], result2);
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
std::cout << mat[res].m[i][j] << ' ';
}
std::cout << std::endl;
}
std::cout << "\n";
}
#else
XMMATRIX results[2] = { result1, result2 };
//for each result
for (int res = 0; res < 2; ++res) {
//for each row
for (int i = 0; i < height; ++i)
{
//for each column
for (int j = 0; j < width; ++j)
{
if (j == 0) {
std::cout << XMVectorGetX(results[res].r[i]) << ' ';
}
else if (j == 1) {
std::cout << XMVectorGetY(results[res].r[i]) << ' ';
}
else if (j == 2) {
std::cout << XMVectorGetZ(results[res].r[i]) << ' ';
}
else if (j == 3) {
std::cout << XMVectorGetW(results[res].r[i]) << ' ';
}
}
std::cout << std::endl;
}
std::cout << "\n";
}
#endif
return 0;
}
您应该使用帮助 -> 发送反馈 -> 报告问题... 来报告错误。请务必提及它适用于 VS 2017 和 VS 2019。