/* Shader make_named_framebuffers Define mental ray framebuffers in version 3.6.x using a geometry shader to modify the options block. For example: instance "framebuffer_creation" geometry "make_named_framebuffers" ( "framebuffers" [ { "name" "diffuse", "type" "rgba_16", "filtering" on, "filename" "buffer_0.tif" }, { "name" "specular", "type" "rgba_16", "filtering" on, "filename" "buffer_1.tif" }, { "name" "indirect", "type" "rgba_16", "filtering" on, "filename" "buffer_2.tif" } ] ) end instance */ #define _CRT_SECURE_NO_WARNINGS #include #include #include "shader.h" #include "geoshader.h" extern "C" { #include "miaux.h" } /* Input parameter for each framebuffer is a struct: */ typedef struct { miInteger name; miTag type; miBoolean filtering; miTag filename; } named_framebuffer; /* Parameter struct for shader function: */ struct make_named_framebuffers { int i_fb; int n_fb; named_framebuffer fb[1]; }; extern "C" DLLEXPORT int make_named_framebuffers_version(void) { return 1; } /* Struct to store evaluated parameters: */ typedef struct { char* name; char* type; miBoolean filtering; char* filename; } fb_args; /* Evaluate the parameters required to define framebuffers: */ std::vector get_named_framebuffer_args( miState *state, struct make_named_framebuffers *params) { int n_fb = *mi_eval_integer(¶ms->n_fb); int i_fb = *mi_eval_integer(¶ms->i_fb); mi_info("Making %i user framebuffers:", n_fb); std::vector args(n_fb); for (int i = 0; i < n_fb; ++i) { named_framebuffer p = params->fb[i + i_fb]; args[i].name = miaux_tag_to_string(*mi_eval_tag(&p.name), NULL); args[i].type = miaux_tag_to_string(*mi_eval_tag(&p.type), NULL); args[i].filtering = *mi_eval_boolean(&p.filtering); args[i].filename = miaux_tag_to_string(*mi_eval_tag(&p.filename), NULL); mi_progress(" Buffer %s: filename '%s', type '%s', filtering %s", args[i].name, args[i].filename, args[i].type, args[i].filtering ? "on" : "off"); } return args; } /* Shader functions: */ extern "C" DLLEXPORT miBoolean make_named_framebuffers ( miTag *result, miState *state, struct make_named_framebuffers *params) { std::vector args = get_named_framebuffer_args(state, params); mi::shader::Edit_fb framebuffers(state->camera->buffertag); for (unsigned int i = 0; i < args.size(); ++i) { framebuffers->set(args[i].name, "datatype", args[i].type); framebuffers->set(args[i].name, "filtering", args[i].filtering ? true : false); framebuffers->set(args[i].name, "user", true); // A framebuffer could be used by output shader and not // written to file, so check for a filename: if (args[i].filename && strlen(args[i].filename) > 1) { mi_info (" ... writes to %s", args[i].filename); framebuffers->set(args[i].name, "filename", args[i].filename); } } return miTRUE; }