clutter/stage: Use graphene_frustum_t for clipping

Instead of 4 planes, use a graphene_frustum_t to store the clipping
planes.

The cautious reviewer might noticed that we are now setting up 6
planes: the 4 planes we were doing before, plus 2 extra planes in
the Z axis. These extra planes simulate an "infinite" Z far, and
an "on-camera" Z near.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
This commit is contained in:
Georges Basile Stavracas Neto 2020-10-09 19:08:47 -03:00
parent 338a9275b4
commit a84dccfd64
5 changed files with 39 additions and 40 deletions

View File

@ -3444,7 +3444,7 @@ cull_actor (ClutterActor *self,
{
ClutterActorPrivate *priv = self->priv;
ClutterStage *stage;
const graphene_plane_t *stage_clip;
const graphene_frustum_t *clip_frustum;
if (!priv->last_paint_volume_valid)
{
@ -3466,10 +3466,10 @@ cull_actor (ClutterActor *self,
}
stage = (ClutterStage *) _clutter_actor_get_stage_internal (self);
stage_clip = _clutter_stage_get_clip (stage);
clip_frustum = _clutter_stage_get_clip (stage);
*result_out =
_clutter_paint_volume_cull (&priv->last_paint_volume, stage_clip);
_clutter_paint_volume_cull (&priv->last_paint_volume, clip_frustum);
if (*result_out != CLUTTER_CULL_RESULT_OUT)
{

View File

@ -123,8 +123,8 @@ void _clutter_paint_volume_axis_align (ClutterPaintVolu
void _clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv,
ClutterActor *actor);
ClutterCullResult _clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_plane_t *planes);
ClutterCullResult _clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_frustum_t *frustum);
void _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
ClutterStage *stage,

View File

@ -1071,14 +1071,11 @@ _clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv,
}
ClutterCullResult
_clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_plane_t *planes)
_clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_frustum_t *frustum)
{
int vertex_count;
graphene_point3d_t *vertices = pv->vertices;
gboolean partial = FALSE;
int i;
int j;
graphene_box_t box;
if (pv->is_empty)
return CLUTTER_CULL_RESULT_OUT;
@ -1095,26 +1092,12 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv,
else
vertex_count = 8;
for (i = 0; i < 4; i++)
{
const graphene_plane_t *plane = &planes[i];
int out = 0;
for (j = 0; j < vertex_count; j++)
{
if (graphene_plane_distance (plane, &vertices[j]) < 0)
out++;
}
graphene_box_init_from_points (&box, vertex_count, pv->vertices);
if (out == vertex_count)
return CLUTTER_CULL_RESULT_OUT;
else if (out != 0)
partial = TRUE;
}
if (partial)
return CLUTTER_CULL_RESULT_PARTIAL;
else
if (graphene_frustum_intersects_box (frustum, &box))
return CLUTTER_CULL_RESULT_IN;
else
return CLUTTER_CULL_RESULT_OUT;
}
void

View File

@ -98,7 +98,7 @@ ClutterActor *_clutter_stage_do_pick (ClutterStage *stage,
ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage);
void _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage);
const graphene_plane_t *_clutter_stage_get_clip (ClutterStage *stage);
const graphene_frustum_t *_clutter_stage_get_clip (ClutterStage *stage);
ClutterStageQueueRedrawEntry *_clutter_stage_queue_actor_redraw (ClutterStage *stage,
ClutterStageQueueRedrawEntry *entry,

View File

@ -115,7 +115,7 @@ struct _ClutterStagePrivate
GArray *paint_volume_stack;
graphene_plane_t current_clip_planes[4];
graphene_frustum_t clip_frustum;
GSList *pending_relayouts;
GList *pending_queue_redraws;
@ -659,13 +659,16 @@ typedef struct _Vector4
} Vector4;
static void
_cogl_util_get_eye_planes_for_screen_poly (float *polygon,
int n_vertices,
float *viewport,
const graphene_matrix_t *projection,
const graphene_matrix_t *inverse_project,
graphene_plane_t *planes)
_cogl_util_get_eye_planes_for_screen_poly (float *polygon,
int n_vertices,
float *viewport,
const graphene_matrix_t *projection,
const graphene_matrix_t *inverse_project,
const ClutterPerspective *perspective,
graphene_frustum_t *frustum)
{
graphene_plane_t planes[6];
graphene_vec4_t v;
float Wc;
Vector4 *tmp_poly;
int i;
@ -749,6 +752,18 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon,
graphene_plane_init_from_points (&planes[i], &p[0], &p[1], &p[2]);
}
graphene_plane_init_from_vec4 (&planes[4],
graphene_vec4_init (&v, 0.f, 0.f, -1.f,
perspective->z_near));
graphene_plane_init_from_vec4 (&planes[5],
graphene_vec4_init (&v, 0.f, 0.f, 1.f,
perspective->z_far));
graphene_frustum_init (frustum,
&planes[0], &planes[1],
&planes[2], &planes[3],
&planes[4], &planes[5]);
}
/* XXX: Instead of having a toplevel 2D clip region, it might be
@ -809,7 +824,8 @@ setup_view_for_pick_or_paint (ClutterStage *stage,
viewport,
&priv->projection,
&priv->inverse_projection,
priv->current_clip_planes);
&priv->perspective,
&priv->clip_frustum);
_clutter_stage_paint_volume_stack_free_all (stage);
}
@ -3075,10 +3091,10 @@ _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage)
/* The is an out-of-band parameter available while painting that
* can be used to cull actors. */
const graphene_plane_t *
const graphene_frustum_t *
_clutter_stage_get_clip (ClutterStage *stage)
{
return stage->priv->current_clip_planes;
return &stage->priv->clip_frustum;
}
/* When an actor queues a redraw we add it to a list on the stage that