Startup

Before the mental ray API functions can be used, the following minimal functions must be called to initialize the library:

if (mi_raylib_attach_process() == miFALSE)
    abort();

mi_mem_init();
mi_ntlib_init();

if (!(nthreads = mi_raylib_license_get(mi_msg_no_of_cpus())))
    abort();

mi_raylib_init(miFALSE, nthreads, coremode);

#ifdef _WIN32
    mi_link_set_module_handle(GetModuleHandle("libray.dll"));
#endif

Almost all initialization is done by mi_raylib_init, but some configurations of the library require early initialization of some modules to allow licensing or command line parsing, and for the function that obtains the number of threads.

mi_raylib_attach_process
This function must always be called first, before any other raylib function is called. It allocates resources such as thread storage that is required to use raylib. If allocation fails, it returns miFALSE.
mi_mem_init
This function starts up mental ray's memory manager. It is not part of mi_raylib_init because that function requires certain arguments that might be retrieved from the command line, and it is useful to be able to call functions such as mi_mem_strdup for this purpose. mi_mem_init must be called before any other mi_mem_* function can work.
mi_ntlib_init
This function initializes a module which provides Posix standard functions that are not natively available on Windows platforms. This allows to deliver a unified system programming interface for mental ray. The support functions are implemented based on native Win32 API functions. Note, that this module is needed on Windows platforms only, but for convenience the mi_ntlib_init function can safely be called on any other platform where it does not perform any operation.
At this point of the initialization sequence, the code may perform operations to parse command lines or otherwise obtain parameters. MEM functions are now available, but API, SCENE, DB, and the other groups do not work yet. The mental ray standalone executable parses the command line into static copies of data structures such as miOptions and miCamera here, which are later installed in the scene database after raylib is fully initialized.
mi_raylib_license_get
This function requests a number of licenses, and returns the number of licenses that were available, which may range from zero to the number requested. Each rendering thread typically requires one license (the actual license policy is built into raylib). If no licenses could be obtained, the code cannot proceed and aborts. Here, the number of licenses to ask for is taken from mi_msg_no_of_cpus, which returns the number of CPUs available on the local machine, but the number of rendering threads may be taken from other sources.
mi_raylib_init
This function initializes all remaining parts of raylib. The first argument must always be miFALSE. The second is the number of rendering threads, which must be the value returned by mi_raylib_license_get (otherwise raylib will not work), and the third can be set to miTRUE to prevent raylib from installing a process-wide exception handler that catches signals such as bus errors. After this call, all other functions are available.
mi_link_set_module_handle
This function is required only on Windows platforms. Since raylib is a dynamically linked library (DLL) and not the main executable, any other DLLs like shaders that are dynamically loaded into raylib cannot call its functions without using raylib's handle. The handle can be obtained with the Win32 function GetModuleHandle, given the name of the raylib DLL file. mental ray will pass on the handle to the shader.lib stubs shader interface built into all shader DLLs, which resolves the calls to the shader interface functions by redirecting to the currently loaded raylib.
The default is GetModuleHandle(NULL), that is, the calling executable - which is not correct for executables that don't contain a shader call interface like raylib.
Note, that mi_link_set_module_handle is not built into mi_raylib_init because raylib integrators may want to change the library name, and because it is a Windows-only function. Most Unix systems have a more sophisticated symbol management with dynamically loaded libraries and don't need this functionality, so mi_link_set_module_handle does nothing on these platforms.

This was the minimal initialization sequence. After attaching the process, applications will normally need to register error handlers and read the standard startup file (like rayrc). Here is an extended version:

static void memerror(void)  { mi_fatal("out of memory"); }
static void imgerror(miImg_file * const ifp)
                            { mi_error("file error"); }
static void error_handler(
    const int         errmask,
    const char *const fullmsg,
    const char *const rawmsg,
    const int         code)
{
    printf("%s\n", fullmsg);
}

static void fatal_handler(
    const int         code)
{
    /* handle as desired, like save important data */
    exit(code);
}

...
if (mi_raylib_attach_process() == miFALSE)
    abort();

mi_mem_error_handler(memerror);
mi_img_err_handler(imgerror);
mi_errorhandler(error_handler);
mi_fatal_handler(fatal_handler);

mi_mem_init();
...
mi_mem_error_handler
This function installs a callback that is called by raylib when a memory allocation fails. If there is no callback, this condition is fatal and raylib exits. Installing a callback protects the application that raylib is built into by giving it a chance to clean up, perhaps freeing memory or giving the user a way out, or doing an emergency save. raylib will then only exit if the allocation failed 100 times in a row despite the callback.
mi_img_error_handler
If an image file such as a texture cannot be found or written to, this is a fatal error. Installing an image callback gives the application a way to downgrade the error level, as was done in the above example. The callback may also be empty; other messages with details are printed by raylib first.
mi_errorhandler
This function installs a generic message callback that allows applications to redirect all raylib messages (fatal, error, warning, info, progress, debug, and verbose debug) to another medium, such as an application error log or popup windows. If there is no callback, messages are printed to the terminal window using stderr, if available. Messages from remote server hosts are also passed to this function.
mi_fatal_handler
This function installs a callback that allows applications to intercept raylib calls to exit() in unrecoverable error conditions. The application may not return control to ray when this handler is called.

After these calls, the initialization can proceed with mi_mem_init and the remaining calls from the first example.

Copyright © 1986, 2015 NVIDIA ARC GmbH. All rights reserved.