i am writing a Matrix4 class for an OpenGL game:
我正在为OpenGL游戏编写Matrix4类:
static class Matrix4
{
private:
float matrix[16];
Matrix4 Identity()
{
matrix[1] = matrix[2] =
matrix[3] = matrix[4] = matrix[6] =
matrix[7] = matrix[8] = matrix[9] =
matrix[11] = matrix[12] = matrix[13] = matrix[14] = 0.f;
matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f;
return *this;
}
public:
Matrix4() { Identity(); };
Matrix4(float vals[16])
{
matrix[0] = vals[0]; matrix[1] = vals[1]; matrix[2] = vals[2]; matrix[3] = vals[3];
matrix[4] = vals[4]; matrix[5] = vals[5]; matrix[6] = vals[6]; matrix[7] = vals[7];
matrix[8] = vals[8]; matrix[9] = vals[9]; matrix[10] = vals[10]; matrix[11] = vals[11];
matrix[12] = vals[12]; matrix[13] = vals[13]; matrix[14] = vals[14]; matrix[15] = vals[15];
}
Matrix4(Vector4 vals[4])
{
matrix[0] = vals[0].GetX(); matrix[1] = vals[0].GetY(); matrix[2] = vals[0].GetZ(); matrix[3] = vals[0].GetW();
matrix[4] = vals[1].GetX(); matrix[5] = vals[1].GetY(); matrix[6] = vals[1].GetZ(); matrix[7] = vals[1].GetW();
matrix[8] = vals[2].GetX(); matrix[9] = vals[2].GetY(); matrix[10] = vals[2].GetZ(); matrix[11] = vals[2].GetW();
matrix[12] = vals[3].GetX(); matrix[13] = vals[3].GetY(); matrix[14] = vals[3].GetZ(); matrix[15] = vals[3].GetW();
}
//OPERATOR DEFINITIONS
//STUDY THE operator<< SHIT
static friend std::ostream& operator<< (std::ostream& os, const Matrix4& other)
{
std::string final = "_____________________________________________\n| " + std::to_string(other.matrix[0]) + " " + std::to_string(other.matrix[1]) + " " + std::to_string(other.matrix[2]) + " " + std::to_string(other.matrix[3]) + " " + " |" + "\n" +
"| " + std::to_string(other.matrix[4]) + " " + std::to_string(other.matrix[5]) + " " + std::to_string(other.matrix[6]) + " " + std::to_string(other.matrix[7]) + " " + " |" + "\n" +
"| " + std::to_string(other.matrix[8]) + " " + std::to_string(other.matrix[9]) + " " + std::to_string(other.matrix[10]) + " " + std::to_string(other.matrix[11]) + " " + " |" + "\n" +
"| " + std::to_string(other.matrix[12]) + " " + std::to_string(other.matrix[13]) + " " + std::to_string(other.matrix[14]) + " " + std::to_string(other.matrix[15]) + " " + " |";
os.write(final.c_str(), final.size());
return os;
}
Matrix4& operator+=(const Matrix4& other)
{
this->matrix[0] += other.matrix[0]; this->matrix[1] += other.matrix[1]; this->matrix[2] += other.matrix[2]; this->matrix[3] += other.matrix[3];
this->matrix[4] += other.matrix[4]; this->matrix[5] += other.matrix[5]; this->matrix[6] += other.matrix[6]; this->matrix[7] += other.matrix[7];
this->matrix[8] += other.matrix[8]; this->matrix[9] += other.matrix[9]; this->matrix[10] += other.matrix[10]; this->matrix[11] += other.matrix[11];
this->matrix[12] += other.matrix[12]; this->matrix[13] += other.matrix[13]; this->matrix[14] += other.matrix[14]; this->matrix[15] += other.matrix[15];
}
Matrix4& operator-=(const Matrix4& other)
{
this->matrix[0] -= other.matrix[0]; this->matrix[1] -= other.matrix[1]; this->matrix[2] -= other.matrix[2]; this->matrix[3] -= other.matrix[3];
this->matrix[4] -= other.matrix[4]; this->matrix[5] -= other.matrix[5]; this->matrix[6] -= other.matrix[6]; this->matrix[7] -= other.matrix[7];
this->matrix[8] -= other.matrix[8]; this->matrix[9] -= other.matrix[9]; this->matrix[10] -= other.matrix[10]; this->matrix[11] -= other.matrix[11];
this->matrix[12] -= other.matrix[12]; this->matrix[13] -= other.matrix[13]; this->matrix[14] -= other.matrix[14]; this->matrix[15] -= other.matrix[15];
}
Matrix4& operator*=(float scale)
{
this->matrix[0] *= scale; this->matrix[1] *= scale; this->matrix[2] *= scale; this->matrix[3] *= scale;
this->matrix[4] *= scale; this->matrix[5] *= scale; this->matrix[6] *= scale; this->matrix[7] *= scale;
this->matrix[8] *= scale; this->matrix[9] *= scale; this->matrix[10] *= scale; this->matrix[11] *= scale;
this->matrix[12] *= scale; this->matrix[13] *= scale; this->matrix[14] *= scale; this->matrix[15] *= scale;
}
Matrix4& operator*=(Vector3& other)
{
this->matrix[0] *= other.GetX(); this->matrix[1] *= other.GetX(); this->matrix[2] *= other.GetX(); this->matrix[3] *= 1;
this->matrix[4] *= other.GetY(); this->matrix[5] *= other.GetY(); this->matrix[6] *= other.GetY(); this->matrix[7] *= 1;
this->matrix[8] *= other.GetZ(); this->matrix[9] *= other.GetZ(); this->matrix[10] *= other.GetZ(); this->matrix[11] *= 1;
return *this;
}
Matrix4& operator*= (Vector4& other)
{
this->matrix[0] *= other.GetX(); this->matrix[1] *= other.GetX(); this->matrix[2] *= other.GetX(); this->matrix[3] *= other.GetX();
this->matrix[4] *= other.GetY(); this->matrix[5] *= other.GetY(); this->matrix[6] *= other.GetY(); this->matrix[7] *= other.GetY();
this->matrix[8] *= other.GetZ(); this->matrix[9] *= other.GetZ(); this->matrix[10] *= other.GetZ(); this->matrix[11] *= other.GetZ();
this->matrix[12] *= other.GetW(); this->matrix[13] *= other.GetW(); this->matrix[14] *= other.GetW(); this->matrix[15] *= other.GetW();
return *this;
}
Matrix4& operator= (Matrix4& other)
{
this->matrix[0] = other.matrix[0]; this->matrix[1] = other.matrix[1]; this->matrix[2] = other.matrix[2]; this->matrix[3] = other.matrix[3];
this->matrix[4] = other.matrix[4]; this->matrix[5] = other.matrix[5]; this->matrix[6] = other.matrix[6]; this->matrix[7] = other.matrix[7];
this->matrix[8] = other.matrix[8]; this->matrix[9] = other.matrix[9]; this->matrix[10] = other.matrix[10]; this->matrix[11] = other.matrix[11];
this->matrix[12] = other.matrix[12]; this->matrix[13] = other.matrix[13]; this->matrix[14] = other.matrix[14]; this->matrix[15] = other.matrix[15];
return *this;
}
//BUG: You need to put the matrix in a variable, otherwise you wil gett strange values
Matrix4& operator+(const Matrix4& other)
{
Matrix4 tmp = *this;
for (int i = 0; i < 16; i++)
{
tmp.matrix[i] += other.matrix[i];
}
return tmp;
}
Matrix4& operator-(const Matrix4& other)
{
Matrix4 tmp = *this;
for (int i = 0; i < 16; i++)
{
tmp.matrix[i] -= other.matrix[i];
}
return tmp;
}
Matrix4& operator*(Vector3& other)
{
Matrix4 tmp = *this;
tmp.matrix[0] *= other.GetX(); tmp.matrix[1] *= other.GetX(); tmp.matrix[2] *= other.GetX(); tmp.matrix[3] *= 1;
tmp.matrix[4] *= other.GetY(); tmp.matrix[5] *= other.GetY(); tmp.matrix[6] *= other.GetY(); tmp.matrix[7] *= 1;
tmp.matrix[8] *= other.GetZ(); tmp.matrix[9] *= other.GetZ(); tmp.matrix[10] *= other.GetZ(); tmp.matrix[11] *= 1;
return tmp;
}
Matrix4& operator*(Vector4& other)
{
Matrix4 tmp = *this;
tmp.matrix[0] *= other.GetX(); tmp.matrix[1] *= other.GetX(); tmp.matrix[2] *= other.GetX(); tmp.matrix[3] *= other.GetX();
tmp.matrix[4] *= other.GetY(); tmp.matrix[5] *= other.GetY(); tmp.matrix[6] *= other.GetY(); tmp.matrix[7] *= other.GetY();
tmp.matrix[8] *= other.GetZ(); tmp.matrix[9] *= other.GetZ(); tmp.matrix[10] *= other.GetZ(); tmp.matrix[11] *= other.GetZ();
tmp.matrix[12] *= other.GetW(); tmp.matrix[13] *= other.GetW(); tmp.matrix[14] *= other.GetW(); tmp.matrix[15] *= other.GetW();
return tmp;
}
//WIP: CREATE BINARY OPERATORS
//Index goes from 0 to 3
void SetCol(unsigned int index, float f1, float f2, float f3, float f4)
{
matrix[index * 4] = f1;
matrix[index * 4 + 1] = f2;
matrix[index * 4 + 2] = f3;
matrix[index * 4 + 3] = f4;
}
//Index goes from 0 to 3
void SetCol(unsigned int index, const float vals[])
{
matrix[index * 4] = vals[0];
matrix[index * 4 + 1] = vals[1];
matrix[index * 4 + 2] = vals[2];
matrix[index * 4 + 3] = vals[3];
}
//Index goes from 0 to 3
void SetCol(unsigned int index, Vector4 val)
{
matrix[index * 4] = val.GetX();
matrix[index * 4 + 1] = val.GetY();
matrix[index * 4 + 2] = val.GetZ();
matrix[index * 4 + 3] = val.GetW();
}
Matrix4 MultiplyByVec3Floats (float x, float y, float z)
{
this->matrix[0] *= x; this->matrix[1] *= x; this->matrix[2] *= x; this->matrix[3] *= 1;
this->matrix[4] *= y; this->matrix[5] *= y; this->matrix[6] *= y; this->matrix[7] *= 1;
this->matrix[8] *= z; this->matrix[9] *= z; this->matrix[10] *= z; this->matrix[11] *= 1;
}
Matrix4 MultiplyByVec4Floats(float x, float y, float z, float w)
{
this->matrix[0] *= x; this->matrix[1] *= x; this->matrix[2] *= x; this->matrix[3] *= w;
this->matrix[4] *= y; this->matrix[5] *= y; this->matrix[6] *= y; this->matrix[7] *= w;
this->matrix[8] *= z; this->matrix[9] *= z; this->matrix[10] *= z; this->matrix[11] *= w;
this->matrix[12] *= x; this->matrix[13] *= y; this->matrix[14] *= z; this->matrix[15] *= w;
}
};`
With the following class, i then create some variables and thest them in my main file:
使用下面的类,我然后在我的主文件中创建一些变量和它们:
//#define TEST_VECTORS
#define TEST_MATRIX
#include <iostream>
#include <sdl/SDL.h>
#include<gl\glew.h>
#include <ostream>
#include <string>
#include "Game.h"
#include "gmath.h"
using namespace std;
int main(int argc, char* argv[])
{
#ifdef TEST_VECTORS
gmath::Vector3 vTestVector(5, 5, 5);
gmath::Vector3 vAnotherVector(1, 1, 1);
gmath::Vector3 vZeroVector = gmath::Vector3::Zero();
cout << vTestVector.Length() << endl;
cout << vTestVector + vAnotherVector << endl;
cout << vTestVector - vAnotherVector << endl;
cout << gmath::Vector3::Distance(vTestVector, vAnotherVector) << endl;
cout << vTestVector.Normalized() << endl;
cout << (vTestVector == vTestVector) << endl;
cout << gmath::Vector3::Dot(vTestVector, vAnotherVector) << endl;
cout << gmath::Vector3::Cross(vTestVector, vAnotherVector) << endl;
#endif
#ifdef TEST_MATRIX
gmath::Matrix4 mat;
float vals[] = { 1.f, 2.f, 3.f, 4.f };
mat.SetCol(1, vals);
gmath::Vector4 testVec(1.f, 4.f, 2.f, 1.f);
mat.SetCol(3, testVec);
mat.SetCol(0, 1.f, 5.f, 35.f, 6.f);
gmath::Matrix4 another;
another = mat;
std::cout << mat << std::endl;
std::cout << another << std::endl;
gmath::Matrix4 sum = another + mat;
cout << sum << std::endl;
gmath::Matrix4 prod = sum*testVec;
cout << prod << endl;
mat = gmath::Matrix4();
cout << mat << endl;
#endif
Game* g = new Game("MyGLTest", 800, 600, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
while (g->isGameRunning())
{
g->Update();
g->HandleInput();
}
return 0;
}
The problem is that, if i try the following operation:
问题是,如果我尝试以下操作:
cout << another + mat << std::endl;
i get the -107374176.000000 number as output, repeated 16 times, while storing the value in a variable:
我将-107374176.000000数作为输出,重复16次,同时将值存储在变量中:
sum = another + mat;
works fine. What could be the problem?
工作良好。可能是什么问题呢?
1 个解决方案
#1
Your overloaded operators are declared as returning references, however some of them are missing the return *this;
statement (operator+=
, operator-=
, operator*=
). Also, in the operators that return *this
, you are doing it wrong. You make a copy to *this
then return the copy. Bam, dangling reference. Example from your code:
您的重载运算符被声明为返回引用,但是其中一些缺少return * this;语句(operator + =,operator- =,operator * =)。另外,在返回* this的运算符中,你做错了。您复制到* this然后返回副本。 Bam,晃来晃去的参考。代码中的示例:
Matrix4& operator-(const Matrix4& other)
{
Matrix4 tmp = *this; // this is a local object, cease to exist at function exit
for (int i = 0; i < 16; i++)
{
tmp.matrix[i] -= other.matrix[i];
}
return tmp; // here you're done, return a reference to a local object
}
So you should really return by value here. Moreover, binary operators are best implemented as friends. See Operator overloading for an excellent guide.
所以你应该在这里真正回报价值。此外,二元运算符最好实现为朋友。有关优秀指南,请参阅操作员重载。
#1
Your overloaded operators are declared as returning references, however some of them are missing the return *this;
statement (operator+=
, operator-=
, operator*=
). Also, in the operators that return *this
, you are doing it wrong. You make a copy to *this
then return the copy. Bam, dangling reference. Example from your code:
您的重载运算符被声明为返回引用,但是其中一些缺少return * this;语句(operator + =,operator- =,operator * =)。另外,在返回* this的运算符中,你做错了。您复制到* this然后返回副本。 Bam,晃来晃去的参考。代码中的示例:
Matrix4& operator-(const Matrix4& other)
{
Matrix4 tmp = *this; // this is a local object, cease to exist at function exit
for (int i = 0; i < 16; i++)
{
tmp.matrix[i] -= other.matrix[i];
}
return tmp; // here you're done, return a reference to a local object
}
So you should really return by value here. Moreover, binary operators are best implemented as friends. See Operator overloading for an excellent guide.
所以你应该在这里真正回报价值。此外,二元运算符最好实现为朋友。有关优秀指南,请参阅操作员重载。