This section describes the high-level API which provides an easy-to-use scene definition layer for geometry shaders. The high-level API functions are mainly concerned with atomic creation of high-level elements like those found in the .mi language. Many such elements, especially geometric objects, are built from multiple scene database entries with numerous internal references. This internal complexity is hidden by the API module and expanded automatically. However, simple elements such as cameras are created by API calls but filling in certain parameters requires struct member assignment. To simplify the API call interface, API calls that would do nothing but assign a variable to another have been omitted.
Conceptually, database storage is performed on four layers:
This section should be read in conjunction with the section scenedatastruct, which describes simple data structures that the API module requires assignments to. For example, API contains functions to begin and finish the creation of a camera, but provides no functions for setting each of the many fields of these structures. Instead, they are simply written to the fields directly.
The API module has been patterned after the .mi language, to the point where the .mi yacc grammar consists almost entirely of one or very few API calls or variable assignments for every statement and clause. To understand the correct order of API calls, refer to the .mi language description (page scenechapter). The complete yacc grammar that parses the .mi language, including C code, is reprinted in appendix B. For information on the syntax of a yacc grammar description, refer to the Unix manual page for yacc.
Note that all character string arguments passed to any of the API functions below are expected to have been allocated with mi_mem_allocate or, more commonly, mi_mem_strdup. All API functions release such strings using mi_mem_release, so the same allocated string may not be passed to API twice. Similarly, miDlists created with mi_api_dlist_create and passed as an argument to an API call are freed by API, and should not be passed to API twice. The reason for this is that API keeps most strings for extended periods of time, so allocation is almost always necessary somewhere, and putting the burden on the API caller avoids double allocations in cases where the caller works with allocated strings anyway (for example in yacc parsers). In the few cases where API could work with non-allocated strings ( mi_api_debug, for example) allocation is required anyway to avoid requiring allocation for some strings but not others, which would invite hard-to-find bugs. Functions whose name does not begin with mi_api_ generally do not require string allocation.
Most API functions return a boolean, a pointer, or a tag. If the function succeeds, miTRUE, a non-null pointer, or a non-null tag is returned, respectively. If an error occurs, miFALSE or a null pointer or tag is returned; this means that errors can be caught with C's "!" operator. The tags returned by the calls whose names end in _end are merely a convenience; they are not generally useful to standard name-based translators.
Note that many of these functions come in begin and end pairs, such as mi_api_object_begin and mi_api_object_end. These calls may not be interleaved in any way; there may only be one open unfinished begin ... end bracket at any time in a single thread. (Multiple threads can have such an open bracket each.)
Copyright © 1986-2009 by mental images GmbH