-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix overlapping polygon rendering #55
Comments
http://commaexcess.com/articles/7/concave-polygon-triangulation-shortcut mentions that this technique "Can be extended to include nonzero rendering by utilizing backface culling." |
We can't just use non-zero drawing because there are buildings that have holes. Instead, we need to first draw all outer polygon rings, then subtract all inner polygon rings. |
With this code, we can draw both overlapping polygons and holes in polygons: gl.disable(gl.BLEND);
gl.stencilMask(0xFF);
gl.enable(gl.STENCIL_TEST);
gl.colorMask(false, false, false, false);
gl.clear(gl.STENCIL_BUFFER_BIT);
// Draw old-style
// gl.stencilOp(gl.INVERT, gl.KEEP, gl.KEEP);
// gl.stencilFunc(gl.NEVER, 1, 0x1);
// draw(gl, 'TRIANGLE_FAN', shape, [0, 1, 1, 1]);
// Draw front facing triangles
gl.stencilOpSeparate(gl.FRONT, gl.INCR, gl.KEEP, gl.KEEP);
gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.KEEP);
gl.stencilFunc(gl.NEVER, 1, 0xFF);
draw(gl, 'TRIANGLE_FAN', shape, [0, 1, 1, 1]);
// Decrease back facing triangles
gl.stencilOpSeparate(gl.BACK, gl.DECR, gl.KEEP, gl.KEEP);
gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.KEEP);
draw(gl, 'TRIANGLE_FAN', shape, [0, 1, 1, 1])
// Draw filling rectangle
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
gl.colorMask(true, true, true, true);
gl.stencilFunc(gl.NOTEQUAL, 0x0, 0xff);
draw(gl, 'TRIANGLE_STRIP', fill, [0, 0, 1, 1]); All shapes with a CCW winding order are filled, while all shapes with a CW winding order are subtracted. Note that this comes at the cost of an additional draw call. We also need to make sure that the winding order is absolutely correct. Currently, we generate |
instead of using GL_INVERT, we increment/decrement the pixels so that we can detect nonzero areas. this means we can now handle overlapping polygons. optionally, you can switch back to even-odd filling if desired (needs to be exposed to the stylesheet). in the same turn, it switches the clipping from the depth to the stencil buffer so that we don't need to request a depth buffer at all. prior to rendering, it masks the 0x80 bit to indicate the current tile extent. it also switches to front-to-back compositing, meaning that things drawn later in a frame will appear *behind* what is already visible. this allows us to use the stencil buffer to mask areas that are fully opaque so that we can cull fragments in those areas early on. fixes #55 fixes #77 fixes #177
Overlapping polygons on the same layer are rendered with a winding fill right now (due to the stencil inverting). We can solve this by computing pairwise intersections of all overlapping polygons and then render those as well to invert the fill again.
The text was updated successfully, but these errors were encountered: