From fa5b232a16e11d7950e80764497f0167ec9e3b41 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 27 Nov 2013 11:06:38 +0200 Subject: [PATCH] Convert Matrix to use floats This halves matrix storage size to 64 bytes and reduces overhead from conversions at certain places. If an application desires greater precision, it can use the LinAl::Matrix and Geometry::AffineTransformation classes internally. --- source/animation.cpp | 24 ++++++++--------- source/animation.h | 2 +- source/camera.cpp | 12 ++++----- source/matrix.cpp | 36 ++++++++++++-------------- source/matrix.h | 59 +++++++++++++++++++++--------------------- source/programdata.cpp | 4 +-- source/shadowmap.cpp | 2 +- 7 files changed, 66 insertions(+), 73 deletions(-) diff --git a/source/animation.cpp b/source/animation.cpp index c0b50818..b1d639e7 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -59,12 +59,12 @@ Animation::AxisInterpolation::AxisInterpolation(): scale(0) { } -Animation::AxisInterpolation::AxisInterpolation(const double *axis1, const double *axis2) +Animation::AxisInterpolation::AxisInterpolation(const float *axis1, const float *axis2) { // Compute a normalized vector halfway between the two endpoints - double half[3]; - double a1_len = 0; - double h_len = 0; + float half[3]; + float a1_len = 0; + float h_len = 0; for(unsigned i=0; i<3; ++i) { half[i] = (axis1[i]+axis2[i])/2; @@ -73,8 +73,8 @@ Animation::AxisInterpolation::AxisInterpolation(const double *axis1, const doubl } // Compute correction factors for smooth interpolation - double cos_half = (axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2])/sqrt(a1_len*h_len); - double angle = acos(cos_half); + float cos_half = (axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2])/sqrt(a1_len*h_len); + float angle = acos(cos_half); slope = (angle ? angle/tan(angle) : 1); scale = cos_half; } @@ -89,8 +89,8 @@ Animation::MatrixInterpolation::MatrixInterpolation(const Matrix &m1, const Matr matrix1(&m1), matrix2(&m2) { - const double *m1_data = matrix1->data(); - const double *m2_data = matrix2->data(); + const float *m1_data = matrix1->data(); + const float *m2_data = matrix2->data(); for(unsigned i=0; i<3; ++i) axes[i] = AxisInterpolation(m1_data+i*4, m2_data+i*4); } @@ -99,12 +99,12 @@ Matrix Animation::MatrixInterpolation::get(float t) const { float u = t*2.0f-1.0f; - double matrix[16]; + float matrix[16]; for(unsigned i=0; i<4; ++i) { - const double *m1_col = matrix1->data()+i*4; - const double *m2_col = matrix2->data()+i*4; - double *out_col = matrix+i*4; + const float *m1_col = matrix1->data()+i*4; + const float *m2_col = matrix2->data()+i*4; + float *out_col = matrix+i*4; if(i<3) { diff --git a/source/animation.h b/source/animation.h index 58a76583..63b13f72 100644 --- a/source/animation.h +++ b/source/animation.h @@ -43,7 +43,7 @@ private: float scale; AxisInterpolation(); - AxisInterpolation(const double *, const double *); + AxisInterpolation(const float *, const float *); }; struct MatrixInterpolation diff --git a/source/camera.cpp b/source/camera.cpp index df4119a9..0202bedf 100644 --- a/source/camera.cpp +++ b/source/camera.cpp @@ -79,7 +79,7 @@ Vector3 Camera::project(const Vector3 &p) const Vector4 Camera::unproject(const Vector4 &p) const { - Vector4 r = invert(proj_matrix)*LinAl::Vector(p.x, p.y, p.z, 1.0f); + Vector4 r = invert(proj_matrix)*Vector4(p.x, p.y, p.z, 1.0f); r = object_matrix*Vector4(r.x, r.y, r.z, p.w); return r; } @@ -104,11 +104,11 @@ void Camera::update_projection_matrix() void Camera::update_object_matrix() { Vector3 right_dir = normalize(cross(look_dir, up_dir)); - LinAl::Vector columns[4]; - columns[0] = LinAl::Vector(right_dir, 0.0f); - columns[1] = LinAl::Vector(cross(right_dir, look_dir), 0.0f); - columns[2] = LinAl::Vector(-look_dir, 0.0f); - columns[3] = LinAl::Vector(position, 1.0f); + Vector4 columns[4]; + columns[0] = Vector4(right_dir, 0.0f); + columns[1] = Vector4(cross(right_dir, look_dir), 0.0f); + columns[2] = Vector4(-look_dir, 0.0f); + columns[3] = Vector4(position, 1.0f); object_matrix = Matrix::from_columns(columns); view_matrix = invert(object_matrix); } diff --git a/source/matrix.cpp b/source/matrix.cpp index cac4a4fc..4bf550aa 100644 --- a/source/matrix.cpp +++ b/source/matrix.cpp @@ -14,14 +14,10 @@ Matrix::Matrix(): { } Matrix::Matrix(const float *m): - Base(LinAl::SquareMatrix(m)) -{ } - -Matrix::Matrix(const double *m): Base(m) { } -Matrix::Matrix(const LinAl::Matrix &other): +Matrix::Matrix(const LinAl::Matrix &other): Base(other) { } @@ -58,7 +54,7 @@ Matrix &Matrix::operator*=(const Matrix &other) Vector4 Matrix::operator*(const Vector4 &vec) const { - return static_cast(*this)*LinAl::Vector(vec); + return static_cast(*this)*LinAl::Vector(vec); } Vector3 Matrix::operator*(const Vector3 &vec) const @@ -66,7 +62,7 @@ Vector3 Matrix::operator*(const Vector3 &vec) const return Vector3((*this)*Vector4(vec, 1.0f)); } -double Matrix::operator[](unsigned i) const +float Matrix::operator[](unsigned i) const { if(i>=16) throw out_of_range("Matrix::operator[]"); @@ -75,20 +71,20 @@ double Matrix::operator[](unsigned i) const Matrix Matrix::translation(const Vector3 &t) { - return Geometry::AffineTransformation::translation(t).get_matrix(); + return Geometry::AffineTransformation::translation(t).get_matrix(); } Matrix Matrix::rotation(const Angle &a, const Vector3 &x) { - return Geometry::AffineTransformation::rotation(a, x).get_matrix(); + return Geometry::AffineTransformation::rotation(a, x).get_matrix(); } Matrix Matrix::scaling(const Vector3 &s) { - return Geometry::AffineTransformation::scaling(s).get_matrix(); + return Geometry::AffineTransformation::scaling(s).get_matrix(); } -Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f) +Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f) { if(l==r || b==t || n==f) throw invalid_argument("Matrix::ortho"); @@ -103,22 +99,22 @@ Matrix Matrix::ortho(double l, double r, double b, double t, double n, double f) return result; } -Matrix Matrix::ortho_centered(double w, double h) +Matrix Matrix::ortho_centered(float w, float h) { return ortho(-w/2, w/2, -h/2, h/2, -1, 1); } -Matrix Matrix::ortho_bottomleft(double w, double h) +Matrix Matrix::ortho_bottomleft(float w, float h) { return ortho(0, w, 0, h, -1, 1); } -Matrix Matrix::ortho_topleft(double w, double h) +Matrix Matrix::ortho_topleft(float w, float h) { return ortho(0, w, h, 0, -1, 1); } -Matrix Matrix::frustum(double l, double r, double b, double t, double n, double f) +Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f) { if(l==r || b==t || n<=0 || f<=n) throw invalid_argument("Matrix::frustum"); @@ -131,18 +127,18 @@ Matrix Matrix::frustum(double l, double r, double b, double t, double n, double result(2, 2) = -(f+n)/(f-n); result(3, 2) = -1; result(2, 3) = -2*f*n/(f-n); - result(3 ,3) = 0; + result(3, 3) = 0; return result; } -Matrix Matrix::frustum_centered(double w, double h, double n, double f) +Matrix Matrix::frustum_centered(float w, float h, float n, float f) { return frustum(-w/2, w/2, -h/2, h/2, n, f); } -Matrix Matrix::perspective(const Angle &h, double a, double n, double f) +Matrix Matrix::perspective(const Angle &h, float a, float n, float f) { - double hh = tan(h/2.0)*n; + float hh = tan(h/2.0f)*n; return frustum(-hh*a, hh*a, -hh, hh, n, f); } @@ -205,7 +201,7 @@ void MatrixStack::update() current_mode = mode; } - glLoadMatrixd(matrices.back().data()); + glLoadMatrixf(matrices.back().data()); } MatrixStack &MatrixStack::operator=(const Matrix &m) diff --git a/source/matrix.h b/source/matrix.h index ce21b46f..2dc3b972 100644 --- a/source/matrix.h +++ b/source/matrix.h @@ -10,58 +10,57 @@ namespace Msp { namespace GL { -class Matrix: public LinAl::SquareMatrix +class Matrix: public LinAl::SquareMatrix { private: - typedef LinAl::SquareMatrix Base; - typedef Geometry::Angle Angle; + typedef LinAl::SquareMatrix Base; + typedef Geometry::Angle Angle; public: Matrix(); Matrix(const float *); - Matrix(const double *); - Matrix(const LinAl::Matrix &); + Matrix(const LinAl::Matrix &); - const double *data() const { return &Base::operator()(0, 0); } + const float *data() const { return &Base::operator()(0, 0); } void multiply(const Matrix &); - void translate(double x, double y, double z) { translate(Vector3(x, y, z)); } + void translate(float x, float y, float z) { translate(Vector3(x, y, z)); } void translate(const Vector3 &); - void rotate(const Angle &a, double x, double y, double z) { rotate(a, Vector3(x, y, z)); } + void rotate(const Angle &a, float x, float y, float z) { rotate(a, Vector3(x, y, z)); } void rotate(const Angle &, const Vector3 &); - void rotate(double a, double x, double y, double z) { rotate(Angle::from_radians(a), Vector3(x, y, z)); } - void rotate(double a, const Vector3 &x) { rotate(Angle::from_radians(a), x); } - void rotate_deg(double a, double x, double y, double z) { rotate(Angle::from_degrees(a), Vector3(x, y, z)); } - void rotate_deg(double a, const Vector3 & x) { rotate(Angle::from_degrees(a), x); } - void scale(double s) { scale(Vector3(s, s, s)); } - void scale(double x, double y, double z) { scale(Vector3(x, y, z)); } + void rotate(float a, float x, float y, float z) { rotate(Angle::from_radians(a), Vector3(x, y, z)); } + void rotate(float a, const Vector3 &x) { rotate(Angle::from_radians(a), x); } + void rotate_deg(float a, float x, float y, float z) { rotate(Angle::from_degrees(a), Vector3(x, y, z)); } + void rotate_deg(float a, const Vector3 & x) { rotate(Angle::from_degrees(a), x); } + void scale(float s) { scale(Vector3(s, s, s)); } + void scale(float x, float y, float z) { scale(Vector3(x, y, z)); } void scale(const Vector3 &); Matrix operator*(const Matrix &) const; Matrix &operator*=(const Matrix &); Vector4 operator*(const Vector4 &) const; Vector3 operator*(const Vector3 &) const; - double operator[](unsigned) const; + float operator[](unsigned) const; - static Matrix translation(double x, double y, double z) { return translation(Vector3(x, y, z)); } + static Matrix translation(float x, float y, float z) { return translation(Vector3(x, y, z)); } static Matrix translation(const Vector3 &); - static Matrix rotation(const Angle &a, double x, double y, double z) { return rotation(a, Vector3(x, y, z)); } + static Matrix rotation(const Angle &a, float x, float y, float z) { return rotation(a, Vector3(x, y, z)); } static Matrix rotation(const Angle &, const Vector3 &); - static Matrix rotation(double a, double x, double y, double z) { return rotation(Angle::from_radians(a), Vector3(x, y, z)); } - static Matrix rotation(double a, const Vector3 &x) { return rotation(Angle::from_radians(a), x); } - static Matrix rotation_deg(double a, double x, double y, double z) { return rotation(Angle::from_degrees(a), Vector3(x, y, z)); } - static Matrix rotation_deg(double a, const Vector3 &x) { return rotation(Angle::from_degrees(a), x); } - static Matrix scaling(double s) { return scaling(Vector3(s, s, s)); } - static Matrix scaling(double x, double y, double z) { return scaling(Vector3(x, y, z)); } + static Matrix rotation(float a, float x, float y, float z) { return rotation(Angle::from_radians(a), Vector3(x, y, z)); } + static Matrix rotation(float a, const Vector3 &x) { return rotation(Angle::from_radians(a), x); } + static Matrix rotation_deg(float a, float x, float y, float z) { return rotation(Angle::from_degrees(a), Vector3(x, y, z)); } + static Matrix rotation_deg(float a, const Vector3 &x) { return rotation(Angle::from_degrees(a), x); } + static Matrix scaling(float s) { return scaling(Vector3(s, s, s)); } + static Matrix scaling(float x, float y, float z) { return scaling(Vector3(x, y, z)); } static Matrix scaling(const Vector3 &); - static Matrix ortho(double, double, double, double, double, double); - static Matrix ortho_centered(double, double); - static Matrix ortho_bottomleft(double, double); - static Matrix ortho_topleft(double, double); - static Matrix frustum(double, double, double, double, double, double); - static Matrix frustum_centered(double, double, double, double); - static Matrix perspective(const Angle &, double, double, double); + static Matrix ortho(float, float, float, float, float, float); + static Matrix ortho_centered(float, float); + static Matrix ortho_bottomleft(float, float); + static Matrix ortho_topleft(float, float); + static Matrix frustum(float, float, float, float, float, float); + static Matrix frustum_centered(float, float, float, float); + static Matrix perspective(const Angle &, float, float, float); }; class MatrixStack diff --git a/source/programdata.cpp b/source/programdata.cpp index 943dcfaf..12879140 100644 --- a/source/programdata.cpp +++ b/source/programdata.cpp @@ -149,9 +149,7 @@ void ProgramData::uniform_matrix3(const string &name, const float *v) void ProgramData::uniform(const string &name, const Matrix &m) { - float v[16]; - copy(m.data(), m.data()+16, v); - uniform_matrix4(name, v); + uniform_matrix4(name, m.data()); } void ProgramData::uniform_matrix4(const string &name, const float *v) diff --git a/source/shadowmap.cpp b/source/shadowmap.cpp index d380257d..91c056fe 100644 --- a/source/shadowmap.cpp +++ b/source/shadowmap.cpp @@ -144,7 +144,7 @@ void ShadowMap::render(Renderer &renderer, const Tag &tag) const if(!enabled_passes.count(tag)) return renderer.render(renderable, tag); - const double *matrix = light_matrix.data(); + const float *matrix = light_matrix.data(); // Has side effect of changing the current unit depth_buf.bind_to(unit); -- 2.43.0