Last modified 30 July 2003 by jdavis@math.wisc.edu

SMKModelDrawer

Inherits from NSObject
Conforms to NSCoding, NSCopying, SMKDrawing, SMKManagedDrawing

SMKModelDrawer draws a customized SMKModel. It colors the model using an SMKTexture, which it tints with an RGBA color. Translucent colors and textures are handled automatically, with the help of SMKDrawingManager and SMKMatrix. To aid reusability, SMKModelDrawer can also draw the model reflected and scaled.

Because of these customizations, a single model can be used by many nodes simultaneously, so the model and texture are retained through an SMKResourceManager. SMKModelDrawer identifies these resources by numeric keys, which correspond to certain files in the application bundle, as described by SMKModel and SMKTexture.

- (id)setModelKey:(int)modelKey textureKey:(int)textureKey;

Sets the model and texture keys and returns the receiver.

- (int)modelKey;

Returns the model key.

- (int)textureKey;

Returns the texture key.

Just setting the model and texture keys does not cause these resources to be updated. To do that, invoke useResourceManager:. Then you can obtain the model and texture using these methods:

- (id)model;

Returns the model.

- (id)texture;

Returns the texture.

You can opt to have SMKModelDrawer draw the model reflected about its internal X-Z plane. This is useful when drawing objects with symmetry. For example, if a figure's left and right feet are symmetric, then they can be described by a single model.

- (id)setIsReflected:(BOOL)isReflected;

Sets the flag that causes the model to be drawn reflected. By default, reflection is disabled.

- (BOOL)isReflected;

Returns the current reflection setting.

SMKModelDrawer also lets you dynamically enlarge or shrink the model to suit your needs. Currently, nothing is done to renormalize the model's normal vectors, so the element's lighting may end up unpleasantly altered when the model is scaled. If you intend to use scaling, you might want to nullify this effect by enabling GL_NORMALIZE in OpenGL.

- (id)setScalar:(float)scalar;

Sets the scaling factor and returns the receiver. The scaling factor should never be 0; the default value is 1.

- (float)scalar;

Returns the scaling factor.

SMKModelDrawer stores a color with red, green, blue, and alpha components, each having a value between 0 and 1. The color is used to tint the texture, via the GL_MODULATE texturing function. For example, if the color is white, then the texture will be rendered faithfully, but if the color is blue, then the texture will be tinted blue. The alpha component of the color measures translucency; we deal with this topic in detail below. You can access the color as a vector or in individual components. The default color is transparent black, (0, 0, 0, 0).

- (id)setColor:(float *)color;

Sets the color to match the indicated (R, G, B, A) vector.

- (id)getColor:(float *)color;

Copies the color into the indicated (R, G, B, A) vector.

- (id)setColor:(unsigned int)index toValue:(float)value;

Sets the R, G, B, or A component of the color to the indicated value, when passed 0, 1, 2, or 3, respectively.

- (float)color:(unsigned int)index;

Returns the R, G, B, or A component of the color, when passed 0, 1, 2, or 3, respectively.

The drawing of translucent objects is more complicated than the drawing of opaque ones, because they must be drawn in order, from back to front, and after all opaque objects, to achieve the correct effect. In fact, this back-to-front algorithm works only if all translucent objects are convex and nonintersecting. If your models have a lot of concavity and you must have perfect overlapping translucency effects, then you need to break the models up into convex pieces.

Assuming that its model is convex, SMKModelDrawer handles translucent color automatically. However, it has no efficient means of determining whether its texture has translucent parts. If you wish to use a translucent texture with an opaque tinting color, then you should notify SMKModelDrawer using this method:

- (id)setIsTranslucent:(BOOL)isTranslucent;

Sets a flag that forces the drawer to use delayed, translucent drawing, even if its tinting color is opaque. By default, this flag is not set.

- (BOOL)isTranslucent;

Returns the current translucency setting.

Delayed drawing of translucent SMKModelDrawers is accomplished using an SMKDrawingManager; you must ensure that the intended one is current. During the delay, the model drawer stores its complete modelview transformation in an SMKMatrix, which is allocated when it is first needed (and thus never for drawers that are always opaque). The projection and viewport transformations are assumed to remain constant during the delay. When it finally draws, SMKModelDrawer automatically manipulates the modelview transformation, blending, and depth buffer writing mask to achieve the correct effect.