/// <summary> /// Add tolerance around the ViewportBounds if the ClipToBounds property is set. /// </summary> private void AddClippingTolerance() { if (bounds.ClipToViewport && RenderTolerance.ViewportClippingTolerance > 0) { SilhouetteEdgeTriangle[] edgeTriangles = new SilhouetteEdgeTriangle[8]; double tolerance = RenderTolerance.ViewportClippingTolerance; double left = bounds.ViewportBounds.Left; double right = bounds.ViewportBounds.Right; double top = bounds.ViewportBounds.Top; double bottom = bounds.ViewportBounds.Bottom; Point3D topLeft = new Point3D(left, top, 0); Point3D topRight = new Point3D(right, top, 0); Point3D bottomLeft = new Point3D(left, bottom, 0); Point3D bottomRight = new Point3D(right, bottom, 0); edgeTriangles[0] = new SilhouetteEdgeTriangle(topLeft, topRight, tolerance); edgeTriangles[1] = new SilhouetteEdgeTriangle(topRight, topLeft, tolerance); edgeTriangles[2] = new SilhouetteEdgeTriangle(topRight, bottomRight, tolerance); edgeTriangles[3] = new SilhouetteEdgeTriangle(bottomRight, topRight, tolerance); edgeTriangles[4] = new SilhouetteEdgeTriangle(bottomRight, bottomLeft, tolerance); edgeTriangles[5] = new SilhouetteEdgeTriangle(bottomLeft, bottomRight, tolerance); edgeTriangles[6] = new SilhouetteEdgeTriangle(bottomLeft, topLeft, tolerance); edgeTriangles[7] = new SilhouetteEdgeTriangle(topLeft, bottomLeft, tolerance); RenderToToleranceShader ignoreClipBounds = new RenderToToleranceShader(edgeTriangles, buffer); // Rasterize to WindowBounds because RenderBounds (==ViewportBounds in this case) // will clip the outside of the silhouette edge triangles. ignoreClipBounds.Rasterize(new Rect(bounds.WindowSize)); } }
private void RenderSilhouetteTolerance(ProjectedGeometry geometry, RenderBuffer rasterization, VisibleFaces faces) { List <Edge> silhouetteEdges = null; // Choose list based on triangle winding/facing switch (faces) { case VisibleFaces.Front: silhouetteEdges = geometry.FrontFaceSilhouetteEdges; break; case VisibleFaces.Back: silhouetteEdges = geometry.BackFaceSilhouetteEdges; break; default: throw new NotSupportedException("Cannot render these type of faces: " + faces); } // Outline edge detection if (RenderTolerance.SilhouetteEdgeTolerance > 0) { // Create a set of triangles that will draw lines on the tolerance buffer SilhouetteEdgeTriangle[] edgeTriangles = new SilhouetteEdgeTriangle[2 * silhouetteEdges.Count]; int count = 0; //double the silhouette pixel tolerance in nonstandard DPI scenario. //This compensates for differences in anti-aliasing sampling patterns in high and low DPI double tolerance = RenderTolerance.SilhouetteEdgeTolerance; if (!RenderTolerance.IsSquare96Dpi) { tolerance *= 4; } foreach (Edge edge in silhouetteEdges) { // FWD triangle edgeTriangles[count++] = new SilhouetteEdgeTriangle(edge.Start, edge.End, tolerance); // BWD triangle edgeTriangles[count++] = new SilhouetteEdgeTriangle(edge.End, edge.Start, tolerance); } // Render our ignore geometry onto the tolerance buffer. RenderToToleranceShader edgeIgnore = new RenderToToleranceShader(edgeTriangles, rasterization); edgeIgnore.Rasterize(bounds.RenderBounds); } }