static RenderPass *render_layer_add_debug_pass(RenderResult *rr, RenderLayer *rl, int channels, int pass_type, int debug_type, const char *view) { RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type, view); rpass->debug_type = debug_type; BLI_strncpy(rpass->name, debug_pass_type_name_get(debug_type), sizeof(rpass->name)); BLI_strncpy(rpass->internal_name, rpass->name, sizeof(rpass->internal_name)); return rpass; }
/* re->winx,winy is coordinate space of entire image, partrct the part within */ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername, const char *viewname) { RenderResult *rr; RenderLayer *rl; RenderView *rv; SceneRenderLayer *srl; int rectx, recty; int nr; rectx = BLI_rcti_size_x(partrct); recty = BLI_rcti_size_y(partrct); if (rectx <= 0 || recty <= 0) return NULL; rr = MEM_callocN(sizeof(RenderResult), "new render result"); rr->rectx = rectx; rr->recty = recty; rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop; /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ rr->crop = crop; /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ rr->tilerect.xmin = partrct->xmin - re->disprect.xmin; rr->tilerect.xmax = partrct->xmax - re->disprect.xmin; rr->tilerect.ymin = partrct->ymin - re->disprect.ymin; rr->tilerect.ymax = partrct->ymax - re->disprect.ymin; if (savebuffers) { rr->do_exr_tile = true; } render_result_views_new(rr, &re->r); /* check renderdata for amount of layers */ for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) { if (layername && layername[0]) if (!STREQ(srl->name, layername)) continue; if (re->r.scemode & R_SINGLE_LAYER) { if (nr != re->r.actlay) continue; } else { if (srl->layflag & SCE_LAY_DISABLE) continue; } rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); rl->lay = srl->lay; rl->lay_zmask = srl->lay_zmask; rl->lay_exclude = srl->lay_exclude; rl->layflag = srl->layflag; rl->passflag = srl->passflag; /* for debugging: srl->passflag | SCE_PASS_RAYHITS; */ rl->pass_xor = srl->pass_xor; rl->light_override = srl->light_override; rl->mat_override = srl->mat_override; rl->rectx = rectx; rl->recty = recty; if (rr->do_exr_tile) { rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba"); rl->exrhandle = IMB_exr_get_handle(); } for (rv = rr->views.first; rv; rv = rv->next) { const char *view = rv->name; if (viewname && viewname[0]) if (!STREQ(view, viewname)) continue; if (rr->do_exr_tile) IMB_exr_add_view(rl->exrhandle, view); /* a renderlayer should always have a Combined pass*/ render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view); if (srl->passflag & SCE_PASS_Z) render_layer_add_pass(rr, rl, 1, SCE_PASS_Z, view); if (srl->passflag & SCE_PASS_VECTOR) render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR, view); if (srl->passflag & SCE_PASS_NORMAL) render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL, view); if (srl->passflag & SCE_PASS_UV) render_layer_add_pass(rr, rl, 3, SCE_PASS_UV, view); if (srl->passflag & SCE_PASS_RGBA) render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA, view); if (srl->passflag & SCE_PASS_EMIT) render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT, view); if (srl->passflag & SCE_PASS_DIFFUSE) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE, view); if (srl->passflag & SCE_PASS_SPEC) render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC, view); if (srl->passflag & SCE_PASS_AO) render_layer_add_pass(rr, rl, 3, SCE_PASS_AO, view); if (srl->passflag & SCE_PASS_ENVIRONMENT) render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT, view); if (srl->passflag & SCE_PASS_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT, view); if (srl->passflag & SCE_PASS_SHADOW) render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW, view); if (srl->passflag & SCE_PASS_REFLECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT, view); if (srl->passflag & SCE_PASS_REFRACT) render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT, view); if (srl->passflag & SCE_PASS_INDEXOB) render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB, view); if (srl->passflag & SCE_PASS_INDEXMA) render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA, view); if (srl->passflag & SCE_PASS_MIST) render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST, view); if (rl->passflag & SCE_PASS_RAYHITS) render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS, view); if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view); if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view); if (srl->passflag & SCE_PASS_DIFFUSE_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view); if (srl->passflag & SCE_PASS_GLOSSY_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view); if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view); if (srl->passflag & SCE_PASS_GLOSSY_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view); if (srl->passflag & SCE_PASS_TRANSM_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view); if (srl->passflag & SCE_PASS_TRANSM_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view); if (srl->passflag & SCE_PASS_TRANSM_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view); if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view); if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view); if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view); #ifdef WITH_CYCLES_DEBUG if (BKE_scene_use_new_shading_nodes(re->scene)) { render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG, re->r.debug_pass_type, view); } #endif } } /* sss, previewrender and envmap don't do layers, so we make a default one */ if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) { rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); rl->rectx = rectx; rl->recty = recty; /* duplicate code... */ if (rr->do_exr_tile) { rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba"); rl->exrhandle = IMB_exr_get_handle(); } for (rv = rr->views.first; rv; rv = rv->next) { const char *view = rv->name; if (viewname && viewname[0]) if (strcmp(view, viewname) != 0) continue; if (rr->do_exr_tile) IMB_exr_add_view(rl->exrhandle, view); /* a renderlayer should always have a Combined pass */ render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view); } /* note, this has to be in sync with scene.c */ rl->lay = (1 << 20) - 1; rl->layflag = 0x7FFF; /* solid ztra halo strand */ rl->passflag = SCE_PASS_COMBINED; re->r.actlay = 0; } /* border render; calculate offset for use in compositor. compo is centralized coords */ /* XXX obsolete? I now use it for drawing border render offset (ton) */ rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2); rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2); return rr; }
/* re->winx,winy is coordinate space of entire image, partrct the part within */ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername) { RenderResult *rr; RenderLayer *rl; SceneRenderLayer *srl; int rectx, recty, nr; rectx = BLI_rcti_size_x(partrct); recty = BLI_rcti_size_y(partrct); if (rectx <= 0 || recty <= 0) return NULL; rr = MEM_callocN(sizeof(RenderResult), "new render result"); rr->rectx = rectx; rr->recty = recty; rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop; /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ rr->crop = crop; /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ rr->tilerect.xmin = partrct->xmin - re->disprect.xmin; rr->tilerect.xmax = partrct->xmax - re->disprect.xmin; rr->tilerect.ymin = partrct->ymin - re->disprect.ymin; rr->tilerect.ymax = partrct->ymax - re->disprect.ymin; if (savebuffers) { rr->do_exr_tile = TRUE; } /* check renderdata for amount of layers */ for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) { if (layername && layername[0]) if (strcmp(srl->name, layername) != 0) continue; if ((re->r.scemode & R_SINGLE_LAYER) && nr != re->r.actlay) continue; if (srl->layflag & SCE_LAY_DISABLE) continue; rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); BLI_strncpy(rl->name, srl->name, sizeof(rl->name)); rl->lay = srl->lay; rl->lay_zmask = srl->lay_zmask; rl->lay_exclude = srl->lay_exclude; rl->layflag = srl->layflag; rl->passflag = srl->passflag; /* for debugging: srl->passflag | SCE_PASS_RAYHITS; */ rl->pass_xor = srl->pass_xor; rl->light_override = srl->light_override; rl->mat_override = srl->mat_override; rl->rectx = rectx; rl->recty = recty; if (rr->do_exr_tile) { rl->exrhandle = IMB_exr_get_handle(); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL); } else rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba"); if (srl->passflag & SCE_PASS_Z) render_layer_add_pass(rr, rl, 1, SCE_PASS_Z); if (srl->passflag & SCE_PASS_VECTOR) render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR); if (srl->passflag & SCE_PASS_NORMAL) render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL); if (srl->passflag & SCE_PASS_UV) render_layer_add_pass(rr, rl, 3, SCE_PASS_UV); if (srl->passflag & SCE_PASS_RGBA) render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA); if (srl->passflag & SCE_PASS_EMIT) render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT); if (srl->passflag & SCE_PASS_DIFFUSE) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE); if (srl->passflag & SCE_PASS_SPEC) render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC); if (srl->passflag & SCE_PASS_AO) render_layer_add_pass(rr, rl, 3, SCE_PASS_AO); if (srl->passflag & SCE_PASS_ENVIRONMENT) render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT); if (srl->passflag & SCE_PASS_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT); if (srl->passflag & SCE_PASS_SHADOW) render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW); if (srl->passflag & SCE_PASS_REFLECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT); if (srl->passflag & SCE_PASS_REFRACT) render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT); if (srl->passflag & SCE_PASS_INDEXOB) render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB); if (srl->passflag & SCE_PASS_INDEXMA) render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA); if (srl->passflag & SCE_PASS_MIST) render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST); if (rl->passflag & SCE_PASS_RAYHITS) render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS); if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT); if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT); if (srl->passflag & SCE_PASS_DIFFUSE_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR); if (srl->passflag & SCE_PASS_GLOSSY_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT); if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT); if (srl->passflag & SCE_PASS_GLOSSY_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR); if (srl->passflag & SCE_PASS_TRANSM_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT); if (srl->passflag & SCE_PASS_TRANSM_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT); if (srl->passflag & SCE_PASS_TRANSM_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR); if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT); if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT); if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR) render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR); } /* sss, previewrender and envmap don't do layers, so we make a default one */ if (rr->layers.first == NULL && !(layername && layername[0])) { rl = MEM_callocN(sizeof(RenderLayer), "new render layer"); BLI_addtail(&rr->layers, rl); rl->rectx = rectx; rl->recty = recty; /* duplicate code... */ if (rr->do_exr_tile) { rl->exrhandle = IMB_exr_get_handle(); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.R", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.G", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.B", 0, 0, NULL); IMB_exr_add_channel(rl->exrhandle, rl->name, "Combined.A", 0, 0, NULL); } else { rl->rectf = MEM_mapallocN(rectx * recty * sizeof(float) * 4, "Combined rgba"); } /* note, this has to be in sync with scene.c */ rl->lay = (1 << 20) - 1; rl->layflag = 0x7FFF; /* solid ztra halo strand */ rl->passflag = SCE_PASS_COMBINED; re->r.actlay = 0; } /* border render; calculate offset for use in compositor. compo is centralized coords */ /* XXX obsolete? I now use it for drawing border render offset (ton) */ rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2); rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2); return rr; }