1OSPRay v2.0 Porting Guide
2=========================
3
4OSPRay v2.0.0 introduces a number of new features and updates, as well
5as some API changes. This guide is intended as an introduction to the
6new features and the concepts behind them, and as a guide to porting
7applications using OSPRay v1.8.x to v2.0.0.
8
9Parameters
10----------
11
12### Setting parameters
13
14OSPRay traded having a limited number of parameter types (with a unique
15function signature for each type) by instead having a single generic
16function that takes any type found in the `OSPDataType` enum. The new
17function signature is as follows:
18
19    void ospSetParam(OSPObject, const char *name, OSPDataType type, const void *mem)
20
21This function takes the address of the value being set, where care
22should be taken when setting pointer-based types. For example, consider
23the following C-array:
24
25    float myValues[] = {0.f, 1.f, 2.f}
26
27If the application wants to set these values as an OSP_VEC3F, note that
28the `const void *mem` parameter to `ospSetParam` should point to what is
29the address of what would be a `vec3f`. Thus either of the following are
30valid:
31
32    void ospSetParam(object, "some_parameter", OSP_VEC3F, &myValues[0]);
33
34or
35
36    void ospSetParam(object, "some_parameter", OSP_VEC3F, myValues);
37
38The second variant relies on implicit casting from `float[]` to
39`float *`, which will point to the address of the first value. This then
40gets casted to a `vec3f` to be set on the target `object`.
41
42Some of the `ospSet*` functions were preserved as utility wrapper
43functions outlined later in this document (and can be found in
44`ospray_util.h`).
45
46### OSPDataType type checking
47
48Where it was previously accepted to create data of generic type
49`OSP_OBJECT` to represent a list of any object type, the `OSPDataType`
50must now match the object(s) it contains.
51
52Objects
53-------
54
55### New Object Hierarchy
56
57OSPRay objects, such as `OSPGeometry` and `OSPVolume`, have a new
58hierarchy that affords more control over geometry and volume
59transformation and instancing in the scene.
60
61Previously, the workflow was to create an object, fill it with the
62necessary parameters, and then place the object into an `OSPModel` via,
63for example, `ospAddGeometry`. An example is shown below using the C
64API.
65
66    OSPGeometry mesh = ospNewGeometry("triangles");
67    // set parameters on mesh
68    ospCommit(mesh);
69
70    OSPModel world = ospNewModel();
71    ospAddGeometry(world, mesh);
72    ospRelease(mesh);
73    ospCommit(world);
74
75In OSPRay v2.0.0, there is now an `OSPWorld`, which effectively replaces
76the old `OSPModel`. In addition, there are now 3 new objects that exist
77"in between" the geometry and the world: `OSPGeometricModel`,
78`OSPGroup`, and `OSPInstance`. There is also an `OSPVolumetricModel`
79equivalent for working with `OSPVolume` objects.
80
81The new workflow is shown below. Note that calls to `ospRelease()` have
82been removed for brevity.
83
84    // create a geometry
85    OSPGeometry mesh = ospNewGeometry("triangles");
86    // set parameters on mesh
87    ospCommit(mesh);
88
89    // put the geometry in a model (a geometry can exist in more than one model)
90    OSPGeometricModel model = ospNewGeometricModel(mesh);
91    ospCommit(model);
92
93    // put the geometric model(s) in a group
94    OSPGroup group = ospNewGroup();
95    OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1);
96    ospSetObject(group, "geometry", geometricModels);
97    ospCommit(group);
98
99    // put the group in an instance (a group can be instanced more than once)
100    OSPInstance = ospNewInstance(group);
101    ospCommit(instance);
102
103    // put the instance in the world
104    OSPWorld world = ospNewWorld();
105    OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1);
106    ospSetObject(world, "instance", instances);
107    ospCommit(world);
108
109While this looks more complex at first, the new hierarchy structure
110provides more fine control over appearance information and instance
111transformations.
112
113In OSPRay v1.x, geometries and volumes contained both structural and
114appearance information which limited their reuse in other objets. For
115example, the volume's transfer function can now be different between an
116isosurface, slice, and rendered volume all in the same scene without
117duplicating the actual volume itself.
118
119#### OSPGeometry and OSPVolume
120
121`OSPGeometry` and `OSPVolume` contain the physical data represented by
122the object. For geometries, this is the intersectable surface. For
123volumes, it is the scalar field to be sampled.
124
125#### OSPGeometricModel and OSPVolumetricModel
126
127`OSPGeometricModel` and `OSPVolumetricModel` contain appearance
128information about the geometry or volume that they hold. They have a
129one-to-N relationship with `OSPGeometry` and `OSPVolume` objects (i.e. a
130geometry or volume can exist in more than one model), but commonly exist
131as one-to-one. This could be used to create multiple copies of a
132geometry with different materials, for example.
133
134`OSPGeometricModel`s can hold primitive color information (e.g. the
135color used for each sphere in a `Spheres` geometry), a material or list
136of materials, and primitive material IDs (i.e. indexes into the list of
137materials if it is used).
138
139`OSPVolumetricModel`s can hold transfer functions.
140
141#### OSPGroup
142
143`OSPGroup` objects contain zero or more `OSPGeometricModel` and
144`OSPVolumetricModel` objects. They can hold geometries and volumes
145simultaneously.
146
147This is useful to collect together any objects that are logically
148grouped together in the scene.
149
150#### OSPInstance
151
152`OSPInstance` contains transformation information on an `OSPGroup`
153object. It has a one-to-one relationship with `OSPGroup`.
154
155This means that each `OSPInstance` contains exactly one `OSPGroup`.
156Similar to models and groups, a single `OSPGroup` may be placed into
157multiple `OSPInstace` objects. This allows for *instancing* of multiple
158objects throughout the scene, each with different transformations.
159
160`OSPInstance` objects holds an affine transformation matrix that is
161applied to all objects in its group.
162
163#### OSPWorld
164
165`OSPWorld` is the final container for all `OSPInstance` and `OSPLight`
166objects. It can contain one or more instances and lights. The world is
167passed along with a renderer, camera, and framebuffer to
168`ospRenderFrame` to generate an image.
169
170### void ospRetain(OSPObject)
171
172To allow the user greater control over the lifetime of objects, a new
173API `ospRetain` has been introduced. This call increments an object's
174reference count, and can delay automatic deletion.
175
176Updated Public Parameter Names
177------------------------------
178
179OSPRay v2.0.0 has updated public parameter names (the strings used in
180`ospSetParam`) to a more consistent naming convention. OSPRay now will
181print a warning (visible if debug logs are enabled) if a parameter
182provided by the user is not used by an object. This can help catch cases
183where applications are using parameter names from OSPRay v1.8.5 or
184mistyped names. Some objects have required parameters. In these cases,
185OSPRay will invoke the error callback indicating which object and
186which parameter.
187
188OSPRay now universally uses the camelCase naming convention for all object
189types and parameter names. Furthermore, parameter names which are data
190arrays now use singular names to indicate what the elements are, and parameters
191which form a logical "struture-of-arrays" are communicated via the
192`"[structure_name].[member_name]"` naming convention.
193
194For example, the `"opacities"` array for `linear` transfer functions is now
195named `"opacity"`.
196
197Finally, some parameters have changed from being string-based to enum-based.
198All enums can be found in `OSPEnums.h`, where their usage can be found in
199the main API documentation.
200
201ospRenderFrame
202--------------
203
204`ospRenderFrame` has changed in two ways. The signature has changed
205from:
206
207    float ospRenderFrame(OSPFrameBuffer, OSPRenderer,
208                         const uint32_t frameBufferChannels = OSP_FB_COLOR);
209
210to
211
212    OSPFuture ospRenderFrame(OSPFrameBuffer, OSPRenderer, OSPCamera, OSPWorld);
213
214And, notably, it is no longer blocking. Two new calls `ospIsReady`, and
215`ospWait` are available to manage synchronization.
216
217Utility Library
218---------------
219
220As a convenience, a lightweight utility library has been provided to
221help users port from the previous versions and reduce boilerplate code.
222This set of additional API calls are all implemented in terms of the
223core API found in `ospray.h`, where they can be found in
224`ospray_util.h`. Their definitions are compiled into `libospray` (the
225`ospray::ospray` CMake target) and are compatible with any valid device
226implementation.
227
228### OSPData and Parameter helpers
229
230The core OSPRay API has been simplified by removing many of the type
231specializations from the data and parameter set calls. The utility library
232provides wrappers to the familiar calls listed below:
233
234    ospSetString(OSPObject, const char *n, const char *s);
235    ospSetObject(OSPObject, const char *n, OSPObject obj);
236
237    ospSetBool(OSPObject, const char *n, int x);
238    ospSetFloat(OSPObject, const char *n, float x);
239    ospSetInt(OSPObject, const char *n, int x);
240
241    ospSetVec2f(OSPObject, const char *n, float x, float y);
242    ospSetVec3f(OSPObject, const char *n, float x, float y, float z);
243    ospSetVec4f(OSPObject, const char *n, float x, float y, float z, float w);
244
245    ospSetVec2i(OSPObject, const char *n, int x, int y);
246    ospSetVec3i(OSPObject, const char *n, int x, int y, int z);
247    ospSetVec4i(OSPObject, const char *n, int x, int y, int z, int w);
248
249    ospSetObjectAsData(OSPObject, const char *n, OSPDataType type, OSPObject obj);
250
251OSPRay v1.x calls to `ospSetData` have been replaced with `ospSetObject`.
252Convenience wrappers have also been provided to specialize `ospNewData`, and the
253new `ospNewSharedData` and `ospCopyData` APIs.
254
255    ospNewSharedData1D(const void *sharedData, OSPDataType type, uint32_t numItems);
256    ospNewSharedData1DStride(const void *sharedData, OSPDataType type, uint32_t numItems, int64_t byteStride);
257    ospNewSharedData2D(const void *sharedData, OSPDataType type, uint32_t numItems1, uint32_t numItems2);
258    ospNewSharedData2DStride(const void *sharedData, OSPDataType type, uint32_t numItems1, int64_t byteStride1, uint32_t numItems2, int64_t byteStride2);
259    ospNewSharedData3D(const void *sharedData, OSPDataType type, uint32_t numItems1, uint32_t numItems2, uint32_t numItems3);
260
261    ospNewData1D(OSPDataType type, uint32_t numItems);
262    ospNewData2D(OSPDataType type, uint32_t numItems1, uint32_t numItems2);
263
264    ospCopyData1D(const OSPData source, OSPData destination, uint32_t destinationIndex);
265    ospCopyData2D(const OSPData source, OSPData destination, uint32_t destinationIndex1, uint32_t destinationIndex2);
266
267### Object Usage Simplification
268
269To simplify setting data onto an object, if there is only a single data
270item, the wrapper `ospSetObjectAsData` permits the user to assign this
271item without first creating a data object containing that item.
272
273For example:
274
275    OSPData geometricModels = ospNewSharedData1D(&model, OSP_GEOMETRIC_MODEL, 1);
276    ospSetObject(group, "geometry", geometricModels);
277    ospRelease(geometricModels);
278
279simply becomes:
280
281    ospSetObjectAsData(group, "geometry", OSP_GEOMETRIC_MODEL, model);
282
283### Rendering helpers
284
285While `ospRenderFrame` is now asynchronous, some users will prefer the
286original blocking behavior that returns the frame variance. The utility
287library provides a wrapper to this functionality:
288
289    float ospRenderFrameBlocking(OSPFrameBuffer fb,
290                                 OSPRenderer renderer,
291                                 OSPCamera camera,
292                                 OSPWorld world)
293
294