3 #include <msp/geometry/affinetransformation.h>
4 #include <msp/gl/extensions/msp_legacy_features.h>
14 Base(Base::identity())
17 Matrix::Matrix(const float *m):
21 Matrix::Matrix(const LinAl::Matrix<float, 4, 4> &other):
25 Matrix &Matrix::translate(const Vector3 &t)
27 return multiply(translation(t));
30 Matrix &Matrix::rotate(const Angle &a, const Vector3 &x)
32 return multiply(rotation(a, x));
35 Matrix &Matrix::scale(const Vector3 &s)
37 return multiply(scaling(s));
40 float Matrix::operator[](unsigned i) const
43 throw out_of_range("Matrix::operator[]");
44 return operator()(i%4, i/4);
47 Matrix Matrix::translation(const Vector3 &t)
49 return Geometry::AffineTransformation<float, 3>::translation(t).get_matrix();
52 Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
54 return Geometry::AffineTransformation<float, 3>::rotation(a, x).get_matrix();
57 Matrix Matrix::scaling(const Vector3 &s)
59 return Geometry::AffineTransformation<float, 3>::scaling(s).get_matrix();
62 Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
64 if(l==r || b==t || n==f)
65 throw invalid_argument("Matrix::ortho");
68 result(0, 0) = 2/(r-l);
69 result(1, 1) = 2/(t-b);
70 result(2, 2) = -2/(f-n);
71 result(0, 3) = -(r+l)/(r-l);
72 result(1, 3) = -(t+b)/(t-b);
73 result(2, 3) = -(f+n)/(f-n);
77 Matrix Matrix::ortho_centered(float w, float h)
79 return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
82 Matrix Matrix::ortho_bottomleft(float w, float h)
84 return ortho(0, w, 0, h, -1, 1);
87 Matrix Matrix::ortho_topleft(float w, float h)
89 return ortho(0, w, h, 0, -1, 1);
92 Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f)
94 if(l==r || b==t || n<=0 || f<=n)
95 throw invalid_argument("Matrix::frustum");
98 result(0, 0) = 2*n/(r-l);
99 result(1, 1) = 2*n/(t-b);
100 result(0, 2) = (r+l)/(r-l);
101 result(1, 2) = (t+b)/(t-b);
102 result(2, 2) = -(f+n)/(f-n);
104 result(2, 3) = -2*f*n/(f-n);
109 Matrix Matrix::frustum_centered(float w, float h, float n, float f)
111 return frustum(-w/2, w/2, -h/2, h/2, n, f);
114 Matrix Matrix::perspective(const Angle &h, float a, float n, float f)
116 float hh = tan(h/2.0f)*n;
117 return frustum(-hh*a, hh*a, -hh, hh, n, f);
121 GLenum MatrixStack::current_mode = GL_MODELVIEW;
123 MatrixStack::MatrixStack(GLenum m):
126 matrices.reserve(mode==GL_MODELVIEW ? 32 : 4);
127 matrices.push_back(Matrix());
130 MatrixStack::MatrixStack():
133 matrices.reserve(32);
134 matrices.push_back(Matrix());
137 const Matrix &MatrixStack::top() const
139 return matrices.back();
142 void MatrixStack::load(const Matrix &m)
148 void MatrixStack::multiply(const Matrix &m)
150 matrices.back() *= m;
154 void MatrixStack::push()
156 matrices.push_back(top());
159 void MatrixStack::pop()
161 if(matrices.size()==1)
162 throw stack_underflow("MatrixStack::pop()");
168 void MatrixStack::update()
173 static Require _req(MSP_legacy_features);
175 if(mode!=current_mode)
181 glLoadMatrixf(matrices.back().data());
184 MatrixStack &MatrixStack::operator=(const Matrix &m)
190 MatrixStack &MatrixStack::operator*=(const Matrix &m)
196 MatrixStack &MatrixStack::modelview()
198 static MatrixStack ms(GL_MODELVIEW);
202 MatrixStack &MatrixStack::projection()
204 static MatrixStack ms(GL_PROJECTION);