Point sprites are an exciting feature supported by OpenGL version 1.5 and later. Although OpenGL has always supported texture mapped points, prior to version 1.5 this meant a single texture coordinate applied to an entire point. Large textured points were simply large versions of a single filtered texel. With point sprites you can place a 2D textured image anywhere onscreen by drawing a single 3D point.
Probably the most common application of point sprites is for particle systems. A large number of particles moving onscreen can be represented as points to produce a number of visual effects. However, representing these points as small overlapped 2D images can produce dramatic streaming animated filaments. For example, Figure 9.14 shows a well-known screensaver on the Macintosh powered by just such a particle effect.
Figure 9.14 A particle effect in the flurry screen saver.
Before point sprites, achieving this type of effect was a matter of drawing a large number of textured quads onscreen. This could be accomplished either by performing a costly rotation to each individual quad to make sure that it faced the camera, or by drawing all particles in a 2D orthographic projection. Point sprites allow you to render a perfectly aligned textured 2D square by sending down a single 3D vertex. At one-quarter the bandwidth of sending down four vertices for a quad, and no client-side matrix monkey business to keep the 3D quad aligned with the camera, point sprites are a potent and efficient feature of OpenGL.
Point sprites are very easy to use. Simply bind to a 2D texture, enable GL_POINT_SPRITE, set the texture environment target GL_POINT_SPRITE's GL_COORD_REPLACE parameter to true, and send down 3D points:
glBindTexture(GL_TEXTURE_2D, objectID); glEnable(GL_POINT_SPRITE); glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); glBegin(GL_POINTS); . . . . . . glEnd();
Figure 9.15 shows the output of the sample program POINTSPRITES. This is an updated version of the SMOOTHER sample program from Chapter 6 that created the star field out of points. In POINTSPRITES, each point now contains a small star image, and the largest point contains a picture of the full moon.
Figure 9.15 A star field drawn with point sprites.
One serious limitation to the use of point sprites is that their size is limited by the range of aliased point sizes (this was discussed in Chapter 3, "Drawing in Space: Geometric Primitives and Buffers"). You can quickly determine this implementation-dependent range with the following two lines of code:
GLfloat fSizes; GLGetFloatfv(GL_ALIASED_POINT_SIZE_RANGE, fSizes);
Following this, the array fSizes will contain the minimum and maximum sizes supported for point sprites, and regular aliased points.
Point sprites obey all other 2D texturing rules. The texture environment can be set to GL_DECAL, GL_REPLACE, GL_MODULATE, and so on. They can also be mipmapped and multitextured. There are a number of ways, however, to get texture coordinates applied to the corners of the points. If GL_COORD_REPLACE is set to false, as shown here
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
then a single texture coordinate is specified with the vertex and applied to the entire point, resulting in one big texel! Setting this value to GL_TRUE, however, causes OpenGL to interpolate the texture coordinates across the face of the point. All of this assumes, of course, that your point size is greater than 1.0!
A number of features of point sprites (and points in general actually) can be fine-tuned with the function glPointParameter. Figure 9.16 shows the two possible locations of the origin (0,0) of the texture applied to a point sprite.
Figure 9.16 Two potential orientations of textures on a point sprite.
Setting the GL_POINT_SPRITE_COORD_ORIGIN parameter to GL_LOWER_LEFT places the origin of the texture coordinate system at the lower-left corner of the point:
The default orientation for point sprites is GL_UPPER_LEFT.
Other non-texture-related point parameters can also be used to set the minimum and maximum allowable size for points, and to cause point size to be attenuated with distance from the eye point. See the glPointParameter function entry in Appendix C, "API Reference," for details of these other parameters.