For each geometric primitive, there is usually a wire frame class which takes care of rendering geometry specific features.
The class hierarchy of the wire frame classes correspond to the class hierarchy of the actual geometric objects. All wire frame classes are derived from 'inc/real/wires/r3wire.h' base class, which corresponds to geometry base class inc/real/objects/r3prim.h'.
The base class can render any object which has well defined 1D, 2D or 3D parametric surface (it evaluates the surface of the geometry by using R3PRIMM_EVALUATE method).
Our sphere has well defined 2d surface, so we can let the super class to render it and our wire frame class is therefore very simple.
When a new geometric object is created, there is no wire frame object associated with it. The application may not even have a view window or any other real time rendering interface, in which case no real time rendering specific objects will ever be created.
However, if the application has a view window, wire frame objects get created when the real time rendering engine needs to render them for the first time. Rendering engine creates a wire frame object for a geometric object by calling:
wire = R3DoA(prim, R3PRIMM_WIREFOROBJECT, NULL);
When an geometric attribute of the actual geometric object (sphere.c) is changed, the geometric object must call R3PRIMM_UPDATEWIRE method. This generates R3WIREM_UPDATE method to the associated wire frame object invalidating the wire object.
When the real time renderer scans through the geometric objects to be rendered it first studies whether the object in question is dirty (invalidatd). If so, the R3WIREM_DOUPDATE method is called.
In this method wire frame objects should update (validate) its internal state to reflect the geometric object. It should prepare its internal data structures to be ready to render the geometric object as efficiently as possible.
Then the 'real time' rendering engine sends R3WIREM_RENDERGEOMETRY metod to the wire frame object. It may also call R3WIREM_RENDEREDITHANDLES if the object is in edit state. In these methods you should call various r3wfdc.h methods to render out the geometric object into the view window.
Note: geometric objects don't know anything about wire frame classes. Therefore, 'callbacks' must be used to implement the R3PRIMM_WIREFOROBJ method. For this you need to handle two class attributes for the geometric sphere:
static R3INT wire_class, wire_mth; static void *r3rm_setclassattr(R3CLASS *cl, R3CLASS *obj, R3TAG *tl) { R3TAG *tag, *tags = tl; void *undef_attr = NULL; while(tag = R3TagNext(&tl)) { switch(tag->ident) { case R3PRIMCA_WireForObjClass: wire_class = (R3INT )tag->value; break; case R3PRIMCA_WireForObjMth: wire_mth = (R3INT )tag->value; break; ...
and handle the R3PRIMM_WIREFOROBJECT method as follows:
case R3PRIMM_WIREFOROBJECT: return R3DoClassA3(wire_class, wire_mth, p1, p2, obj);
In other words, when the wire frame rendering engine asks you to create a wire frame object, you just call 'wire_class' with the 'wire_mth'. Thats everything geometric objects should know about wire frame objects.
To plug your geometric class in, just call:
R3SetClassAttrs(R3CLID_SDKSPHERE, R3PRIMCA_WireForObjClass, R3CLID_FOO, R3PRIMCA_WireForObjMth, MYCM_GETWIRE, R3TAG_END);
to tell the real time rendering system of Realsoft 3D how to create a wire frame rendering object for your geometric object.
The actual 'MYCM_GETWIRE' method should look as follows:
#define MY_WIREDENSITY 10 case MYCM_WIREFOROBJECT: { int density = (int)p1; int curves = (int)p2; return R3New(R3CLID_MYWIRE, R3WIREA_Object, msg, R3WIREA_DensityU, density*curves*MY_WIREDENSITY, R3WIREA_DensityV, density*curves*MY_WIREDENSITY/2, R3WIREA_IsopCurveU, density*2, R3WIREA_IsopCurveV, density, R3WIREA_ClosedU, TRUE, R3WIREA_ClosedV, FALSE, R3TAG_END); }
The above listed attributes define the density in which the wire frame base class represents the surface of your geometry.
Sometimes different rendering methods (OpenGL, GDI, XLib) may need completely different 'density' and other wire frame settings. Geometric objects can create so called 'wiremanager' object, which is capable to manage multiple wire frame objects per geometric object: one for each rendering system.
To support this feature:
#include <real/wires/r3wmanag.h> case MYCM_WIREFOROBJECT: return R3New(R3CLID_WIREOBJMANAGER, R3WMANAGA_WireClass, clid, R3WIREA_Object, msg, R3TAG_END);
where 'clid' is the class id of the actual wire frame class.