openMSX
gl_transform.hh
Go to the documentation of this file.
1 #ifndef GL_TRANSFORM_HH
2 #define GL_TRANSFORM_HH
3 
4 // OpenGLES 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 
15 namespace gl {
16 
17 // Returns a 4x4 scaling matrix for the given xyz scale factors.
18 // Comparable to the glScale() function.
19 inline 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 inline 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 inline 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 inline 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 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 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 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 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 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 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 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 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 inline mat4 ortho(float left, float right,
170  float bottom, float top,
171  float nearVal, float farVal)
172 {
173  return {vec4(-2.0f / (left - right), 0.0f, 0.0f, 0.0f),
174  vec4( 0.0f, -2.0f / (bottom - top), 0.0f, 0.0f),
175  vec4( 0.0f, 0.0f, 2.0f / (nearVal - farVal), 0.0f),
176  vec4((left + right ) / (left - right ),
177  (bottom + top ) / (bottom - top ),
178  (nearVal + farVal) / (nearVal - farVal),
179  1.0f)};
180 }
181 
182 // Returns a 4x4 frustum projection matrix. Comparable to
183 // the glFrustum() function.
184 inline mat4 frustum(float left, float right,
185  float bottom, float top,
186  float nearVal, float farVal)
187 {
188  return {vec4((2.0f * nearVal) / (right - left), 0.0f, 0.0f, 0.0f),
189  vec4(0.0f, (2.0f * nearVal) / (top - bottom), 0.0f, 0.0f),
190  vec4((right + left ) / (right - left ),
191  (top + bottom) / (top - bottom),
192  (nearVal + farVal) / (nearVal - farVal),
193  -1.0f),
194  vec4(0.0f,
195  0.0f,
196  (2.0f * farVal * nearVal) / (nearVal - farVal),
197  0.0f)};
198 }
199 
200 } // namespace gl
201 
202 #endif
mat4 frustum(float left, float right, float bottom, float top, float nearVal, float farVal)
mat4 rotateY(float angle)
matMxN< 4, 4, float > mat4
Definition: gl_mat.hh:159
mat4 scale(const vec3 &xyz)
Definition: gl_transform.hh:19
vecN< 4, float > vec4
Definition: gl_vec.hh:141
mat4 rotateZ(float angle)
mat4 translate(const vec3 &xyz)
Definition: gl_transform.hh:36
mat4 rotate(float angle, const vec3 &axis)
Definition: gl_transform.hh:58
mat4 ortho(float left, float right, float bottom, float top, float nearVal, float farVal)
mat4 rotateX(float angle)
Definition: gl_transform.hh:93
Definition: gl_mat.hh:24