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
{
mi::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);
}
Note
The conditional 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.