Differences with the OpenSceneGraph C++ API

The notable differences between the osgDotNet interfaces and the OpenSceneGraph C++ API, in roughly decreasing order of significance, are:

  • Extra action must be taken to ensure the Win32 viewer is destroyed in the same thread in which it is created (this is a Win32 restriction). This can be done either by invoking Dispose on the object, or via a using statement in C#.
    using (OsgViewer.Viewer viewer = new OsgViewer.Viewer())
    {
        /* ... */
    
        viewer.setSceneData(/* ... */);
        viewer.run();
    }
    
  • Some OpenSceneGraph types that have value semantics in C++ have reference semantics in C#. The general rule is that osg::Vec types have value semantics; all other types have reference semantics. Also note that both reference and value types are created with the new keyword in C#.
    // C++
    osg::Quat q1(1.0f, 0.0f, 0.0f, 0.0f), q2;
    q2 = q1; // copy q1 to q2
    q2.set(0.0f, 1.0f, 0.0f, 0.0f);
    // now q1 = (1.0f, 0.0f, 0.0f, 0.0f), q2 = (0.0f, 1.0f, 0.0f, 0.0f)
    
    osg::Vec3 v(1.0f, 2.0f, 3.0f);
    
    // C#
    Osg.Quat q1 = new Osg.Quat(1.0f, 0.0f, 0.0f, 0.0f), q2;
    q2 = q1; // make q2 reference the same object as q1
    q2.set(0.0f, 1.0f, 0.0f, 0.0f);
    // now q1 and q2 reference the SAME Osg.Quat with value of
    // (0.0f, 1.0f, 0.0f, 0.0f)
    
    Osg.Vec3 v = new Osg.Vec3(1.0f, 2.0f, 3.0f);
    
  • Enum literals must be scoped with their enum type when used, and implicit conversion of literals to numeric types is not available in C#. Explicit casting of enums to uint is necessary when passing to some OpenSceneGraph functions.
    Osg.DrawArrays drawArrays = new Osg.DrawArrays((uint)Osg.DrawArrays.Mode.QUADS, 0, 4);
    
  • Wrappers of OpenSceneGraph types that inherit from std::vector implement the IList<T> generic interface to allow idiomatic container access and iteration.
    Osg.Vec3Array vertices = new Osg.Vec3Array();
    
    vertices.Add(new Osg.Vec3(1.0f, 0.0f, 0.0f));
    vertices.Add(new Osg.Vec3(2.0f, 0.0f, 0.0f));
    vertices.Add(new Osg.Vec3(3.0f, 0.0f, 0.0f));
    
    foreach (Osg.Vec3 v in vertices)
       Console.WriteLine("{0} {1} {2} {3}", v[0], v[1], v[2], v[3]);
    
  • Operator function support is limited since it must be supported ad hoc (due to limitations of osgIntrospection).
  • Global functions are exposed ad hoc as static methods in the Globals class in each namespace. Wrappers for global functions in the osg, osgDB, and osgText libraries are provided; support has not yet been implemented for the other libraries.
    Osg.Node node = OsgDB.Globals.readNodeFile("cow.osg");
    
  • No reference counting is required. ref_ptr's are neither necessary nor supported.
  • Namespaces start with a capital letter. Using lowercase namespaces will result in a cryptic error, e.g.:
    error CS0122: 'osg.Node' is inaccessible due to its protection level
  • C++ return-by-reference (e.g. osg::Vec3's float &x()) cannot be supported. The bindings for these functions simply return the type by value.
  • Protected members are not supported.
  • Member variable access is not supported other than via pre-existing getter/setter functions.