actor: Reset the modelview matrix
authorEmmanuele Bassi <ebassi@linux.intel.com>
Mon, 19 Apr 2010 11:32:15 +0000 (12:32 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Thu, 3 Jun 2010 13:10:55 +0000 (14:10 +0100)
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

index cb5dd17..1cc8453 100644 (file)
@@ -2210,12 +2210,55 @@ _clutter_actor_get_relative_modelview (ClutterActor *self,
                                        ClutterActor *ancestor,
                                        CoglMatrix *matrix)
 {
-  _clutter_actor_ensure_stage_current (self);
+  ClutterActor *stage;
+  gfloat width, height;
+  CoglMatrix tmp_matrix;
+  gfloat z_camera;
+  ClutterPerspective perspective;
 
-  /* FIXME: init_identity instead of assuming we have an empty stack! */
+  _clutter_actor_ensure_stage_current (self);
 
   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);