4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 2008,2009 Intel Corporation.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
24
* Robert Bragg <robert@linux.intel.com>
27
#define USE_MESA_MATRIX_API
30
#include <cogl-matrix.h>
31
#include <cogl-matrix-private.h>
32
#ifdef USE_MESA_MATRIX_API
33
#include <cogl-matrix-mesa.h>
41
_cogl_matrix_print (CoglMatrix *matrix)
43
float *m = (float *)matrix;
46
for (y = 0; y < 4; y++)
47
g_print ("\t%6.4f %6.4f %6.4f %6.4f\n", m[y], m[4+y], m[8+y], m[12+y]);
51
cogl_matrix_init_identity (CoglMatrix *matrix)
53
#ifndef USE_MESA_MATRIX_API
54
matrix->xx = 1; matrix->xy = 0; matrix->xz = 0; matrix->xw = 0;
55
matrix->yx = 0; matrix->yy = 1; matrix->yz = 0; matrix->yw = 0;
56
matrix->zx = 0; matrix->zy = 0; matrix->zz = 1; matrix->zw = 0;
57
matrix->wx = 0; matrix->wy = 0; matrix->wz = 0; matrix->ww = 1;
59
_math_matrix_init_identity (matrix);
61
_COGL_MATRIX_DEBUG_PRINT (matrix);
65
cogl_matrix_multiply (CoglMatrix *result,
69
#ifndef USE_MESA_MATRIX_API
73
r.xx = a->xx * b->xx + a->xy * b->yx + a->xz * b->zx + a->xw * b->wx;
74
r.xy = a->xx * b->xy + a->xy * b->yy + a->xz * b->zy + a->xw * b->wy;
75
r.xz = a->xx * b->xz + a->xy * b->yz + a->xz * b->zz + a->xw * b->wz;
76
r.xw = a->xx * b->xw + a->xy * b->yw + a->xz * b->zw + a->xw * b->ww;
79
r.yx = a->yx * b->xx + a->yy * b->yx + a->yz * b->zx + a->yw * b->wx;
80
r.yy = a->yx * b->xy + a->yy * b->yy + a->yz * b->zy + a->yw * b->wy;
81
r.yz = a->yx * b->xz + a->yy * b->yz + a->yz * b->zz + a->yw * b->wz;
82
r.yw = a->yx * b->xw + a->yy * b->yw + a->yz * b->zw + a->yw * b->ww;
85
r.zx = a->zx * b->xx + a->zy * b->yx + a->zz * b->zx + a->zw * b->wx;
86
r.zy = a->zx * b->xy + a->zy * b->yy + a->zz * b->zy + a->zw * b->wy;
87
r.zz = a->zx * b->xz + a->zy * b->yz + a->zz * b->zz + a->zw * b->wz;
88
r.zw = a->zx * b->xw + a->zy * b->yw + a->zz * b->zw + a->zw * b->ww;
91
r.wx = a->wx * b->xx + a->wy * b->yx + a->wz * b->zx + a->ww * b->wx;
92
r.wy = a->wx * b->xy + a->wy * b->yy + a->wz * b->zy + a->ww * b->wy;
93
r.wz = a->wx * b->xz + a->wy * b->yz + a->wz * b->zz + a->ww * b->wz;
94
r.ww = a->wx * b->xw + a->wy * b->yw + a->wz * b->zw + a->ww * b->ww;
96
/* The idea was that having this unrolled; it might be easier for the
97
* compiler to vectorize, but that's probably not true. Mesa does it
98
* using a single for (i=0; i<4; i++) approach, maybe that's better...
103
_math_matrix_multiply (result, a, b);
105
_COGL_MATRIX_DEBUG_PRINT (result);
109
cogl_matrix_rotate (CoglMatrix *matrix,
115
#ifndef USE_MESA_MATRIX_API
120
angle *= G_PI / 180.0f;
124
rotation.xx = x * x * (1.0f - c) + c;
125
rotation.yx = y * x * (1.0f - c) + z * s;
126
rotation.zx = x * z * (1.0f - c) - y * s;
129
rotation.xy = x * y * (1.0f - c) - z * s;
130
rotation.yy = y * y * (1.0f - c) + c;
131
rotation.zy = y * z * (1.0f - c) + x * s;
134
rotation.xz = x * z * (1.0f - c) + y * s;
135
rotation.yz = y * z * (1.0f - c) - x * s;
136
rotation.zz = z * z * (1.0f - c) + c;
144
cogl_matrix_multiply (&result, matrix, &rotation);
147
_math_matrix_rotate (matrix, angle, x, y, z);
149
_COGL_MATRIX_DEBUG_PRINT (matrix);
153
cogl_matrix_translate (CoglMatrix *matrix,
158
#ifndef USE_MESA_MATRIX_API
159
matrix->xw = matrix->xx * x + matrix->xy * y + matrix->xz * z + matrix->xw;
160
matrix->yw = matrix->yx * x + matrix->yy * y + matrix->yz * z + matrix->yw;
161
matrix->zw = matrix->zx * x + matrix->zy * y + matrix->zz * z + matrix->zw;
162
matrix->ww = matrix->wx * x + matrix->wy * y + matrix->wz * z + matrix->ww;
164
_math_matrix_translate (matrix, x, y, z);
166
_COGL_MATRIX_DEBUG_PRINT (matrix);
170
cogl_matrix_scale (CoglMatrix *matrix,
175
#ifndef USE_MESA_MATRIX_API
176
matrix->xx *= sx; matrix->xy *= sy; matrix->xz *= sz;
177
matrix->yx *= sx; matrix->yy *= sy; matrix->yz *= sz;
178
matrix->zx *= sx; matrix->zy *= sy; matrix->zz *= sz;
179
matrix->wx *= sx; matrix->wy *= sy; matrix->wz *= sz;
181
_math_matrix_scale (matrix, sx, sy, sz);
183
_COGL_MATRIX_DEBUG_PRINT (matrix);
187
cogl_matrix_frustum (CoglMatrix *matrix,
195
#ifndef USE_MESA_MATRIX_API
196
float x, y, a, b, c, d;
199
x = (2.0f * z_near) / (right - left);
200
y = (2.0f * z_near) / (top - bottom);
201
a = (right + left) / (right - left);
202
b = (top + bottom) / (top - bottom);
203
c = -(z_far + z_near) / ( z_far - z_near);
204
d = -(2.0f * z_far* z_near) / (z_far - z_near);
226
cogl_matrix_multiply (matrix, matrix, &frustum);
228
_math_matrix_frustum (matrix, left, right, bottom, top, z_near, z_far);
230
_COGL_MATRIX_DEBUG_PRINT (matrix);
234
cogl_matrix_perspective (CoglMatrix *matrix,
240
float ymax = z_near * tan (fov_y * G_PI / 360.0);
242
cogl_matrix_frustum (matrix,
243
-ymax * aspect, /* left */
244
ymax * aspect, /* right */
249
_COGL_MATRIX_DEBUG_PRINT (matrix);
253
cogl_matrix_ortho (CoglMatrix *matrix,
261
#ifndef USE_MESA_MATRIX_API
265
ortho.xx = 2.0 / (right - left);
272
ortho.yy = 2.0 / (top - bottom);
279
ortho.zz = -2.0 / (far_val - near_val);
283
ortho.xw = -(right + left) / (right - left);
284
ortho.yw = -(top + bottom) / (top - bottom);
285
ortho.zw = -(far_val + near_val) / (far_val - near_val);
288
cogl_matrix_multiply (matrix, matrix, &ortho);
290
_math_matrix_ortho (matrix, left, right, bottom, top, near_val, far_val);
292
_COGL_MATRIX_DEBUG_PRINT (matrix);
296
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
298
#ifndef USE_MESA_MATRIX_API
299
memcpy (matrix, array, sizeof (float) * 16);
301
_math_matrix_init_from_array (matrix, array);
303
_COGL_MATRIX_DEBUG_PRINT (matrix);
307
cogl_matrix_get_array (const CoglMatrix *matrix)
309
return (float *)matrix;
313
cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse)
315
#ifndef USE_MESA_MATRIX_API
316
#warning "cogl_matrix_get_inverse not supported without Mesa matrix API"
317
cogl_matrix_init_identity (inverse);
320
if (_math_matrix_update_inverse ((CoglMatrix *)matrix))
322
cogl_matrix_init_from_array (inverse, matrix->inv);
327
cogl_matrix_init_identity (inverse);
334
cogl_matrix_transform_point (const CoglMatrix *matrix,
340
float _x = *x, _y = *y, _z = *z, _w = *w;
342
*x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w;
343
*y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w;
344
*z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w;
345
*w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w;