bool imb_addrectfloatImBuf(ImBuf *ibuf) { size_t size; if (ibuf == NULL) return false; if (ibuf->rect_float) imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */ size = (size_t)(ibuf->x * ibuf->y) * sizeof(float[4]); ibuf->channels = 4; if ((ibuf->rect_float = MEM_mapallocN(size, __func__))) { ibuf->mall |= IB_rectfloat; ibuf->flags |= IB_rectfloat; return true; } return false; }
static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) { const size_t size = vd_resol_size(vd); size_t i; char *data_c; if (is_vd_res_ok(vd) == false) return 0; vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); if (vd->dataset == NULL) return 0; data_c = (char *)MEM_mallocN(sizeof(char) * size, "temporary voxel file reading storage"); if (data_c == NULL) { MEM_freeN(vd->dataset); vd->dataset = NULL; return 0; } if (fseek(fp, (frame - 1) * size * sizeof(char), 0) == -1) { MEM_freeN(data_c); MEM_freeN(vd->dataset); vd->dataset = NULL; return 0; } if (fread(data_c, sizeof(char), size, fp) != size) { MEM_freeN(data_c); MEM_freeN(vd->dataset); vd->dataset = NULL; return 0; } for (i = 0; i < size; i++) { vd->dataset[i] = (float)data_c[i] / 255.f; } MEM_freeN(data_c); vd->cachedframe = frame; vd->ok = 1; return 1; }
static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype) { const char *typestr = get_pass_name(passtype, 0); RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr); int rectsize = rr->rectx * rr->recty * channels; BLI_addtail(&rl->passes, rpass); rpass->passtype = passtype; rpass->channels = channels; rpass->rectx = rl->rectx; rpass->recty = rl->recty; BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name)); if (rl->exrhandle) { int a; for (a = 0; a < channels; a++) IMB_exr_add_channel(rl->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL); } else { float *rect; int x; rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr); if (passtype == SCE_PASS_VECTOR) { /* initialize to max speed */ rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = PASS_VECTOR_MAX; } else if (passtype == SCE_PASS_Z) { rect = rpass->rect; for (x = rectsize - 1; x >= 0; x--) rect[x] = 10e10; } } }
static void init_frame_smoke(VoxelData *vd, int cfra) { #ifdef WITH_SMOKE Object *ob; ModifierData *md; vd->dataset = NULL; if (vd->object == NULL) return; ob = vd->object; /* draw code for smoke */ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { SmokeModifierData *smd = (SmokeModifierData *)md; SmokeDomainSettings *sds = smd->domain; if (sds && sds->fluid) { BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ); if (!sds->fluid) { BLI_rw_mutex_unlock(sds->fluid_mutex); return; } if (cfra < sds->point_cache[0]->startframe) ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; if (!smoke_has_heat(sds->fluid)) { BLI_rw_mutex_unlock(sds->fluid_mutex); return; } copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); /* get heat data */ heat = smoke_get_heat(sds->fluid); /* scale heat values from -2.0-2.0 to 0.0-1.0 */ for (i = 0; i < totRes; i++) { vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; } } else if (vd->smoked_type == TEX_VD_SMOKEVEL) { size_t totRes; size_t i; float *xvel, *yvel, *zvel; copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); /* get velocity data */ xvel = smoke_get_velocity_x(sds->fluid); yvel = smoke_get_velocity_y(sds->fluid); zvel = smoke_get_velocity_z(sds->fluid); /* map velocities between 0 and 0.3f */ for (i = 0; i < totRes; i++) { vd->dataset[i] = sqrtf(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; } } else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { size_t totRes; float *flame; if (sds->flags & MOD_SMOKE_HIGHRES) { if (!smoke_turbulence_has_fuel(sds->wt)) { BLI_rw_mutex_unlock(sds->fluid_mutex); return; } smoke_turbulence_get_res(sds->wt, vd->resol); flame = smoke_turbulence_get_flame(sds->wt); } else { if (!smoke_has_fuel(sds->fluid)) { BLI_rw_mutex_unlock(sds->fluid_mutex); return; } copy_v3_v3_int(vd->resol, sds->res); flame = smoke_get_flame(sds->fluid); } /* always store copy, as smoke internal data can change */ totRes = vd_resol_size(vd); vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); memcpy(vd->dataset, flame, sizeof(float)*totRes); } else { size_t totCells; int depth = 4; vd->data_type = TEX_VD_RGBA_PREMUL; /* data resolution */ if (sds->flags & MOD_SMOKE_HIGHRES) { smoke_turbulence_get_res(sds->wt, vd->resol); } else { copy_v3_v3_int(vd->resol, sds->res); } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ totCells = vd_resol_size(vd) * depth; /* always store copy, as smoke internal data can change */ vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); if (sds->flags & MOD_SMOKE_HIGHRES) { if (smoke_turbulence_has_colors(sds->wt)) { smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); } else { smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); } } else { if (smoke_has_colors(sds->fluid)) { smoke_get_rgba(sds->fluid, vd->dataset, 1); } else { smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); } } } /* end of fluid condition */ BLI_rw_mutex_unlock(sds->fluid_mutex); } } vd->ok = 1; #else // WITH_SMOKE (void)vd; (void)cfra; vd->dataset = NULL; #endif }
/* 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; }
/* note: this function is used for multilayer too, to ensure uniform handling with BKE_image_get_ibuf() */ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser) { ImBuf *ibuf; CompBuf *stackbuf; int type; float *rect; int alloc= FALSE; ibuf= BKE_image_get_ibuf(ima, iuser); if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { return NULL; } if (ibuf->rect_float == NULL) { IMB_float_from_rect(ibuf); } /* now we need a float buffer from the image with matching color management */ /* XXX weak code, multilayer is excluded from this */ if(ibuf->channels == 4 && ima->rr==NULL) { if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { if(ibuf->profile != IB_PROFILE_NONE) { rect= ibuf->rect_float; } else { rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); alloc= TRUE; } } else { if(ibuf->profile == IB_PROFILE_NONE) { rect= ibuf->rect_float; } else { rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); alloc= TRUE; } } } else { /* non-rgba passes can't use color profiles */ rect= ibuf->rect_float; } /* done coercing into the correct color management */ type= ibuf->channels; if(rd->scemode & R_COMP_CROP) { stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type); if(alloc) MEM_freeN(rect); } else { /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE); stackbuf->rect= rect; stackbuf->malloc= alloc; } /*code to respect the premul flag of images; I'm not sure if this is a good idea for multilayer images, since it never worked before for them. if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { //premul the image int i; float *pixel = stackbuf->rect; for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) { pixel[0] *= pixel[3]; pixel[1] *= pixel[3]; pixel[2] *= pixel[3]; } } */ return stackbuf; }
static void init_frame_smoke(VoxelData *vd, float cfra) { #ifdef WITH_SMOKE Object *ob; ModifierData *md; vd->dataset = NULL; if (vd->object == NULL) return; ob= vd->object; /* draw code for smoke */ if( (md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke)) ) { SmokeModifierData *smd = (SmokeModifierData *)md; if(smd->domain && smd->domain->fluid) { if(cfra < smd->domain->point_cache[0]->startframe) ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; VECCOPY(vd->resol, smd->domain->res); totRes= vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); heat = smoke_get_heat(smd->domain->fluid); for (i=0; i<totRes; i++) { vd->dataset[i] = (heat[i]+2.0f)/4.0f; } //vd->dataset = smoke_get_heat(smd->domain->fluid); } else if (vd->smoked_type == TEX_VD_SMOKEVEL) { size_t totRes; size_t i; float *xvel, *yvel, *zvel; VECCOPY(vd->resol, smd->domain->res); totRes= vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); xvel = smoke_get_velocity_x(smd->domain->fluid); yvel = smoke_get_velocity_y(smd->domain->fluid); zvel = smoke_get_velocity_z(smd->domain->fluid); for (i=0; i<totRes; i++) { vd->dataset[i] = sqrt(xvel[i]*xvel[i] + yvel[i]*yvel[i] + zvel[i]*zvel[i])*3.0f; } } else { size_t totRes; float *density; if (smd->domain->flags & MOD_SMOKE_HIGHRES) { smoke_turbulence_get_res(smd->domain->wt, vd->resol); density = smoke_turbulence_get_density(smd->domain->wt); } else { VECCOPY(vd->resol, smd->domain->res); density = smoke_get_density(smd->domain->fluid); } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ totRes= vd_resol_size(vd); /* always store copy, as smoke internal data can change */ vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); memcpy(vd->dataset, density, sizeof(float)*totRes); } // end of fluid condition } } vd->ok = 1; #else // WITH_SMOKE (void)vd; (void)cfra; vd->dataset= NULL; #endif }
/* 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; }