Polygon objects represent one or more filled polygons that share a given set of vertices and rendering attributes. All polygons must be simple (the edges of the polygon should not intersect) and convex (the shape of the polygon should not have any indentations). Concave polygons can be converted into convex polygons using the helper object IDLgrTessellator. See Tessellator Objects for more on tessellator objects.
To create a polygon object, provide a two- or three-dimensional array (or two or three vectors) containing the locations of the polygon's vertices to the IDLgrPolygon::Init method. For example, the following statement creates a square with sides one unit in length, with the lower left corner at the origin:
mypolygon = OBJ_NEW('IDLgrPolygon', [[0,0], [0,1], [1,1], [1,0]])
See IDLgrPolygon for details on creating polygon objects.
Polygon objects have numerous properties controlling how they are rendered. You can set these properties when creating the polygon object, or use the SetProperty method to the polygon object to change these properties after creation.
Set the STYLE property to an integer value that controls how the polygon is rendered. Set the STYLE property equal to 0 (zero) to render only the vertices. The following statement changes the polygon to display only the vertex points, in blue:
mypolygon->SetProperty, STYLE=0, COLOR=[0,0,255]
Set the STYLE property equal to 1 (one) to render the vertices and lines connecting them. The following statement draws the polygon's outline in green:
mypolygon->SetProperty, STYLE=1, COLOR=[0,255,0,]
The default setting for the STYLE property is 2, which produces a filled polygon. The following statement draws the filled polygon in red:
mypolygon->SetProperty, STYLE=2, COLOR=[255,0,0]
You can supply a vector of vertex colors via the VERT_COLORS property. The colors in the vector will be applied to each vertex in turn. If there are more vertices than colors supplied for the VERT_COLORS property, IDL will cycle through the colors. For example, the following statements color each vertex and connecting line one of four colors:
vcolors =[[0,100,200],[200,150,200],[150,200,250],[250,0,100]] mypolygon->SetProperty, STYLE=1, VERT_COLORS=vcolors
As demonstrated in Pattern Objects, you can fill a polygon with a pattern contained in an IDLgrPattern object. Set the FILL_PATTERN property equal to the object reference of the pattern object. If you have created a pattern object called mypattern, the following statement uses that pattern as the polygon's fill pattern:
mypolygon->SetProperty, STYLE=2, FILL_PATTERN=mypattern
IDL provides two types of shading for filled objects. In Flat shading, the color of the first vertex in each polygon is used to define the color for the entire polygon. The polygon color has a constant intensity. In Gouraud shading, the colors along each line are interpolated between vertex colors, and then along scanlines from each of the edge intensities.
Set the SHADING property of the polygon object equal to 0 (zero) to use flat shading (this is the default), or equal to 1 (one) to use Gouraud shading. In the above example using vertex colors, adding the following statement:
mypolygon->SetProperty, STYLE=2, SHADING=1
creates a polygon fill in which the color values are interpolated between the vertex colors.
You can map an image onto a polygon object by specifying an IDLgrImage object to the TEXTURE_MAP property. The TEXTURE_COORD property defines how individual data points within the image data are mapped to the polygon's vertices. Note that you must specify both TEXTURE_MAP and TEXTURE_COORD to enable texture mapping.
IDLgrPolygon objects consist of a set of vertices and, optionally-via the POLYGON keyword-a connectivity array describing how those vertices are to be connected to form one or more polygons. Internally, IDL can identify three special types of polygonal meshes that may be represented very efficiently and therefore displayed substantially faster than individually described polygons. These special mesh types are characterized by repetitive patterns in the connectivity of the vertices. In performance terms, it is to the users advantage to utilize this optimization whenever possible by appropriately preparing the connectivity list according to the rules described for the corresponding type of mesh. The special mesh types are as follows:
A quad strip is a connected set of four-sided polygons. To take advantage of accelerated quad strips, the connectivity should be set up so that the first and last vertex for one quad are the same as the second and third of the previous quad. See the figure below.
For example, to use a quad strip optimization for the polygons shown above, the connectivity for the vertices should be as follows:
verts = [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 ,v11] oPoly = OBJ_NEW(IDLgrPolygon, verts, $ POLYGON=[4, 0, 1, 5, 4, $ 4, 1, 2 ,6, 5, $ 4, 2, 3, 7, 6, $ 4, 4, 5, 9, 8, $ 4, 5, 6, 10, 9, $ 4, 6, 7, 11, 10])
An alternate connectivity list that still uses quad strip optimization can also be used as in the following example, which orients each quad in the opposite direction of the first example.
oPoly = OBJ_NEW('IDLgrPolygon', verts, $
POLYGON=[4, 4, 5, 1, 0, $
4, 5, 6, 2, 1, $
4, 6, 7, 3, 2, $
4, 8, 9, 5, 4, $
4, 9, 10, 6, 5,$
4, 10, 11, 7, 6])
A triangle fan is a set of connected triangles that all share a common vertex. To take advantage of accelerated triangle fans, the connectivity should be set up so that the first vertex in every triangle is the common vertex, and the second vertex is the same as the last vertex of the previous triangle, as shown below.
For example, to use a triangle fan optimization for the polygons shown in the left side of the figure, the connectivity for the vertices should be as follows:
verts = [v0, v1, v2, v3, v4, v5] oPoly = OBJ_NEW(IDLgrPolygon, verts, $ POLYGON=[3, 0, 1, 2, $ 3, 0, 2, 3, $ 3, 0, 3, 4, $ 3, 0, 4, 5])
A triangle strip is a set of connected triangles, each of which share two vertices with the previous triangle. To take advantage of accelerated triangle strips, the connectivity should be set up so that the first two vertices in every triangle must have been in the previous triangle and ordered in the same direction (counter-clockwise or clockwise) and the final vertex must be new, as shown in the right side of the previous figure.
For example, to use the triangle strip optimization for the polygons shown in the right-hand figure, the connectivity for the vertices should be as follows:
verts = [v0, v1, v2, v3, v4, v5] oPoly = OBJ_NEW(IDLgrPolygon, verts, $ POLYGON=[3, 0, 1, 2, $ 3, 2, 1, 3, $ 3, 2, 3, 4, $ 3, 4, 3, 5])
No limits are imposed on the number of meshes or types of meshes within any given polygon object. A single POLYGON keyword value might contain any combination of quad strips, triangle strips, triangle fans, or non-specialized polygons.
As the length of the strips or fans grows, and as the percentage of vertex connections that are optimized by the rules described above increases, the performance upgrade becomes more perceptible. The optimizations are a result of minimizing the time required to perform vertex transforms. If the drawing of the polygons are otherwise limited by fill-rate (as might occur on some systems if texture-mapping is being applied, for instance), these optimizations may not be of significant benefit. In any case, performance will not be hindered in any way by utilizing these specialized meshes, so it is suggested that they be applied whenever possible.
| Note |
For IDLgrPolygon objects, normal vectors are computed by default at each vertex by averaging the normals of the polygons that share that vertex. These normals are then used to compute illumination intensities across the surface of the polygon. Computing default normals is a computationally expensive operation. Each time the polygon is drawn, this computation will be repeated if the polygon has changed significantly enough to warrant a new internal cache (for example, if the connectivity, vertices, shading, or style have changed). In some cases, the normals do not actually change as other modifications are made. In these cases, the expense of default normal computation can be bypassed if the user provides the normals explicitly (via the NORMALS keyword). The provided normals will be reused every time the polygon is drawn (without further computation) until they are replaced explicitly by the user. See COMPUTE_MESH_NORMALSfor more information.