Within immediate mode callback functions, a clump can be considered to be a '3-D volume marker'. A clump occupies volume in world space. In retained mode, if any part of that space is within the view frustrum an attempt is made to render the polygonal geometry of the clump. Clump callbacks allow a clump's rendering to be `overloaded' by a user specified function.
A clump callback may be set by the function RwSetClumpImmediateCallBack(). The current callback can be queried with RwGetClumpImmediateCallBack(). Note that if the clump callback is set to NULL the clump is rendered in normal 'retained' mode. Thus, to terminate a clump callback invoke:
RwSetClumpImmediateCallBack(clump,
NULL).
The `win' with the clump callback is that rendering effort need only be undertaken if the geometry to be rendered is within the view volume. The clump itself simply fulfils the role of a space marker determining if the geometry is visible.
The callback is only called if any part of the volume, taken as the clumps bounding box, is within the view volume.
For example, a 'dummy' clump with no geometry can be created and set to perform a callback as follows:
void
ClumpCallBack(RwClump *clump)
{
...
Do some immediate mode rendering
...
}
{
RwClump *clump;
if (clump =
RwCreateClump(0,0))
{
RwV3d bll,fur;
bll.x =
CREAL(-1);
bll.y = CREAL(-1);
bll.z = CREAL(-1);
fur.x =
CREAL(2);
fur.y = CREAL(1);
fur.z = CREAL(0);
RwSetClumpLocalBBox(clump,&bll,&fur);
RwSetClumpImmediateCallBack(clump,ClumpCallBack);
}
else
{
Error
cannot create the clump
}
...
}
Whenever the clump 'clump' is subsequently rendered, if it is within the view volume then the function 'ClumpCallBack' is invoked. Note that the clump itself is not rendered -- in this case the clump is empty. Any visible artefacts are generated by the callback.
An immediate mode rendering context is automatically established within the callback, initialising the immediate mode structures to allow rendering.
There is no need for the user to invoke RwImmediateBegin() and RwImmediateEnd()within the callback -- indeed, these functions should NEVER be called within an immediate mode callback.
A clump with geometry may also be assigned an immediate mode callback. This allows the user to get a 'look in' just before the clump is rendered. The clump can still be rendered via the RwRenderImmediateClump()function. Other properties of the clump could also be altered dynamically at this point. For example if lighting is disabled on the clump with
RwSetClumpLightSampleRate(clump,
CREAL(0))
then the user can set custom lighting characteristics.
Note immediate mode callbacks cannot recurse - there must be no call to RwRenderClump() or RwRenderScene() from within an immediate mode callback. These functions are not re-entrant.
Any 3-D vertex specified within a clump callback is projected through the clumps 'LTM' into world space before being projected into camera space. All vertices should therefore be specified in the LOCAL co-ordinate space of the clump. When an immediate mode rendering context is established between calls to RwImmediateBegin() and RwImmediateEnd() however, 3-D vertices are specified in the world co-ordinate space.
The Importance Of Bounding Boxes
The internals of RenderWare make extensive use of Bounding boxes for optimisation. It is essential that if a local bounding box is explicitly set then that volume should contain all the space where objects are to be rendered. If a bounding box is set which fails to fulfil this obligation, the result of rendering is undefined - and could easily lead to a crash. It is critical that only valid bounding boxes are set.
If RwRenderImmediateClump() is to be called then the bounding box hold all of the points which are referenced by polygons within the clump. Similarly if an immediate mode triangle is to be rendered via object space co-ordinates, the vertices specified must lie within the bounding box. If co-ordinates are specified in 2-D, then they must lie within the clump's camera viewport rectangle.
Materials in Immediate Mode
In immediate mode, materials define the appearance of a triangle or line, in terms of color, texture and other characteristics. When displaying a polygon as flat shaded, lit and non-textured polygons, the color rendered depends not only on the color of that polygon's material, but also on the luminance of the polygon. If the luminance is set to the maximum value then the polygon will appear white, whatever the color of its material. In 'true color' modes, the color not only depends on the material color but also the red, green and blue components of luminance arising from lighting on the polygon.
The material's color is attenuated by the luminance values. Luminance values are treated differently in 'indexed' (i.e. 8 bit) and 'true color' (i.e. 16 bit) rendering modes.
In indexed modes, there is single luminance channel which determines the 'brightness' of a polygon. From 0 to 0.75 the rendering color increases from black to the brightest form of the material's color. From 0.75 to 1.0 the color is desaturated to white.
In true color modes the luminance is controlled by three luminance channels - red, green and blue. They have a similar role to the 'indexed' rendering brightness channel, with the red entry affecting the red component of the materials color and so son for green and blue. If the color of a polygon's material is pure red and but the polygon's luminance for red is zero, that polygon will be rendered as black, whatever the green or blue luminance components are. Similarly, if the color of a polygon's materials white, then the polygon is rendered in exactly the color defined by the red, green and blue components of luminance. For example, setting red and green to the maximum luminance and blue to zero will cause a polygon whose material color is white to be rendered as yellow.
If a polygon is to be textured in an immediate mode rendering, the texture must first be applied to a material and that material set as the immediate mode material. The material also encapsulated the type of texturing to be performed, and other state such as the geometry and light sampling modes.
The following functions allow material properties to be set during immediate mode rendering:
The base color of the polygon is specified with either of:
RwSetMaterialColor()
RwSetMaterialColorStruct()
The base color of the polygon - rendered if the material does not have an applied texture -- which will be attenuated by the polygon's lighting luminance values.
The density in which geometry of the immediate mode primitive will be drawn is specified with:
RwSetMaterialGeometrySampling()
A triangle can be drawn as a solid filled triangle, 3 edge lines or 3 vertex points. These are selected by setting the geometry sampling mode to rwSOLID, rwWIREFRAME, or rwPOINTCLOUD respectively. A line can be drawn as an edge line or 2 vertex points, in a similar fashion.
The frequency of light value sampling and hence luminance calculation over a polygon is specified with:
RwSetMaterialLightSampling()
If the light sampling is rwVERTEX, the luminance values at the vertices will be interpolated across the polygon face, thus producing a 'smooth' or 'Gouraud' shaded polygon. If the light sampling is rwFACET then the luminance value of the polygon's center will be applied across its surface, thus rendering 'flat' shading. Note that for a line with rwVERTEX light sampling, although the vertex luminance values will determine lines rendering color, the values will not be interpolated. Thus it is not possible to produce a 'smooth shaded' line.
The opacity of an immediate mode triangle primitive is specified with:
RwSetMaterialOpacity()
Changing the opacity will have no effect on lines.
The texture map to be applied to an immediate mode triangle primitive is specified with:
RwSetMaterialTexture()
If a NULL texture is passed this suppresses texturing of the polygons with this material. Setting the material texture to a valid texture will cause texture mapped polygons to be rendered with the specified texture. Texture U and V co-ordinates must be set at the vertices of any texture mapped polygon.
The nature of texture mapping applied to an immediate mode triangle is specified with:
RwSetMaterialTextureModes()
The texture modes are specified as a combination of the bit-flags rwLIT, rwFORESHORTEN and rwFILTER.
Since RenderWare performs no lighting when drawing immediate mode primitives, the following material characteristics will have no effect when rendering immediate mode polygons or line primitives:
RwSetMaterialAmbient()
RwSetMaterialDiffuse()
RwSetMaterialSpecular()
RwSetMaterialSurface()
Z-Buffering In An Immediate Mode Callback
Z-Buffering can only be performed in an immediate mode call back on an appropriately initialised clump. This initialisation can be ensured by setting the hints on the clump to rwHS and rwEDITABLE. RenderWare will sometimes switch on Z-Buffering automatically when objects are found to intersect when during a call to RwRenderScene(). Thus even a clump which has a hint of NULL -- meaning don't Z-Buffer in this context -- can sometimes be Z-Buffered. When drawn by a direct call to RwRenderClump() however, a clump with the NULL hint is never Z-buffered. To render a Z-Buffered clump, not only must that clump have Z-Buffering enabled -- either through the hints or the fact that something is intersecting the clump -- but also that the immediate rendering primitive must have Z-Buffering enabled with the macro:
RWSETIMMEDIATEZBUFFERON(imm)
where `imm' is the immediate primitive structure.
If this latter call is not made, setting the primitive hints for Z-buffering will have no effect -- the primitive will not be Z-Buffered. Both obligations must be fulfilled if a primitive is to be correctly rendered.
Note that the Z-Buffer will be initialised for correct rendering within immediate mode callback, provided that all points to be rendered are any of:
· vertices indexed by number in the clump and within the bounding box.
· 3-D object space vertices in within the bounding box
· 2-D pixel space vertices within the clumps viewport
If any point meets none of these criteria then the result is undefined.
Key Points For Rendering In Immediate Mode Callbacks