Make the vector clip tool mask based on winding number so that the masking matches VSFilter's clipping.

Originally committed to SVN as r4442.
This commit is contained in:
Thomas Goyne 2010-06-05 22:40:16 +00:00
parent ff34a08afd
commit 3fbdf5b7e5
2 changed files with 39 additions and 16 deletions

View file

@ -303,6 +303,7 @@ void Spline::GetPointList(std::vector<Vector2D> &points,std::vector<int> &pointC
if (isFirst) { if (isFirst) {
points.push_back(cur->p1); points.push_back(cur->p1);
pointCurve.push_back(curve); pointCurve.push_back(curve);
isFirst = false;
} }
// Line // Line

View file

@ -134,26 +134,48 @@ void VisualToolVectorClip::Draw() {
std::vector<int> pointCurve; std::vector<int> pointCurve;
spline.GetPointList(points,pointCurve); spline.GetPointList(points,pointCurve);
// Draw stencil mask // The following is nonzero winding-number PIP based on stencils
glEnable(GL_STENCIL_TEST);
glColorMask(0,0,0,0);
glStencilFunc(GL_NEVER,1,1);
glStencilOp(GL_INVERT,GL_INVERT,GL_INVERT);
for (size_t i=2;i<points.size();i++) {
glBegin(GL_TRIANGLES);
glVertex2f(points[0].x,points[0].y);
glVertex2f(points[i-1].x,points[i-1].y);
glVertex2f(points[i].x,points[i].y);
glEnd();
}
// Draw "outside clip" mask // Draw to stencil only
glEnable(GL_STENCIL_TEST);
glColorMask(0, 0, 0, 0);
// GL_INCR_WRAP was added in 1.4, so instead set the entire stencil to 128
// and wobble from there
glStencilFunc(GL_NEVER, 128, 0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
DrawRectangle(0,0,video.w,video.h);
// Increment the winding number for each forward facing triangle
glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glBegin(GL_TRIANGLE_FAN);
for (size_t i = 0; i < points.size(); i++) {
glVertex2f(points[i].x,points[i].y);
}
glEnd();
// Decrement the winding number for each backfacing triangle
glStencilOp(GL_DECR, GL_DECR, GL_DECR);
glCullFace(GL_FRONT);
glBegin(GL_TRIANGLE_FAN);
for (size_t i = 0; i < points.size(); i++) {
glVertex2f(points[i].x,points[i].y);
}
glEnd();
glDisable(GL_CULL_FACE);
// Draw the actual rectangle
glColorMask(1,1,1,1); glColorMask(1,1,1,1);
if (inverse) glStencilFunc(GL_EQUAL, 1, 1);
else glStencilFunc(GL_EQUAL, 0, 1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
SetLineColour(colour[3],0.0f); SetLineColour(colour[3],0.0f);
SetFillColour(wxColour(0,0,0),0.5f); SetFillColour(wxColour(0,0,0),0.5f);
// VSFilter draws when the winding number is nonzero, so we want to draw the
// mask when the winding number is zero (where 128 is zero due to the lack of
// wrapping combined with unsigned numbers)
glStencilFunc(inverse ? GL_NOTEQUAL : GL_EQUAL, 128, 0xFF);
DrawRectangle(0,0,video.w,video.h); DrawRectangle(0,0,video.w,video.h);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);