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
This commit is contained in:
parent
17a1595cb0
commit
9d93e250d1
@ -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))
|
||||
{
|
||||
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));
|
||||
}
|
||||
/* 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_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 the clip planes to form lines between all of the vertices
|
||||
using the same orientation as we calculated */
|
||||
if (signed_area > 0.0f)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user