I'm trying to code a matrix struct in C++ and I'm a newbie. The mat4.h file:
#include "math.h"
namespace engine {
namespace math {
struct mat4 {
float elements[4 * 4]; // column major ordering, index = row + col * 4
mat4();
mat4(float diagonal);
mat4& mul(const mat4& other);
static mat4 identity(); // construct and return an identity matrix
static mat4 orthographic(float left, float right, float bottom, float top, float near, float far); // boundaries (clipping planes)
static mat4 perspective(float fov, float aspectRatio, float near, float far);
static mat4 translation(const vec3& translation);
static mat4 rotation(float angle, const vec3 & axis);
static mat4 scale(const vec3 & scale);
friend mat4 operator*(mat4 left, const mat4 & right);
mat4& operator*=(const mat4 &other);
};
}
}
And here is mat4.cpp:
#include "mat4.h"
namespace engine {
namespace math {
mat4::mat4() {
for (int i = 0; i < 4 * 4; i++)
elements[i] = 0;
}
mat4::mat4(float diagonal) {
for (int i = 0; i < 4 * 4; ++i) {
elements[i] = 0;
}
for(int i = 0; i < 4; i += 1)
elements[i + i * 4] = diagonal;
}
mat4& mat4::mul(const mat4 &other) {
for (int i = 0; i < 4; ++i) // col
for (int j = 0; j < 4; ++j) { // row
float sum = 0;
for (int k = 0; k < 4; ++k)
sum += elements[j + k * 4] * other.elements[k + i * 4];
elements[j + i * 4] = sum;
}
}
mat4 mat4::identity() {
return mat4(1);
}
mat4 operator*(mat4 left, const mat4 &right) {
return left.mul(right);
}
mat4 &mat4::operator*=(const mat4 &other) {
return mul(other);
}
mat4 mat4::orthographic(float left, float right, float bottom, float top, float near, float far) {
mat4 result(1);
result.elements[0 + 0 * 4] = 2.0f / (right - left);
result.elements[1 + 1 * 4] = 2.0f / (top - bottom);
result.elements[2 + 2 * 4] = -2.0f / (far - near);
result.elements[0 + 3 * 4] = (left + right) / (left - right);
result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
result.elements[2 + 3 * 4] = (far + near) / (far - near);
//result.elements[3 + 3 * 4] = 1; this is achieved by mat result(1);
return result;
}
mat4 mat4::perspective(float fov, float aspectRatio, float near, float far) {
mat4 result();
float q = 1.0f / (float) tan(toRadians(fov) / 2.0f);
result.elements[0 + 0 * 4] = q / aspectRatio;
result.elements[1 + 1 * 4] = q;
result.elements[2 + 2 * 4] = (-near - far) / (near - far);
result.elements[3 + 2 * 4] = 1;
result.elements[2 + 3 * 4] = 2 * far * near / (near - far);
return result;
}
}
}
As you can see, I have 2 constructors for mat4, one that gets a float diagonal, and one without parameters.
in orthographic(...) result can access its elements correctly, but in perspective(...) it doesn't compile (when I do mat4 result();
), saying "Structure type required instead of 'mat4()'".
However, if I change the line mat4 result();
to:
mat4 result = mat4();
Then everything is fine. What's going on here?