openMSX
gl_transform.hh
Go to the documentation of this file.
1#ifndef GL_TRANSFORM_HH
2#define GL_TRANSFORM_HH
3
4// openGL ES 2.0 removed functions like
5// glRotate(), glTranslate(), glScale(), ...
6// This code can be used to replace them.
7//
8// This code was inspired by the 'glm' library (though written from scratch).
9// Compared to glm this code is much simpler but offers much less functionality.
10// http://glm.g-truc.net
11
12#include "gl_mat.hh"
13#include "gl_vec.hh"
14
15namespace gl {
16
17// Returns a 4x4 scaling matrix for the given xyz scale factors.
18// Comparable to the glScale() function.
19[[nodiscard]] constexpr mat4 scale(const vec3& xyz)
20{
21 return mat4(vec4(xyz, 1.0f));
22}
23
24// Multiplies the given matrix by a scaling matrix. Equivalent to (but more
25// efficient than) 'A * scale(xyz)'.
26[[nodiscard]] constexpr mat4 scale(const mat4& A, const vec3& xyz)
27{
28 return {A[0] * xyz[0],
29 A[1] * xyz[1],
30 A[2] * xyz[2],
31 A[3]};
32}
33
34// Returns a 4x4 translation matrix for the given xyz translation vector.
35// Comparable to the glTranslate() function.
36[[nodiscard]] constexpr mat4 translate(const vec3& xyz)
37{
38 mat4 result;
39 result[3] = vec4(xyz, 1.0f);
40 return result;
41}
42
43// Multiplies the given matrix by a translation matrix. Equivalent to (but
44// more efficient than) 'A * translate(xyz)'.
45[[nodiscard]] constexpr mat4 translate(mat4& A, const vec3& xyz)
46{
47 return {A[0],
48 A[1],
49 A[2],
50 A[0] * xyz[0] + A[1] * xyz[1] + A[2] * xyz[2] + A[3]};
51}
52
53// Returns a 4x4 rotation matrix for rotation of the given 'angle' around the
54// 'xyz' axis.
55// Comparable to the glRotate() function, but with these differences:
56// - 'angle' is in radians instead of degrees
57// - 'axis' must be a normalized vector
58[[nodiscard]] inline mat4 rotate(float angle, const vec3& axis)
59{
60 float s = sinf(angle);
61 float c = cosf(angle);
62 vec3 temp = (1.0f - c) * axis;
63
64 return {vec4(axis[0] * temp[0] + c,
65 axis[1] * temp[0] + s * axis[2],
66 axis[2] * temp[0] - s * axis[1],
67 0.0f),
68 vec4(axis[0] * temp[1] - s * axis[2],
69 axis[1] * temp[1] + c,
70 axis[2] * temp[1] + s * axis[0],
71 0.0f),
72 vec4(axis[0] * temp[2] + s * axis[1],
73 axis[1] * temp[2] - s * axis[0],
74 axis[2] * temp[2] + c,
75 0.0f),
76 vec4(0.0f,
77 0.0f,
78 0.0f,
79 1.0f)};
80}
81
82// Multiplies the given matrix by a rotation matrix. Equivalent to
83// 'A * rotate(angle, axis)'.
84[[nodiscard]] inline mat4 rotate(const mat4& A, float angle, const vec3& axis)
85{
86 // TODO this could be optimized (only a little), though it's rarely used
87 return A * rotate(angle, axis);
88}
89
90// Returns a 4x4 rotation matrix for rotation around the X-axis. Much more
91// efficient than calling the generic rotate() function with a vec3(1,0,0)
92// axis.
93[[nodiscard]] inline mat4 rotateX(float angle)
94{
95 float s = sinf(angle);
96 float c = cosf(angle);
97 return {vec4(1.0f, 0.0f, 0.0f, 0.0f),
98 vec4(0.0f, c , s , 0.0f),
99 vec4(0.0f, -s , c , 0.0f),
100 vec4(0.0f, 0.0f, 0.0f, 1.0f)};
101}
102
103// Multiplies the given matrix by a X-rotation matrix. Equivalent to (but more
104// efficient than) 'A * rotateX(angle)'.
105[[nodiscard]] inline mat4 rotateX(const mat4& A, float angle)
106{
107 float s = sinf(angle);
108 float c = cosf(angle);
109 return {A[0],
110 A[1] * c + A[2] * s,
111 A[2] * c - A[1] * s,
112 A[3]};
113}
114
115// Returns a 4x4 rotation matrix for rotation around the Y-axis. Much more
116// efficient than calling the generic rotate() function with a vec3(0,1,0)
117// axis.
118[[nodiscard]] inline mat4 rotateY(float angle)
119{
120 float s = sinf(angle);
121 float c = cosf(angle);
122 return {vec4( c , 0.0f, -s , 0.0f),
123 vec4(0.0f, 1.0f, 0.0f, 0.0f),
124 vec4( s , 0.0f, c , 0.0f),
125 vec4(0.0f, 0.0f, 0.0f, 1.0f)};
126}
127
128// Multiplies the given matrix by a Y-rotation matrix. Equivalent to (but more
129// efficient than) 'A * rotateY(angle)'.
130[[nodiscard]] inline mat4 rotateY(const mat4& A, float angle)
131{
132 float s = sinf(angle);
133 float c = cosf(angle);
134 return {A[0] * c - A[2] * s,
135 A[1],
136 A[2] * c + A[0] * s,
137 A[3]};
138}
139
140// Returns a 4x4 rotation matrix for rotation around the Z-axis. Much more
141// efficient than calling the generic rotate() function with a vec3(0,0,1)
142// axis.
143[[nodiscard]] inline mat4 rotateZ(float angle)
144{
145 float s = sinf(angle);
146 float c = cosf(angle);
147 return {vec4( c , s , 0.0f, 0.0f),
148 vec4(-s , c , 0.0f, 0.0f),
149 vec4(0.0f, 0.0f, 1.0f, 0.0f),
150 vec4(0.0f, 0.0f, 0.0f, 1.0f)};
151}
152
153// Multiplies the given matrix by a Z-rotation matrix. Equivalent to (but more
154// efficient than) 'A * rotateZ(angle)'.
155[[nodiscard]] inline mat4 rotateZ(const mat4& A, float angle)
156{
157 float s = sinf(angle);
158 float c = cosf(angle);
159 return {A[0] * c + A[1] * s,
160 A[1] * c - A[0] * s,
161 A[2],
162 A[3]};
163}
164
165// Note: Don't use "near" or "far" as names since those are macros on Windows.
166
167// Returns a 4x4 orthographic projection matrix. Comparable to
168// the glOrtho() function.
169[[nodiscard]] constexpr mat4 ortho(
170 float left, float right,
171 float bottom, float top,
172 float nearVal, float farVal)
173{
174 return {vec4(-2.0f / (left - right), 0.0f, 0.0f, 0.0f),
175 vec4( 0.0f, -2.0f / (bottom - top), 0.0f, 0.0f),
176 vec4( 0.0f, 0.0f, 2.0f / (nearVal - farVal), 0.0f),
177 vec4((left + right ) / (left - right ),
178 (bottom + top ) / (bottom - top ),
179 (nearVal + farVal) / (nearVal - farVal),
180 1.0f)};
181}
182
183// Returns a 4x4 frustum projection matrix. Comparable to
184// the glFrustum() function.
185[[nodiscard]] constexpr mat4 frustum(
186 float left, float right,
187 float bottom, float top,
188 float nearVal, float farVal)
189{
190 return {vec4((2.0f * nearVal) / (right - left), 0.0f, 0.0f, 0.0f),
191 vec4(0.0f, (2.0f * nearVal) / (top - bottom), 0.0f, 0.0f),
192 vec4((right + left ) / (right - left ),
193 (top + bottom) / (top - bottom),
194 (nearVal + farVal) / (nearVal - farVal),
195 -1.0f),
196 vec4(0.0f,
197 0.0f,
198 (2.0f * farVal * nearVal) / (nearVal - farVal),
199 0.0f)};
200}
201
202} // namespace gl
203
204#endif
Definition: gl_mat.hh:23
mat4 rotateZ(float angle)
mat4 rotate(float angle, const vec3 &axis)
Definition: gl_transform.hh:58
mat4 rotateY(float angle)
mat4 rotateX(float angle)
Definition: gl_transform.hh:93
constexpr mat4 ortho(float left, float right, float bottom, float top, float nearVal, float farVal)
matMxN< 4, 4, float > mat4
Definition: gl_mat.hh:123
vecN< 4, float > vec4
Definition: gl_vec.hh:152
constexpr mat4 frustum(float left, float right, float bottom, float top, float nearVal, float farVal)
constexpr mat4 translate(const vec3 &xyz)
Definition: gl_transform.hh:36
constexpr mat4 scale(const vec3 &xyz)
Definition: gl_transform.hh:19
std::array< const EDStorage, 4 > A