]> git.tdb.fi Git - libs/gl.git/blob - source/core/matrix.cpp
Change default binding ranges to match lowest OpenGL standard
[libs/gl.git] / source / core / matrix.cpp
1 #include <cmath>
2 #include <stdexcept>
3 #include <msp/geometry/affinetransformation.h>
4 #include "matrix.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 Matrix::Matrix():
12         Base(Base::identity())
13 { }
14
15 Matrix::Matrix(const float *m):
16         Base(m)
17 { }
18
19 Matrix::Matrix(const LinAl::Matrix<float, 4, 4> &other):
20         Base(other)
21 { }
22
23 Matrix &Matrix::translate(const Vector3 &t)
24 {
25         return multiply(translation(t));
26 }
27
28 Matrix &Matrix::rotate(const Angle &a, const Vector3 &x)
29 {
30         return multiply(rotation(a, x));
31 }
32
33 Matrix &Matrix::scale(const Vector3 &s)
34 {
35         return multiply(scaling(s));
36 }
37
38 float Matrix::operator[](unsigned i) const
39 {
40         if(i>=16)
41                 throw out_of_range("Matrix::operator[]");
42         return operator()(i%4, i/4);
43 }
44
45 Matrix Matrix::translation(const Vector3 &t)
46 {
47         return Geometry::AffineTransformation<float, 3>::translation(t).get_matrix();
48 }
49
50 Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
51 {
52         return Geometry::AffineTransformation<float, 3>::rotation(a, x).get_matrix();
53 }
54
55 Matrix Matrix::scaling(const Vector3 &s)
56 {
57         return Geometry::AffineTransformation<float, 3>::scaling(s).get_matrix();
58 }
59
60 Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
61 {
62         if(l==r || b==t || n==f)
63                 throw invalid_argument("Matrix::ortho");
64
65         Matrix result;
66         result(0, 0) = 2/(r-l);
67         result(1, 1) = 2/(t-b);
68         result(2, 2) = -2/(f-n);
69         result(0, 3) = -(r+l)/(r-l);
70         result(1, 3) = -(t+b)/(t-b);
71         result(2, 3) = -(f+n)/(f-n);
72         return result;
73 }
74
75 Matrix Matrix::ortho_centered(float w, float h)
76 {
77         return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
78 }
79
80 Matrix Matrix::ortho_bottomleft(float w, float h)
81 {
82         return ortho(0, w, 0, h, -1, 1);
83 }
84
85 Matrix Matrix::ortho_topleft(float w, float h)
86 {
87         return ortho(0, w, h, 0, -1, 1);
88 }
89
90 Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f)
91 {
92         if(l==r || b==t || n<=0 || f<=n)
93                 throw invalid_argument("Matrix::frustum");
94
95         Matrix result;
96         result(0, 0) = 2*n/(r-l);
97         result(1, 1) = 2*n/(t-b);
98         result(0, 2) = (r+l)/(r-l);
99         result(1, 2) = (t+b)/(t-b);
100         result(2, 2) = -(f+n)/(f-n);
101         result(3, 2) = -1;
102         result(2, 3) = -2*f*n/(f-n);
103         result(3, 3) = 0;
104         return result;
105 }
106
107 Matrix Matrix::frustum_centered(float w, float h, float n, float f)
108 {
109         return frustum(-w/2, w/2, -h/2, h/2, n, f);
110 }
111
112 Matrix Matrix::perspective(const Angle &h, float a, float n, float f)
113 {
114         float hh = tan(h/2.0f)*n;
115         return frustum(-hh*a, hh*a, -hh, hh, n, f);
116 }
117
118 } // namespace GL
119 } // namespace Msp