OpenVRML Documentation

0.16.4

OpenVRML comprises a runtime library for VRML97 along with an OpenGL renderer.

Contents

1 Introduction
1.1 History
2 Getting started
2.1 Fetching network resources
2.1.1 Rationale
2.1.2 Introducing resource_istream
2.1.3 Introducing browser
2.1.4 resource_istream implementation considerations
Conformance Test ResultsNIST VRML Test Suite results

1 Introduction

OpenVRML is a runtime library for VRML97 and X3D worlds. OpenVRML parses VRML/X3D directly into an in-memory scene graph format that can be further manipulated through its API and/or rendered.

1.1 History

OpenVRML was started as LibVRML97 by Chris Morley. Since 2000 it has been maintained by Braden McDaniel.

2 Getting started

2.1 Fetching network resources

2.1.1 Rationale

A VRML/X3D runtime must, of course, be able to fetch network resources using URIs. However, there is no standard mechanism in C++ for network communication. Various libraries are available to fill this void; but if OpenVRML were to depend on one of them it could make OpenVRML more difficult to integrate into applications that use some different network layer.

In order to integrate into systems using arbitrary mechanisms for network I/O, OpenVRML requires the user to supply a resource fetching facility. As such, the URI schemes (and corresponding resolution and transfer protocols) supported in worlds loaded into OpenVRML are a function of the user-supplied resource fetching mechanism.

The resource fetching mechanism can be as full-featured or as spartan as the user application requires. A minimal facility might only handle file URLs. But in general it is desirable to support at least the schemes supported by modern Web browsers (significantly, ftp and http).

2.1.2 Introducing resource_istream

OpenVRML accomplishes this extensibility by extending the C++ IOStreams framework. openvrml::resource_istream inherits std::istream and adds a few member functions particular to network resource fetching:

 const std::string url() const throw (std::bad_alloc);
 const std::string type() const throw (std::bad_alloc);
 bool data_available() const throw ();

resource_istream is an abstract class. It is an interface through which OpenVRML can access user code. You use resource_istream by inheriting it and providing implementations for its pure virtual functions.

2.1.3 Introducing browser

The centerpiece of the OpenVRML library is openvrml::browser. This class provides the interface for loading VRML/X3D worlds. Most management of the runtime will be handled through its member functions. Like resource_istream, browser is an abstract class that users must inherit. However, browser has only one pure virtual function you must implement: the one responsible for creating resource_istreams.

 virtual std::auto_ptr<resource_istream> do_get_resource(const std::string & uri) = 0;

The API documentation for openvrml::browser::do_get_resource provides more details on the requirements for this function's implementation. Briefly, your implementation will return a std::auto_ptr to an instance of your class that implements openvrml::resource_istream.

Note:
Most “factory functions” (i.e., functions that return an instance of an object allocated with new) in OpenVRML return an auto_ptr. std::auto_ptr is used for ownership transfer; its use for a return value signals that the caller is taking ownership of the resource.

2.1.4 resource_istream implementation considerations

OpenVRML supports a notion of data streaming. In general, network resources are read asynchronously with respect to the rendering thread. User code that does not support data streaming (as in the example using std::filebuf in the documentation for openvrml::browser::do_get_resource) can remain largely oblivious to synchronization issues. However, user code that supports data streaming must be mindful of the fact that OpenVRML uses separate threads to read the data streams. Care must be taken not to write to a buffer at the same time OpenVRML's stream reading thread is reading the buffer.

The IOstreams framework is typically extended by inheriting std::streambuf to implement new sources and sinks for data. (Full treatment of this topic is beyond the scope of this document; see The C++ Standard Library by Nicolai M. Josuttis and Standard C++ IOStreams and Locales by Angelika Langer and Klaus Kreft.) However, std::streambuf's interface is not thread-safe. Since OpenVRML's stream-reading thread can be expected to be using the streambuf interface (by way of the std::istream member functions inherited by openvrml::resource_istream), it is only safe for user code to use the streambuf interface in that same thread; i.e., in code called by OpenVRML.

If user code needs to feed data into a buffer in a separate thread, that buffer should not be the one managed by the streambuf interface (i.e., the buffer to which eback, gptr, and egptr point). In general it is appropriate to use a secondary buffer, protected with thread synchronization primitives, for writing incoming data. Data can then be moved from this buffer to the streambuf's buffer in the implementation of std::streambuf::underflow.