The following examples are similar to the previous, except that the scene is not read from a .mi file but created with API calls. Most of these function calls belong to the geometry shader interface described in the programming book [Handbook 2].
This example is creating polygonal geometry in mental ray. The mainline program is unchanged from the previous example, except that the mi_mi_parse loop was replaced with a new function create_scene that uses API calls to create the scene.
#include <stdio.h> #include <shader.h> #include <geoshader.h> #include <mirelay.h> static void memerror(void) { mi_fatal("out of memory"); } static void imgerror(miImg_file * const ifp) { mi_fatal("file error, exiting."); } static void create_scene(void); int main( int argc, char *argv[]) { int nthreads; miTag root, caminst, cam, opt; miInh_func inh; if (!mi_raylib_attach_process()) return(1); mi_mem_error_handler(memerror); mi_img_err_handler(imgerror); mi_mem_init(); mi_ntlib_init(); nthreads = mi_raylib_license_get(mi_msg_no_of_cpus()); mi_raylib_init(miFALSE, nthreads, miFALSE); #ifdef _WIN32 mi_link_set_module_handle(GetModuleHandle("libray.dll")); #endif mi_mi_parse_rayrc(0, miFALSE); create_scene(); mi_api_render_params(&root, &caminst, &cam, &opt, &inh); if (!mi_rc_run(miRENDER_DEFAULT, 0, 0, root, caminst, cam, opt, inh)) mi_api_render_release(); mi_raylib_license_release(); mi_raylib_exit(); mi_raylib_detach_process(); return(0); } /* * The following code was generated from the cube .mi scene * using the mitoapi utility, and heavily cleaned up by hand. */ static miGeoVector cubevectors[8] = { { -0.5, -0.5, -0.5 }, { -0.5, -0.5, 0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, -0.5, 0.5 }, { 0.5, 0.5, -0.5 }, { 0.5, 0.5, 0.5 }}; static int cubepolygons[6][4] = { { 0, 1, 3, 2 }, { 1, 5, 7, 3 }, { 5, 4, 6, 7 }, { 4, 0, 2, 6 }, { 4, 5, 1, 0 }, { 2, 3, 7, 6 }}; static void create_scene(void) { miCamera *camera; miOptions *options; miLight *light; miMaterial *material; miInstance *instance, dummy_inst; miObject *object; miParameter *parm, *cparm, *plist; miFunction_decl *decl, dummy_decl; miTag function; miMatrix transform; char *symbol; int ivalue; float fvalue; int i, j; mi_set_verbosity(miERR_DEFAULT | miERR_INFO | miERR_PROGRESS); mi_link_file_add("base.so", miFALSE, miFALSE, miFALSE); /* * declare shader mib_light_point */ symbol = mi_mem_strdup("color"); parm = mi_api_parameter_decl(miTYPE_COLOR, symbol, 0); plist = parm; symbol = mi_mem_strdup("shadow"); parm = mi_api_parameter_decl(miTYPE_BOOLEAN, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("factor"); parm = mi_api_parameter_decl(miTYPE_SCALAR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("atten"); parm = mi_api_parameter_decl(miTYPE_BOOLEAN, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("start"); parm = mi_api_parameter_decl(miTYPE_SCALAR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("stop"); parm = mi_api_parameter_decl(miTYPE_SCALAR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("mib_light_point"); parm = mi_api_parameter_decl(miTYPE_COLOR, 0, 0); if (!(decl = mi_api_funcdecl_begin(parm, symbol, plist))) decl = &dummy_decl; decl->version = 1; decl->apply = miAPPLY_LIGHT; mi_api_funcdecl_end(); /* * declare shader mib_illum_phong */ symbol = mi_mem_strdup("ambience"); parm = mi_api_parameter_decl(miTYPE_COLOR, symbol, 0); plist = parm; symbol = mi_mem_strdup("ambient"); parm = mi_api_parameter_decl(miTYPE_COLOR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("diffuse"); parm = mi_api_parameter_decl(miTYPE_COLOR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("specular"); parm = mi_api_parameter_decl(miTYPE_COLOR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("exponent"); parm = mi_api_parameter_decl(miTYPE_SCALAR, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("mode"); parm = mi_api_parameter_decl(miTYPE_INTEGER, symbol, 0); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("lights"); cparm = mi_api_parameter_decl(miTYPE_LIGHT, symbol, 0); parm = mi_api_parameter_decl(miTYPE_ARRAY, 0, 0); mi_api_parameter_child(parm, cparm); plist = mi_api_parameter_append(plist, parm); symbol = mi_mem_strdup("mib_illum_phong"); parm = mi_api_parameter_decl(miTYPE_COLOR, 0, 0); if (!(decl = mi_api_funcdecl_begin(parm, symbol, plist))) decl = &dummy_decl; decl->version = 2; mi_api_funcdecl_end(); /* * create options block */ options = mi_api_options_begin(mi_mem_strdup("opt")); options->min_samples = -1; options->max_samples = 2; options->contrast.r = options->contrast.g = options->contrast.b = options->contrast.a = 0.1f; options->render_space = 'o'; mi_api_options_end(); /* * create camera */ camera = mi_api_camera_begin(mi_mem_strdup("cam")); camera->frame = 1; mi_api_function_delete(&camera->output); #ifdef RAY36 {Note The conditionalmi::shader::Edit_fb framebuffers(camera->buffertag); framebuffers->set("main", "filename", "out.rgb"); framebuffers->set("main", "filetype", "rgb");} #else camera->output = mi_api_function_append(camera->output, mi_api_output_file_def(0, 0, mi_mem_strdup("rgb"), mi_mem_strdup("out.rgb"))); #endif camera->focal = 50; camera->orthographic = miFALSE; camera->aperture = 44; camera->aspect = 1.25; camera->x_resolution = 720; camera->y_resolution = 576; mi_api_camera_end(); /* * create camera instance */ instance = mi_api_instance_begin(mi_mem_strdup("cam_inst")); if (!instance) instance = &dummy_inst; transform[ 0] = 0.771900f; transform[ 1] = 0.304200f; transform[ 2] = -0.558200f; transform[ 3] = 0.000000f; transform[ 4] = 0.000000f; transform[ 5] = 0.878100f; transform[ 6] = 0.478500f; transform[ 7] = 0.000000f; transform[ 8] = 0.635700f; transform[ 9] = -0.369300f; transform[10] = 0.677800f; transform[11] = 0.000000f; transform[12] = 0.000000f; transform[13] = 0.000000f; transform[14] = -2.500000f; transform[15] = 1.000000f; instance->tf.function = 0; mi_matrix_copy(instance->tf.global_to_local, transform); if (!mi_matrix_invert(instance->tf.local_to_global, instance->tf.global_to_local)) { mi_api_warning("singular matrix, using identity"); mi_matrix_ident(instance->tf.global_to_local); mi_matrix_ident(instance->tf.local_to_global); } mi_api_instance_end(mi_mem_strdup("cam"), 0, (miTag)-1); /* * create light shader */ mi_api_function_call(mi_mem_strdup("mib_light_point")); fvalue = 1.0; mi_api_parameter_name(mi_mem_strdup("color")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); fvalue = 0.75; mi_api_parameter_name(mi_mem_strdup("factor")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); function = mi_api_function_call_end(0); /* * create light */ light = mi_api_light_begin(mi_mem_strdup("light1")); mi_api_function_delete(&light->shader); light->shader = mi_api_function_append(light->shader, function); light->origin.x = light->origin.y = light->origin.z = 0; light->type = miLIGHT_ORIGIN; mi_api_light_end(); /* * create light instance */ if (instance = mi_api_instance_begin(mi_mem_strdup("light1_inst"))) { instance->tf.global_to_local[12] = -2; instance->tf.global_to_local[13] = -3; instance->tf.global_to_local[14] = -2; mi_matrix_invert(instance->tf.local_to_global, instance->tf.global_to_local); } mi_api_instance_end(mi_mem_strdup("light1"), 0, (miTag)-1); /* * create material shader */ mi_api_function_call(mi_mem_strdup("mib_illum_phong")); fvalue = 0.5f; mi_api_parameter_name(mi_mem_strdup("ambient")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); fvalue = 0.7f; mi_api_parameter_name(mi_mem_strdup("diffuse")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); fvalue = 0.3f; mi_api_parameter_name(mi_mem_strdup("ambience")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); fvalue = 1.0f; mi_api_parameter_name(mi_mem_strdup("specular")); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); mi_api_parameter_value(miTYPE_SCALAR, &fvalue, 0, 0); ivalue = 50; mi_api_parameter_name(mi_mem_strdup("exponent")); mi_api_parameter_value(miTYPE_INTEGER, &ivalue, 0, 0); ivalue = 4; mi_api_parameter_name(mi_mem_strdup("mode")); mi_api_parameter_value(miTYPE_INTEGER, &ivalue, 0, 0); function = mi_api_function_call_end(0); /* * create material */ material = mi_api_material_begin(mi_mem_strdup("mtl")); material->opaque = miTRUE; material->shader = function; mi_api_material_end(); /* * create cube object */ object = mi_api_object_begin(mi_mem_strdup("object1")); object->visible = miTRUE; object->shadow = object->reflection = object->refraction = object->finalgather = 0x03; object->label = 1; mi_api_object_group_begin(0.0); for (i=0; i < 8;="" i++)="" mi_api_geovector_xyz_add(&cubevectors[i]);="" for="" (i="0;" i="" />< 8;="" i++)="" mi_api_vertex_add(i);="" for="" (i="0;" i="" />< 6;="" i++)="" {="" mi_api_poly_begin(0,="" i="" 0="" :="" mi_mem_strdup("mtl"));="" for="" (j="0;" j="" />< 4;="" j++)="" mi_api_poly_index_add(cubepolygons[i][j]);="" mi_api_poly_end();="" }="" mi_api_object_group_end();="" mi_api_object_end();="" *="" create="" cube="" object="" instance="" */="" if="" (instance="mi_api_instance_begin(mi_mem_strdup("object1_inst")))" {="" mi_api_light_list_begin();="" mi_api_light_list_add(mi_mem_strdup("light1_inst"));="" instance-="" />light_list = mi_api_light_list_end(); } mi_api_instance_end(mi_mem_strdup("object1"), 0, (miTag)-1); /* * create root group containing all instances */ mi_api_instgroup_begin(mi_mem_strdup("rootgrp")); mi_api_instgroup_clear(); mi_api_instgroup_additem(mi_mem_strdup("cam_inst")); mi_api_instgroup_additem(mi_mem_strdup("light1_inst")); mi_api_instgroup_additem(mi_mem_strdup("object1_inst")); mi_api_instgroup_end(); /* * what to render */ mi_api_render(mi_mem_strdup("rootgrp"), mi_mem_strdup("cam_inst"), mi_mem_strdup("opt"), 0); }
RAY36
section shows how to use the modern C++ API
to create a named frame buffer that is written to a file.
All functions used in create_scene are part of the geometry shader API, with three exceptions:
Here is the .mi scene file that create_scene was derived from. Feeding this scene to the first example using mi_mi_parse will create exactly the same rendered image as this example.
verbose on link "base.so" declare shader color "mib_light_point" ( color "color", boolean "shadow", scalar "factor", boolean "atten", scalar "start", scalar "stop" ) version 1 apply light end declare declare shader color "mib_illum_phong" ( color "ambience", color "ambient", color "diffuse", color "specular", scalar "exponent", integer "mode", array light "lights" ) version 2 end declare options "opt" samples -1 2 contrast 0.1 0.1 0.1 0.1 object space end options camera "cam" $ifdef "RAY36"framebuffer "main" filetype "rgb" filename "out.rgb"$else output "rgb" "out.rgb" $endif frame 1 focal 50 aperture 44 aspect 1.25 resolution 720 576 end camera instance "cam_inst" "cam" transform 0.7719 0.3042 -0.5582 0.0 0.0000 0.8781 0.4785 0.0 0.6357 -0.3693 0.6778 0.0 0.0000 0.0000 -2.5000 1.0 end instance light "light1" "mib_light_point" ( "color" 1 1 1, "factor" 0.75 ) origin 0 0 0 end light instance "light1_inst" "light1" transform 1 0 0 0 0 1 0 0 0 0 1 0 -2 -3 -2 1 end instance material "mtl" opaque "mib_illum_phong" ( "ambient" 0.5 0.5 0.5, "diffuse" 0.7 0.7 0.7, "ambience" 0.3 0.3 0.3, "specular" 1.0 1.0 1.0, "exponent" 50, "mode" 4 ) end material object "object1" visible on shadow 3 reflection 3 refraction 3 finalgather 3 tag 1 group -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 v 0 v 1 v 2 v 3 v 4 v 5 v 6 v 7 p "mtl" 0 1 3 2 p 1 5 7 3 p 5 4 6 7 p 4 0 2 6 p 4 5 1 0 p 2 3 7 6 end group end object instance "object1_inst" "object1" light [ "light1_inst" ] transform 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 end instance instgroup "rootgrp" "cam_inst" "light1_inst" "object1_inst" end instgroup render "rootgrp" "cam_inst" "opt"
Note The marked section shows how to use modern .mi syntax to create a named frame buffer with image file output.
Copyright © 1986, 2015 NVIDIA ARC GmbH. All rights reserved.