0

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?

shoham
  • 792
  • 2
  • 12
  • 30

1 Answers1

10

mat4 result(); declares a function. Change it to mat4 result; to declare (and default-initialise) a variable.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644