Working With Object Handles
Most types of objects in Beast, such as scenes, textures, meshes, light sources and render jobs, are used through
handles. Each type of handle has its own set of functions that you can call to initialize
it, access its data, and operate on it. Taken together, these handles and their related
functions are quite similar to classes and class methods in object-oriented languages
such as C++: you can think of the handle as a pointer to a class instance, and the
functions that operate on it are like class methods.
Typically, you work with these handles as follows:
- You create a new instance of the handle, either on the stack or on the heap.
- You initialize the handle and prepare it for use by calling a function specific to
that type of handle, and passing a pointer to your handle as an argument. For example,
to initialize a light source handle as a point light, you call ILBCreatePointLight(). Similarly, to initialize a camera handle, you call ILBCreatePerspectiveCamera().
- Any time you call a function to access the data in the handle, you pass your handle
as an argument by value.
- Some kinds of handles, such as scenes and meshes, need to be closed when you are finished
modifying them. This marks them as being complete, prevents them from further modification,
and enables their use for other purposes. For example, after a scene is closed you
can render it, and after a mesh is closed you can create instances of it.
- Some kinds of handles, such as jobs, job updates, framebuffers and scenes, also offer
"destroy" or "release" functions that release all memory allocated by the handle.
In most cases, you do not need to call these explicitly, as the handle will be cleared
transparently when its variable passes out of scope or when the Beast manager is destroyed. However, if you need to free up the memory at some point, you
can call these functions to do so. Note that these calls invalidate the handles; the
destroyed or released handles cannot be used again unless you re-initialize them.
For example, the following code shows how to create and use mesh and instance handles:
ILBMeshHandle myMesh;
// Note that myMesh is passed as a pointer for initialization.
ILBBeginMesh(bm, "myMesh", &myMesh);
// Now myMesh is passed as a value.
ILBAddVertexData(myMesh, vertexData, normalData, vertexCount);
...
// Now myMesh is closed, after which it can be instantiated.
ILBEndMesh(myMesh);
ILBInstanceHandle myMeshInstance;
ILBCreateInstance(myScene, myMesh, "InstanceName", matrix, &myMeshInstance);
...