~ubuntu-branches/ubuntu/vivid/clutter-1.0/vivid-proposed

« back to all changes in this revision

Viewing changes to clutter/cogl/cogl/cogl-matrix.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-07-18 17:21:49 UTC
  • mfrom: (1.2.1 upstream) (4.1.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20100718172149-j6s9u4chocaoykme
Tags: 1.2.12-1
* New upstream release.
* debian/libclutter-1.0-0.symbols,
  debian/rules:
  - Add a symbols file.
* debian/rules,
  debian/source/format:
  - Switch to source format 3.0 (quilt).
* debian/control.in:
  - Standards-Version is 3.9.0, no changes needed.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Cogl
 
3
 *
 
4
 * An object oriented GL/GLES Abstraction/Utility Layer
 
5
 *
 
6
 * Copyright (C) 2008,2009 Intel Corporation.
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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/>.
 
20
 *
 
21
 *
 
22
 *
 
23
 * Authors:
 
24
 *   Robert Bragg <robert@linux.intel.com>
 
25
 */
 
26
 
 
27
#define USE_MESA_MATRIX_API
 
28
 
 
29
#include <cogl.h>
 
30
#include <cogl-matrix.h>
 
31
#include <cogl-matrix-private.h>
 
32
#ifdef USE_MESA_MATRIX_API
 
33
#include <cogl-matrix-mesa.h>
 
34
#endif
 
35
 
 
36
#include <glib.h>
 
37
#include <math.h>
 
38
#include <string.h>
 
39
 
 
40
void
 
41
_cogl_matrix_print (CoglMatrix *matrix)
 
42
{
 
43
  float *m = (float *)matrix;
 
44
  int y;
 
45
 
 
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]);
 
48
}
 
49
 
 
50
void
 
51
cogl_matrix_init_identity (CoglMatrix *matrix)
 
52
{
 
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;
 
58
#else
 
59
  _math_matrix_init_identity (matrix);
 
60
#endif
 
61
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
62
}
 
63
 
 
64
void
 
65
cogl_matrix_multiply (CoglMatrix *result,
 
66
                      const CoglMatrix *a,
 
67
                      const CoglMatrix *b)
 
68
{
 
69
#ifndef USE_MESA_MATRIX_API
 
70
  CoglMatrix r;
 
71
 
 
72
  /* row 0 */
 
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;
 
77
 
 
78
  /* row 1 */
 
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;
 
83
 
 
84
  /* row 2 */
 
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;
 
89
 
 
90
  /* row 3 */
 
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;
 
95
 
 
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...
 
99
   */
 
100
 
 
101
  *result = r;
 
102
#else
 
103
  _math_matrix_multiply (result, a, b);
 
104
#endif
 
105
  _COGL_MATRIX_DEBUG_PRINT (result);
 
106
}
 
107
 
 
108
void
 
109
cogl_matrix_rotate (CoglMatrix *matrix,
 
110
                    float angle,
 
111
                    float x,
 
112
                    float y,
 
113
                    float z)
 
114
{
 
115
#ifndef USE_MESA_MATRIX_API
 
116
  CoglMatrix rotation;
 
117
  CoglMatrix result;
 
118
  float c, s;
 
119
 
 
120
  angle *= G_PI / 180.0f;
 
121
  c = cosf (angle);
 
122
  s = sinf (angle);
 
123
 
 
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;
 
127
  rotation.wx = 0.0f;
 
128
 
 
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;
 
132
  rotation.wy = 0.0f;
 
133
 
 
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;
 
137
  rotation.wz = 0.0f;
 
138
 
 
139
  rotation.xw = 0.0f;
 
140
  rotation.yw = 0.0f;
 
141
  rotation.zw = 0.0f;
 
142
  rotation.ww = 1.0f;
 
143
 
 
144
  cogl_matrix_multiply (&result, matrix, &rotation);
 
145
  *matrix = result;
 
146
#else
 
147
  _math_matrix_rotate (matrix, angle, x, y, z);
 
148
#endif
 
149
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
150
}
 
151
 
 
152
void
 
153
cogl_matrix_translate (CoglMatrix *matrix,
 
154
                       float x,
 
155
                       float y,
 
156
                       float z)
 
157
{
 
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;
 
163
#else
 
164
  _math_matrix_translate (matrix, x, y, z);
 
165
#endif
 
166
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
167
}
 
168
 
 
169
void
 
170
cogl_matrix_scale (CoglMatrix *matrix,
 
171
                   float sx,
 
172
                   float sy,
 
173
                   float sz)
 
174
{
 
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;
 
180
#else
 
181
  _math_matrix_scale (matrix, sx, sy, sz);
 
182
#endif
 
183
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
184
}
 
185
 
 
186
void
 
187
cogl_matrix_frustum (CoglMatrix *matrix,
 
188
                     float       left,
 
189
                     float       right,
 
190
                     float       bottom,
 
191
                     float       top,
 
192
                     float       z_near,
 
193
                     float       z_far)
 
194
{
 
195
#ifndef USE_MESA_MATRIX_API
 
196
  float x, y, a, b, c, d;
 
197
  CoglMatrix frustum;
 
198
 
 
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);
 
205
 
 
206
  frustum.xx = x;
 
207
  frustum.yx = 0.0f;
 
208
  frustum.zx = 0.0f;
 
209
  frustum.wx = 0.0f;
 
210
 
 
211
  frustum.xy = 0.0f;
 
212
  frustum.yy = y;
 
213
  frustum.zy = 0.0f;
 
214
  frustum.wy = 0.0f;
 
215
 
 
216
  frustum.xz = a;
 
217
  frustum.yz = b;
 
218
  frustum.zz = c;
 
219
  frustum.wz = -1.0f;
 
220
 
 
221
  frustum.xw = 0.0f;
 
222
  frustum.yw = 0.0f;
 
223
  frustum.zw = d;
 
224
  frustum.ww = 0.0f;
 
225
 
 
226
  cogl_matrix_multiply (matrix, matrix, &frustum);
 
227
#else
 
228
  _math_matrix_frustum (matrix, left, right, bottom, top, z_near, z_far);
 
229
#endif
 
230
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
231
}
 
232
 
 
233
void
 
234
cogl_matrix_perspective (CoglMatrix *matrix,
 
235
                         float       fov_y,
 
236
                         float       aspect,
 
237
                         float       z_near,
 
238
                         float       z_far)
 
239
{
 
240
  float ymax = z_near * tan (fov_y * G_PI / 360.0);
 
241
 
 
242
  cogl_matrix_frustum (matrix,
 
243
                       -ymax * aspect,  /* left */
 
244
                       ymax * aspect,   /* right */
 
245
                       -ymax,           /* bottom */
 
246
                       ymax,            /* top */
 
247
                       z_near,
 
248
                       z_far);
 
249
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
250
}
 
251
 
 
252
void
 
253
cogl_matrix_ortho (CoglMatrix *matrix,
 
254
                   float left,
 
255
                   float right,
 
256
                   float bottom,
 
257
                   float top,
 
258
                   float near_val,
 
259
                   float far_val)
 
260
{
 
261
#ifndef USE_MESA_MATRIX_API
 
262
  CoglMatrix ortho;
 
263
 
 
264
  /* column 0 */
 
265
  ortho.xx = 2.0 / (right - left);
 
266
  ortho.yx = 0.0;
 
267
  ortho.zx = 0.0;
 
268
  ortho.wx = 0.0;
 
269
 
 
270
  /* column 1 */
 
271
  ortho.xy = 0.0;
 
272
  ortho.yy = 2.0 / (top - bottom);
 
273
  ortho.zy = 0.0;
 
274
  ortho.wy = 0.0;
 
275
 
 
276
  /* column 2 */
 
277
  ortho.xz = 0.0;
 
278
  ortho.yz = 0.0;
 
279
  ortho.zz = -2.0 / (far_val - near_val);
 
280
  ortho.wz = 0.0;
 
281
 
 
282
  /* column 3 */
 
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);
 
286
  ortho.ww = 1.0;
 
287
 
 
288
  cogl_matrix_multiply (matrix, matrix, &ortho);
 
289
#else
 
290
  _math_matrix_ortho (matrix, left, right, bottom, top, near_val, far_val);
 
291
#endif
 
292
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
293
}
 
294
 
 
295
void
 
296
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
 
297
{
 
298
#ifndef USE_MESA_MATRIX_API
 
299
  memcpy (matrix, array, sizeof (float) * 16);
 
300
#else
 
301
  _math_matrix_init_from_array (matrix, array);
 
302
#endif
 
303
  _COGL_MATRIX_DEBUG_PRINT (matrix);
 
304
}
 
305
 
 
306
const float *
 
307
cogl_matrix_get_array (const CoglMatrix *matrix)
 
308
{
 
309
  return (float *)matrix;
 
310
}
 
311
 
 
312
gboolean
 
313
cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse)
 
314
{
 
315
#ifndef USE_MESA_MATRIX_API
 
316
#warning "cogl_matrix_get_inverse not supported without Mesa matrix API"
 
317
  cogl_matrix_init_identity (inverse);
 
318
  return FALSE;
 
319
#else
 
320
  if (_math_matrix_update_inverse ((CoglMatrix *)matrix))
 
321
    {
 
322
      cogl_matrix_init_from_array (inverse, matrix->inv);
 
323
      return TRUE;
 
324
    }
 
325
  else
 
326
    {
 
327
      cogl_matrix_init_identity (inverse);
 
328
      return FALSE;
 
329
    }
 
330
#endif
 
331
}
 
332
 
 
333
void
 
334
cogl_matrix_transform_point (const CoglMatrix *matrix,
 
335
                             float *x,
 
336
                             float *y,
 
337
                             float *z,
 
338
                             float *w)
 
339
{
 
340
  float _x = *x, _y = *y, _z = *z, _w = *w;
 
341
 
 
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;
 
346
}
 
347
 
 
348