The file world.html shows how to an application can use the build-in vrml parser to parse and render a world. However, building up your own world manually (instead of calling the build-in parser) is a little bit more involved.

However, it's pretty easy once you know how it works. I'm therefore demonstrating it in a few, well-documented examples.

Example 1 : creating a simple scenegraph consisting of 2 gray triangles

/*
   include all necessary include files
*/
/* header file declaring the toy::importer class as a sub-class of
 * xrml::importer. */
#include "importer.H"

#include "xrml.H"
#include "IndexedFaceSet.H"
#include "Group.H"
#include "Material.H"
#include "Appearance.H"
#include "Transform.H"
#include "Shape.H"
#include "world.H"

using namespace xrml;  // so we can omit the xrml:: name space prefix

// this routine gets called from 
// xrml::world::parse(filename, start_time, toy_importer) 
// if toy_importer points to an object of the class toy::importer 
// being implemented here.
bool toy::importer::parse(class world* world, char **strpool)
{
  // builds up an example scenegraph for the specified world
  // this example only creates 2 gray triangles, but already shows 
  // most of the important things....

  // The world object being passed has a sceneGraph MFNode array
  // (declared in xrml.H and derived from xrml::array in Array.H).
  MFNode *sg = world->sceneGraph;

  // If you care, you can set the global variables indicating the
  // file name and line number at which a node is parser. This
  // information can be used for error reporting later on.
  xrml::current_filename = "blabla";
  xrml::current_linenr = 1;
  // Of course, this is not very meaningful for this example.
  
  /*
    generally, for having 2 gray triangles, we basically
    need an indexedfaceset to specify the geometry for the triangles,
    and some gray material for them.
    in order to apply the material to the triangles, we have to pool them 
    in a shape node. 
  */
  
  /*
    generate the material that is to be used in the appearance node 
    values are always assigned to fields of a vrml-node by calling
    node->assign_ with the appropriate values
  */
  Material *material = new Material; // create a new material
  SFColor gray(.6,.6,.6); // get a color to assign
  material->assign_ambientIntensity(SFFloat(.6));
  material->assign_diffuseColor(gray); // set the diffuse color to gray
  material->assign_emissiveColor(gray);// set the emissive color to gray

  /*
    now, put this material in an appearance node
    materials can only be applied to geometry through appearance nodes...
  */
  Appearance *appearance = new Appearance; // create a new appearance node
  appearance->assign_material(material);   // ... and assign our gray material

  /*
    after having generated the appearance, we're generating the geometry.
    first, we specify the vertices of our triangles.
  */
  float vert_xyz[12] = { 0., 0., 0.,  0., 1., 0.,  1., 0., 0.,  1., 1., 1. };
  MFVec3f coords(4, (SFVec3f*)vert_xyz);

  /*
    create a coordinate node that can hold the vertex positions
    the coords can not be assigned directly, but only through a coordinate
    class. the same applies for normals, texturecoords aso...
  */
  Coordinate *coord = new Coordinate;
  coord->assign_point(coords); // assign our array or vertex positions

  /*
    after having the vertex positions, we have to generate the index-array for the
    faces in basically the same way. specify a MFInt32 field and assign the indices 
  */
  SFInt32 indices[8] = { 0, 1, 2, -1, 1, 2, 3, -1 };
  MFInt32 index(8, indices);

  /*
     There are various ways of constructing MFxxx (array) objects. See
     the Array.H include file and the TOOLS/testarrayassign.C code
     fragment.
  */

  /* 
     after having both the index array and the coordinate node,
     we can put them together in a new indexedfaceset
  */
  IndexedFaceSet *ifs = new IndexedFaceSet; // create a new indexedfaceset
  ifs->assign_coord(coord);                 // assing our coordinates
  ifs->assign_coordIndex(index);            // assign the index-array

  /* 
     now that we have both the appearance and the geometry (the indexedfaceset,
     which is a subclass of geometry), we can put them together with a shape-node.
     basically a shape node is the only way how to bring geometry and materials together...
  */
  Shape *shape = new Shape;             // generate a new shape
  shape->assign_appearance(appearance); // take our previously defined appearance
  shape->assign_geometry(ifs);          // assign our indexedfaceset-geometry

  /* 
     we're almost done : just add the newly created shape (our two-triangle-indexfaceset 
     with a gray-material-appearance) to the scenegraph...
  */
  sg->append(shape);

  return true;
}
This file is maintained by Ingo Wald (i.w.) wald@graphics.cs.uni-sb.de
Last update: February 21, 2001