4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 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, write to the
20
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
* Boston, MA 02111-1307, USA.
24
* Havoc Pennington <hp@pobox.com> for litl
25
* Robert Bragg <robert@linux.intel.com>
33
#include "cogl-context.h"
34
#include "cogl-internal.h"
35
#include "cogl-current-matrix.h"
36
#include "cogl-matrix-stack.h"
38
#ifdef HAVE_COGL_GLES2
39
#include "cogl-gles2-wrapper.h"
41
#define glFrustum(L,R,B,T,N,F) \
42
cogl_wrap_glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
43
(GLfloat)T, (GLfloat)N, (GLfloat)F)
44
#elif defined (HAVE_COGL_GLES)
46
#define glFrustum(L,R,B,T,N,F) \
47
glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
48
(GLfloat)T, (GLfloat)N, (GLfloat)F)
50
#define glOrtho glOrthof
58
_cogl_get_client_stack (CoglContext *ctx,
60
CoglMatrixStack **current_stack_p)
62
if (ctx->modelview_stack &&
63
mode == COGL_MATRIX_MODELVIEW)
64
*current_stack_p = ctx->modelview_stack;
65
else if (ctx->projection_stack &&
66
mode == COGL_MATRIX_PROJECTION)
67
*current_stack_p = ctx->projection_stack;
69
*current_stack_p = NULL;
72
#define _COGL_GET_CONTEXT_AND_STACK(contextvar, stackvar, rval) \
73
CoglMatrixStack *stackvar; \
74
_COGL_GET_CONTEXT (contextvar, rval); \
75
_cogl_get_client_stack (contextvar, ctx->matrix_mode, &stackvar)
78
_cogl_set_current_matrix (CoglMatrixMode mode)
81
CoglMatrixStack *current_stack; \
82
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
84
if (mode == ctx->matrix_mode)
86
ctx->matrix_mode = mode;
88
/* If we have a client side stack then then the GL matrix mode only needs
89
* changing when we come to flush it to OpenGL */
90
_cogl_get_client_stack (ctx, mode, ¤t_stack);
94
gl_mode = 0; /* silence compiler warning */
97
case COGL_MATRIX_MODELVIEW:
98
gl_mode = GL_MODELVIEW;
100
case COGL_MATRIX_PROJECTION:
101
gl_mode = GL_PROJECTION;
103
case COGL_MATRIX_TEXTURE:
104
gl_mode = GL_TEXTURE;
108
GE (glMatrixMode (gl_mode));
112
_cogl_current_matrix_push (void)
114
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
116
if (current_stack != NULL)
117
_cogl_matrix_stack_push (current_stack);
119
GE (glPushMatrix ());
123
_cogl_current_matrix_pop (void)
125
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
127
if (current_stack != NULL)
128
_cogl_matrix_stack_pop (current_stack);
134
_cogl_current_matrix_identity (void)
136
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
138
if (current_stack != NULL)
139
_cogl_matrix_stack_load_identity (current_stack);
141
GE (glLoadIdentity ());
145
_cogl_current_matrix_load (const CoglMatrix *matrix)
147
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
149
if (current_stack != NULL)
150
_cogl_matrix_stack_set (current_stack, matrix);
152
GE (glLoadMatrixf (cogl_matrix_get_array (matrix)));
156
_cogl_current_matrix_multiply (const CoglMatrix *matrix)
158
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
160
if (current_stack != NULL)
161
_cogl_matrix_stack_multiply (current_stack, matrix);
163
GE (glMultMatrixf (cogl_matrix_get_array (matrix)));
167
_cogl_current_matrix_rotate (float angle,
172
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
174
if (current_stack != NULL)
175
_cogl_matrix_stack_rotate (current_stack, angle, x, y, z);
177
GE (glRotatef (angle, x, y, z));
181
_cogl_current_matrix_scale (float x,
185
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
187
if (current_stack != NULL)
188
_cogl_matrix_stack_scale (current_stack, x, y, z);
190
GE (glScalef (x, y, z));
194
_cogl_current_matrix_translate (float x,
198
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
200
if (current_stack != NULL)
201
_cogl_matrix_stack_translate (current_stack, x, y, z);
203
GE (glTranslatef (x, y, z));
207
_cogl_current_matrix_frustum (float left,
214
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
216
if (current_stack != NULL)
217
_cogl_matrix_stack_frustum (current_stack,
223
GE (glFrustum (left, right, bottom, top, near_val, far_val));
227
_cogl_current_matrix_perspective (float fov_y,
232
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
234
if (current_stack != NULL)
235
_cogl_matrix_stack_perspective (current_stack,
236
fov_y, aspect, z_near, z_far);
239
/* NB: There is no glPerspective() (only gluPerspective()) so we use
240
* cogl_matrix_perspective: */
242
_cogl_get_matrix (ctx->matrix_mode, &matrix);
243
cogl_matrix_perspective (&matrix,
244
fov_y, aspect, z_near, z_far);
245
_cogl_current_matrix_load (&matrix);
250
_cogl_current_matrix_ortho (float left,
257
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
259
if (current_stack != NULL)
260
_cogl_matrix_stack_ortho (current_stack,
267
#ifdef HAVE_COGL_GLES2
268
/* NB: GLES 2 has no glOrtho(): */
270
_cogl_get_matrix (ctx->matrix_mode, &matrix);
271
cogl_matrix_ortho (&matrix,
272
left, right, bottom, top, near_val, far_val);
273
_cogl_current_matrix_load (&matrix);
275
GE (glOrtho (left, right, bottom, top, near_val, far_val));
281
_cogl_get_matrix (CoglMatrixMode mode,
284
CoglMatrixStack *current_stack;
285
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
287
_cogl_get_client_stack (ctx, mode, ¤t_stack);
290
_cogl_matrix_stack_get (current_stack, matrix);
294
GLfloat gl_matrix[16];
296
gl_mode = 0; /* silence compiler warning */
299
case COGL_MATRIX_MODELVIEW:
300
gl_mode = GL_MODELVIEW_MATRIX;
302
case COGL_MATRIX_PROJECTION:
303
gl_mode = GL_PROJECTION_MATRIX;
305
case COGL_MATRIX_TEXTURE:
306
gl_mode = GL_TEXTURE_MATRIX;
310
/* Note: we have a redundant copy happening here. If that turns out to be
311
* a problem then, since this is internal to Cogl, we could pass the
312
* CoglMatrix pointer directly to glGetFloatv; the only problem with that
313
* is that if we later add internal flags to CoglMatrix they will need to
314
* be initialized seperatly.
316
GE (glGetFloatv (gl_mode, gl_matrix));
317
cogl_matrix_init_from_array (matrix, gl_matrix);
322
_cogl_set_matrix (const CoglMatrix *matrix)
324
_cogl_current_matrix_load (matrix);
328
_cogl_current_matrix_state_init (void)
330
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
332
ctx->matrix_mode = COGL_MATRIX_MODELVIEW;
333
ctx->modelview_stack = NULL;
334
ctx->projection_stack = NULL;
338
cogl_debug_flags & COGL_DEBUG_FORCE_CLIENT_SIDE_MATRICES)
341
ctx->modelview_stack = _cogl_matrix_stack_new ();
342
ctx->projection_stack = _cogl_matrix_stack_new ();
347
_cogl_current_matrix_state_destroy (void)
349
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
352
_cogl_matrix_stack_destroy (current_stack);
356
_cogl_current_matrix_state_flush (void)
358
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
360
if (ctx->matrix_mode != COGL_MATRIX_MODELVIEW &&
361
ctx->matrix_mode != COGL_MATRIX_PROJECTION)
363
g_warning ("matrix state must be flushed in "
364
"MODELVIEW or PROJECTION mode");
368
if (ctx->modelview_stack &&
369
ctx->matrix_mode == COGL_MATRIX_MODELVIEW)
371
_cogl_matrix_stack_flush_to_gl (ctx->modelview_stack,
374
else if (ctx->projection_stack &&
375
ctx->matrix_mode == COGL_MATRIX_PROJECTION)
377
_cogl_matrix_stack_flush_to_gl (ctx->projection_stack,
383
_cogl_current_matrix_state_dirty (void)
385
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
388
_cogl_matrix_stack_dirty (current_stack);
392
cogl_push_matrix (void)
394
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
395
_cogl_current_matrix_push ();
399
cogl_pop_matrix (void)
401
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
402
_cogl_current_matrix_pop ();
406
cogl_scale (float x, float y, float z)
408
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
409
_cogl_current_matrix_scale (x, y, z);
413
cogl_translate (float x, float y, float z)
415
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
416
_cogl_current_matrix_translate (x, y, z);
420
cogl_rotate (float angle, float x, float y, float z)
422
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
423
_cogl_current_matrix_rotate (angle, x, y, z);
427
cogl_perspective (float fov_y,
432
float ymax = z_near * tanf (fov_y * G_PI / 360.0);
434
cogl_frustum (-ymax * aspect, /* left */
435
ymax * aspect, /* right */
443
cogl_frustum (float left,
452
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
454
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
455
_cogl_current_matrix_identity ();
457
_cogl_current_matrix_frustum (left,
464
/* Calculate and store the inverse of the matrix */
465
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
467
c = - (z_far + z_near) / (z_far - z_near);
468
d = - (2 * (z_far * z_near)) / (z_far - z_near);
470
#define M(row,col) ctx->inverse_projection[col*4+row]
471
M(0,0) = (right - left) / (2 * z_near);
472
M(0,3) = (right + left) / (2 * z_near);
473
M(1,1) = (top - bottom) / (2 * z_near);
474
M(1,3) = (top + bottom) / (2 * z_near);
480
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
484
cogl_ortho (float left,
492
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
494
cogl_matrix_init_identity (&ortho);
495
cogl_matrix_ortho (&ortho, left, right, bottom, top, z_near, z_far);
496
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
497
_cogl_current_matrix_load (&ortho);
499
/* Calculate and store the inverse of the matrix */
500
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
502
#define M(row,col) ctx->inverse_projection[col*4+row]
503
M(0,0) = 1.0 / ortho.xx;
505
M(1,1) = 1.0 / ortho.yy;
507
M(2,2) = 1.0 / ortho.zz;
514
cogl_get_modelview_matrix (CoglMatrix *matrix)
516
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
521
cogl_set_modelview_matrix (CoglMatrix *matrix)
523
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
524
_cogl_current_matrix_load (matrix);
528
cogl_get_projection_matrix (CoglMatrix *matrix)
530
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
535
cogl_set_projection_matrix (CoglMatrix *matrix)
537
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
538
_cogl_current_matrix_load (matrix);
542
_cogl_flush_matrix_stacks (void)
544
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
545
_cogl_current_matrix_state_flush ();
546
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
547
_cogl_current_matrix_state_flush ();