From 5ffbcbe9ee7d0b74bc5048fafd2ea15ee0486a58 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 19 Apr 2010 12:32:15 +0100 Subject: [PATCH] actor: Reset the modelview matrix When getting the relative modelview matrix we need to reset it to the stage's initial state or, at least, initialize it to the identity matrix, instead of assuming we have an empty stack. --- clutter/clutter-actor.c | 47 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index cb5dd1775..1cc84535b 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -2210,12 +2210,55 @@ _clutter_actor_get_relative_modelview (ClutterActor *self, ClutterActor *ancestor, CoglMatrix *matrix) { + ClutterActor *stage; + gfloat width, height; + CoglMatrix tmp_matrix; + gfloat z_camera; + ClutterPerspective perspective; + _clutter_actor_ensure_stage_current (self); - /* FIXME: init_identity instead of assuming we have an empty stack! */ - cogl_push_matrix (); + if (ancestor == NULL) + { + stage = clutter_actor_get_stage (self); + + clutter_stage_get_perspective (CLUTTER_STAGE (stage), &perspective); + cogl_perspective (perspective.fovy, + perspective.aspect, + perspective.z_near, + perspective.z_far); + + cogl_get_projection_matrix (&tmp_matrix); + z_camera = 0.5f * tmp_matrix.xx; + + clutter_actor_get_size (stage, &width, &height); + + /* obliterate the current modelview matrix and reset it to be + * the same as the stage's at the beginning of a paint run; this + * is done to paint the target material in screen coordinates at + * the same place as the actor would have been + */ + cogl_matrix_init_identity (&tmp_matrix); + cogl_matrix_translate (&tmp_matrix, -0.5f, -0.5f, -z_camera); + cogl_matrix_scale (&tmp_matrix, 1.0f / width, -1.0f / height, 1.0f / width); + cogl_matrix_translate (&tmp_matrix, 0.0f, -1.0f * height, 0.0f); + cogl_set_modelview_matrix (&tmp_matrix); + } + else + { + static CoglMatrix identity; + static gboolean initialized_identity = FALSE; + + if (!initialized_identity) + { + cogl_matrix_init_identity (&identity); + initialized_identity = TRUE; + } + cogl_set_modelview_matrix (&identity); + } + _clutter_actor_apply_modelview_transform_recursive (self, ancestor); cogl_get_modelview_matrix (matrix);