diff --git a/clutter/cogl/cogl/cogl-context.c b/clutter/cogl/cogl/cogl-context.c index 0f309bd06..ccd71c7d0 100644 --- a/clutter/cogl/cogl/cogl-context.c +++ b/clutter/cogl/cogl/cogl-context.c @@ -71,6 +71,10 @@ cogl_create_context (void) _context->indirect = gl_is_indirect; + cogl_matrix_init_identity (&_context->identity_matrix); + cogl_matrix_init_identity (&_context->y_flip_matrix); + cogl_matrix_scale (&_context->y_flip_matrix, 1, -1, 1); + _context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW; _context->texture_units = NULL; diff --git a/clutter/cogl/cogl/cogl-context.h b/clutter/cogl/cogl/cogl-context.h index 67e33cc68..1d3f9ecf3 100644 --- a/clutter/cogl/cogl/cogl-context.h +++ b/clutter/cogl/cogl/cogl-context.h @@ -52,6 +52,10 @@ typedef struct gboolean indirect; + /* A few handy matrix constants */ + CoglMatrix identity_matrix; + CoglMatrix y_flip_matrix; + /* Client-side matrix stack or NULL if none */ CoglMatrixMode flushed_matrix_mode; GList *texture_units; diff --git a/clutter/cogl/cogl/cogl-draw-buffer-private.h b/clutter/cogl/cogl/cogl-draw-buffer-private.h index d5bdf0b11..5ad4fc896 100644 --- a/clutter/cogl/cogl/cogl-draw-buffer-private.h +++ b/clutter/cogl/cogl/cogl-draw-buffer-private.h @@ -115,6 +115,9 @@ _cogl_draw_buffer_flush_state (CoglHandle handle, CoglHandle _cogl_onscreen_new (void); +gboolean +cogl_is_offscreen (CoglHandle handle); + CoglHandle _cogl_get_draw_buffer (void); GSList * diff --git a/clutter/cogl/cogl/cogl-matrix-stack.c b/clutter/cogl/cogl/cogl-matrix-stack.c index b1f21c946..4e2269dbc 100644 --- a/clutter/cogl/cogl/cogl-matrix-stack.c +++ b/clutter/cogl/cogl/cogl-matrix-stack.c @@ -22,6 +22,7 @@ * * Authors: * Havoc Pennington for litl + * Robert Bragg */ #ifdef HAVE_CONFIG_H @@ -32,6 +33,7 @@ #include "cogl-context.h" #include "cogl-internal.h" #include "cogl-matrix-stack.h" +#include "cogl-draw-buffer-private.h" typedef struct { CoglMatrix matrix; @@ -412,21 +414,35 @@ _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack, ctx->flushed_matrix_mode = mode; } - /* In theory it might help the GL implementation if we used our - * local analysis of the matrix and called Translate/Scale rather - * than LoadMatrix to send a 2D matrix + /* Because Cogl defines texture coordinates to have a top left origin and + * because offscreen draw buffers may be used for rendering to textures we + * always render upside down to offscreen buffers. */ - - if (state->is_identity) + if (mode == COGL_MATRIX_PROJECTION && + cogl_is_offscreen (_cogl_get_draw_buffer ())) { - if (!stack->flushed_identity) - GE (glLoadIdentity ()); - stack->flushed_identity = TRUE; + CoglMatrix flipped_projection; + CoglMatrix *projection = + state->is_identity ? &ctx->identity_matrix : &state->matrix; + + cogl_matrix_multiply (&flipped_projection, + &ctx->y_flip_matrix, projection); + GE (glLoadMatrixf (cogl_matrix_get_array (&flipped_projection))); + stack->flushed_identity = FALSE; } else { - GE (glLoadMatrixf (cogl_matrix_get_array (&state->matrix))); - stack->flushed_identity = FALSE; + if (state->is_identity) + { + if (!stack->flushed_identity) + GE (glLoadIdentity ()); + stack->flushed_identity = TRUE; + } + else + { + GE (glLoadMatrixf (cogl_matrix_get_array (&state->matrix))); + stack->flushed_identity = FALSE; + } } stack->flushed_state = state; }