From abc64a2c671a4eeafa374ceb91482e058705f6fb Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Tue, 20 Apr 2010 14:58:57 +0100 Subject: [PATCH] cogl-clip-stack: Use orientation of the polygon to set clip planes Previously the clip stack code was trying to detect when the orientation of the on-screen rectangle had changed by checking if the order of the y-coordinates on the left edge was different from the order the x-coordinates on the top edge. This doesn't work for some rotations which was causing the clip planes to clip the wrong side of the line. This patch makes it detect the orientation by calculating the signed area which is a standard computer graphics algorithm. http://bugzilla.openedhand.com/show_bug.cgi?id=2079 --- clutter/cogl/cogl/cogl-clip-stack.c | 43 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/clutter/cogl/cogl/cogl-clip-stack.c b/clutter/cogl/cogl/cogl-clip-stack.c index 6322156..eb2f04a 100644 --- a/clutter/cogl/cogl/cogl-clip-stack.c +++ b/clutter/cogl/cogl/cogl-clip-stack.c @@ -243,6 +243,7 @@ set_clip_planes (float x_1, CoglMatrixStack *projection_stack = _cogl_framebuffer_get_projection_stack (framebuffer); CoglMatrix projection_matrix; + float signed_area; float vertex_tl[4] = { x_1, y_1, 0, 1.0 }; float vertex_tr[4] = { x_2, y_1, 0, 1.0 }; @@ -257,27 +258,31 @@ set_clip_planes (float x_1, project_vertex (&modelview_matrix, &projection_matrix, vertex_bl); project_vertex (&modelview_matrix, &projection_matrix, vertex_br); - /* If the order of the top and bottom lines is different from the - order of the left and right lines then the clip rect must have - been transformed so that the back is visible. We therefore need - to swap one pair of vertices otherwise all of the planes will be - the wrong way around */ - if ((vertex_tl[0] < vertex_tr[0] ? 1 : 0) - != (vertex_bl[1] < vertex_tl[1] ? 1 : 0)) + /* Calculate the signed area of the polygon formed by the four + vertices so that we can know its orientation */ + signed_area = (vertex_tl[0] * (vertex_tr[1] - vertex_bl[1]) + + vertex_tr[0] * (vertex_br[1] - vertex_tl[1]) + + vertex_br[0] * (vertex_bl[1] - vertex_tr[1]) + + vertex_bl[0] * (vertex_tl[1] - vertex_br[1])); + + /* Set the clip planes to form lines between all of the vertices + using the same orientation as we calculated */ + if (signed_area > 0.0f) { - float temp[4]; - memcpy (temp, vertex_tl, sizeof (temp)); - memcpy (vertex_tl, vertex_tr, sizeof (temp)); - memcpy (vertex_tr, temp, sizeof (temp)); - memcpy (temp, vertex_bl, sizeof (temp)); - memcpy (vertex_bl, vertex_br, sizeof (temp)); - memcpy (vertex_br, temp, sizeof (temp)); + /* counter-clockwise */ + set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_bl); + set_clip_plane (GL_CLIP_PLANE1, vertex_bl, vertex_br); + set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_tr); + set_clip_plane (GL_CLIP_PLANE3, vertex_tr, vertex_tl); + } + else + { + /* clockwise */ + set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_tr); + set_clip_plane (GL_CLIP_PLANE1, vertex_tr, vertex_br); + set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_bl); + set_clip_plane (GL_CLIP_PLANE3, vertex_bl, vertex_tl); } - - set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_tr); - set_clip_plane (GL_CLIP_PLANE1, vertex_tr, vertex_br); - set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_bl); - set_clip_plane (GL_CLIP_PLANE3, vertex_bl, vertex_tl); } void -- 2.7.4