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.
