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 void Matrix::multiply(const Matrix &other)
30 void Matrix::translate(const Vector3 &t)
32 multiply(translation(t));
35 void Matrix::rotate(const Angle &a, const Vector3 &x)
37 multiply(rotation(a, x));
40 void Matrix::scale(const Vector3 &s)
45 Matrix Matrix::operator*(const Matrix &other) const
47 return static_cast<const Base &>(*this)*static_cast<const Base &>(other);
50 Matrix &Matrix::operator*=(const Matrix &other)
56 Vector4 Matrix::operator*(const Vector4 &vec) const
58 return static_cast<const Base &>(*this)*LinAl::Vector<float, 4>(vec);
61 Vector3 Matrix::operator*(const Vector3 &vec) const
63 return Vector3((*this)*Vector4(vec, 1.0f));
66 float Matrix::operator[](unsigned i) const
69 throw out_of_range("Matrix::operator[]");
70 return operator()(i%4, i/4);
73 Matrix Matrix::translation(const Vector3 &t)
75 return Geometry::AffineTransformation<float, 3>::translation(t).get_matrix();
78 Matrix Matrix::rotation(const Angle &a, const Vector3 &x)
80 return Geometry::AffineTransformation<float, 3>::rotation(a, x).get_matrix();
83 Matrix Matrix::scaling(const Vector3 &s)
85 return Geometry::AffineTransformation<float, 3>::scaling(s).get_matrix();
88 Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
90 if(l==r || b==t || n==f)
91 throw invalid_argument("Matrix::ortho");
94 result(0, 0) = 2/(r-l);
95 result(1, 1) = 2/(t-b);
96 result(2, 2) = -2/(f-n);
97 result(0, 3) = -(r+l)/(r-l);
98 result(1, 3) = -(t+b)/(t-b);
99 result(2, 3) = -(f+n)/(f-n);
103 Matrix Matrix::ortho_centered(float w, float h)
105 return ortho(-w/2, w/2, -h/2, h/2, -1, 1);
108 Matrix Matrix::ortho_bottomleft(float w, float h)
110 return ortho(0, w, 0, h, -1, 1);
113 Matrix Matrix::ortho_topleft(float w, float h)
115 return ortho(0, w, h, 0, -1, 1);
118 Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f)
120 if(l==r || b==t || n<=0 || f<=n)
121 throw invalid_argument("Matrix::frustum");
124 result(0, 0) = 2*n/(r-l);
125 result(1, 1) = 2*n/(t-b);
126 result(0, 2) = (r+l)/(r-l);
127 result(1, 2) = (t+b)/(t-b);
128 result(2, 2) = -(f+n)/(f-n);
130 result(2, 3) = -2*f*n/(f-n);
135 Matrix Matrix::frustum_centered(float w, float h, float n, float f)
137 return frustum(-w/2, w/2, -h/2, h/2, n, f);
140 Matrix Matrix::perspective(const Angle &h, float a, float n, float f)
142 float hh = tan(h/2.0f)*n;
143 return frustum(-hh*a, hh*a, -hh, hh, n, f);
147 GLenum MatrixStack::current_mode = GL_MODELVIEW;
149 MatrixStack::MatrixStack(GLenum m):
152 matrices.reserve(mode==GL_MODELVIEW ? 32 : 4);
153 matrices.push_back(Matrix());
156 MatrixStack::MatrixStack():
159 matrices.reserve(32);
160 matrices.push_back(Matrix());
163 const Matrix &MatrixStack::top() const
165 return matrices.back();
168 void MatrixStack::load(const Matrix &m)
174 void MatrixStack::multiply(const Matrix &m)
176 matrices.back() *= m;
180 void MatrixStack::push()
182 matrices.push_back(top());
185 void MatrixStack::pop()
187 if(matrices.size()==1)
188 throw stack_underflow("MatrixStack::pop()");
194 void MatrixStack::update()
199 static Require _req(MSP_legacy_features);
201 if(mode!=current_mode)
207 glLoadMatrixf(matrices.back().data());
210 MatrixStack &MatrixStack::operator=(const Matrix &m)
216 MatrixStack &MatrixStack::operator*=(const Matrix &m)
222 MatrixStack &MatrixStack::modelview()
224 static MatrixStack ms(GL_MODELVIEW);
228 MatrixStack &MatrixStack::projection()
230 static MatrixStack ms(GL_PROJECTION);