Programming with View3D requires an application to first create a View3D widget, and then create a number of 3D objects and materials. After the objects have been created, they must be added to the display list of a View3D viewer. Each 3D object must have a material object assigned when attached to a viewer. The following diagram illustrates a simple example where one viewer is used to display two objects, each having a different material.

Figure 1: Simple attachment of objects and materials to a viewer
A material can be shared by multiple objects. Also, a 3D object can be added to multiple viewers, using a different material on each viewer if desired. The following diagram illustrates a more complex case, where two objects are attached to two different viewers, the second object being displayed with a different material in the second view.

Figure 2: Complex attachment of objects and materials to multiple viewers
Function XintView3DSetMaterial is used to assign a material to an object. Function XintView3DAddObject is used to add an object to a viewer. Function XintView3DAddObjectAndMaterial combines the operations of the above functions in one call. Function XintView3DRemoveObject can be used to remove an object from the display list of a viewer, temporarily or permanently.
Each object (3D objects and material objects) keeps a link count to prevent the object from being destroyed when still in use inside a viewer. The reference count of a 3D object is set to 0 at creation time. Each time an object is added to a viewer, its reference count is incremented by 1. Conversely, it is decremented by 1 when the object is removed from a viewer. An object is destroyed when its reference count drops back to 0. Functions XintView3DRefObject and XintView3DUnRefObject can be used to increase or decrease the reference count of an object respectively. The reference count of a material object is increased by 1 when assigned to a 3D object, it is decreased by 1 when the object is destroyed or when a new material is assigned to the object.
Because View3D is based on OpenGL, it may require a special visual to create its window, which can be different from the visual used by the application. View3D usually creates this special visual (one that is compatible with OpenGL) at creation time, along with a matching colormap. This operation is transparent for the application.
When linking with a native OpenGL library, the selected visual will, in most cases, be a TrueColor visual.
When linking with the Mesa 3-D library, the selected visual will, in most cases, be a PseudoColor visual. In the case of an 8-bit PseudoColor visual, the Mesa library tries to allocate a color cube containing 225 colors. If this allocation fails for some colors, the closest color available in the colormap will be used. In the case of a 24-plane screen, an 8-bit visual is selected if available. It is possible to override the visual selection process using environment variable MESA_RGB_VISUAL. For example, the following setting ( specified using the csh syntax) forces the Mesa library to select a 24-bit visual:
setenv MESA_RGB_VISUAL "TrueColor 24"
Possible specifications for the visual type include TrueColor, PseudoColor, StaticColor, GrayScale and DirectColor. What you specify must match a valid visual otherwise the directive will be ignored.
Applications requiring full control over the visual and colormap selection process can use View3D resource XmNvisual and Core resource XmNcolormap to impose a particular visual and colormap. Convenience functions XintGlChooseVisual and XintGlGetVisualInfo can be used to facilitate this process.
typedef float XintReal; /* default type */
For applications requiring more precision, a special version of the library can be provided where type XintReal is defined as:
typedef double XintReal; /* ONLY when USE_DOUBLE is set */
Note: It is not enough to set flag USE_DOUBLE when you compile your application. You must build or obtain a special version of the View3D library compiled with flag USE_DOUBLE set.
typedef float XintColor4[4];
This data type contains 4 values, all between 0.0 and 1.0, which represent the red, green, blue and transparency values respectively. A set of convenience functions described in Color Functions section is available for converting pixel values to XintColor4 values and vice versa.
The following code sample shows when to allocate and free the data required to create a line object.
XintVector3 *vertices;
...
/* Generate line points */
vertices = (XintVector3 *) XtMalloc(sizeof(XintVector3) * NV);
for (i=0; i<NV; i++) {
vertices[i][0] = sin((double) i/10.);
vertices[i][1] = cos((double) i/10.);
vertices[i][2] = cos((double) i/7.);
}
/* Create line object */
line = XintView3DCreateLine("line", XintOBJECT_LINE_POLYLINE, 2.0,
NV, vertices, 0, NULL, True, NULL, NULL);
/* Free the line points */
XtFree((char *) vertices);
...

num_verts = 10; /* Number of vertices */
num_lists = 3; /* Number of polygons */
num_indices[0] = 5; /* Num indices in poly 0 */
num_indices[1] = 4; /* Num indices in poly 1 */
num_indices[2] = 6; /* Num indices in poly 2 */
indices[0][0] = 0; /* Poly 0 Index 0 -> Vert 0 */
indices[0][1] = 1; /* Poly 0 Index 1 -> Vert 1 */
indices[0][2] = 2; /* Poly 0 Index 2 -> Vert 2 */
indices[0][3] = 8; /* Poly 0 Index 3 -> Vert 8 */
indices[0][4] = 7; /* Poly 0 Index 4 -> Vert 7 */
indices[1][0] = 6; /* Poly 1 Index 0 -> Vert 6 */
indices[1][1] = 7; /* Poly 1 Index 1 -> Vert 7 */
indices[1][2] = 8; /* Poly 1 Index 2 -> Vert 8 */
indices[1][3] = 5; /* Poly 1 Index 3 -> Vert 5 */
indices[2][0] = 8; /* Poly 2 Index 0 -> Vert 8 */
indices[2][1] = 2; /* Poly 2 Index 1 -> Vert 2 */
indices[2][2] = 3; /* Poly 2 Index 2 -> Vert 3 */
indices[2][3] = 4; /* Poly 2 Index 3 -> Vert 4 */
indices[2][4] = 9; /* Poly 2 Index 4 -> Vert 9 */
indices[2][5] = 5; /* Poly 2 Index 5 -> Vert 5 */

num_verts = 5; /* Number of vertices */
num_lists = 1; /* Only 1 list */
num_indices[0] = 5; /* Num indices in poly 0 */
indices[0][0] = 0; /* Tri 0 Index 0 -> Vert 0 */
indices[0][1] = 1; /* Tri 0 Index 1 -> Vert 1 */
indices[0][2] = 4; /* Tri 0 Index 2 -> Vert 4 */
indices[0][3] = 1; /* Tri 0 Index 0 -> Vert 1 */
indices[0][4] = 3; /* Tri 0 Index 1 -> Vert 3 */
indices[0][5] = 4; /* Tri 0 Index 2 -> Vert 4 */
indices[0][6] = 2; /* Tri 0 Index 0 -> Vert 2 */
indices[0][7] = 3; /* Tri 0 Index 1 -> Vert 3 */
indices[0][8] = 1; /* Tri 0 Index 2 -> Vert 1 */
Only use 1 list. Every 3 indices is 1 triangle.
This method works for most of the data types that
use more than one list of indices.