void _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, ClutterStage *stage, ClutterActorBox *box) { ClutterPaintVolume projected_pv; CoglMatrix modelview; CoglMatrix projection; float viewport[4]; _clutter_paint_volume_copy_static (pv, &projected_pv); cogl_matrix_init_identity (&modelview); /* If the paint volume isn't already in eye coordinates... */ if (pv->actor) _clutter_actor_apply_relative_transformation_matrix (pv->actor, NULL, &modelview); _clutter_stage_get_projection_matrix (stage, &projection); _clutter_stage_get_viewport (stage, &viewport[0], &viewport[1], &viewport[2], &viewport[3]); _clutter_paint_volume_project (&projected_pv, &modelview, &projection, viewport); _clutter_paint_volume_get_bounding_box (&projected_pv, box); _clutter_actor_box_enlarge_for_effects (box); clutter_paint_volume_free (&projected_pv); }
void _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, ClutterStage *stage, ClutterActorBox *box) { ClutterPaintVolume projected_pv; CoglMatrix modelview; CoglMatrix projection; float viewport[4]; float width; float height; _clutter_paint_volume_copy_static (pv, &projected_pv); cogl_matrix_init_identity (&modelview); /* If the paint volume isn't already in eye coordinates... */ if (pv->actor) _clutter_actor_apply_relative_transformation_matrix (pv->actor, NULL, &modelview); _clutter_stage_get_projection_matrix (stage, &projection); _clutter_stage_get_viewport (stage, &viewport[0], &viewport[1], &viewport[2], &viewport[3]); _clutter_paint_volume_project (&projected_pv, &modelview, &projection, viewport); _clutter_paint_volume_get_bounding_box (&projected_pv, box); /* The aim here is that for a given rectangle defined with floating point * coordinates we want to determine a stable quantized size in pixels * that doesn't vary due to the original box's sub-pixel position. * * The reason this is important is because effects will use this * API to determine the size of offscreen framebuffers and so for * a fixed-size object that may be animated accross the screen we * want to make sure that the stage paint-box has an equally stable * size so that effects aren't made to continuously re-allocate * a corresponding fbo. * * The other thing we consider is that the calculation of this box is * subject to floating point precision issues that might be slightly * different to the precision issues involved with actually painting the * actor, which might result in painting slightly leaking outside the * user's calculated paint-volume. For this we simply aim to pad out the * paint-volume by at least half a pixel all the way around. */ width = box->x2 - box->x1; height = box->y2 - box->y1; width = CLUTTER_NEARBYINT (width); height = CLUTTER_NEARBYINT (height); /* XXX: NB the width/height may now be up to 0.5px too small so we * must also pad by 0.25px all around to account for this. In total we * must padd by at least 0.75px around all sides. */ /* XXX: The furthest that we can overshoot the bottom right corner by * here is 1.75px in total if you consider that the 0.75 padding could * just cross an integer boundary and so ceil will effectively add 1. */ box->x2 = ceilf (box->x2 + 0.75); box->y2 = ceilf (box->y2 + 0.75); /* Now we redefine the top-left relative to the bottom right based on the * rounded width/height determined above + a constant so that the overall * size of the box will be stable and not dependant on the box's * position. * * Adding 3px to the width/height will ensure we cover the maximum of * 1.75px padding on the bottom/right and still ensure we have > 0.75px * padding on the top/left. */ box->x1 = box->x2 - width - 3; box->y1 = box->y2 - height - 3; clutter_paint_volume_free (&projected_pv); }