void render_result_single_layer_begin(Render *re) { /* all layers except the active one get temporally pushed away */ /* officially pushed result should be NULL... error can happen with do_seq */ RE_FreeRenderResult(re->pushedresult); re->pushedresult = re->result; re->result = NULL; }
int RE_engine_render(Render *re, int do_all) { RenderEngineType *type= RE_engines_find(re->r.engine); RenderEngine *engine; /* verify if we can render */ if(!type->render) return 0; if((re->r.scemode & R_PREVIEWBUTS) && !(type->flag & RE_USE_PREVIEW)) return 0; if(do_all && !(type->flag & RE_USE_POSTPROCESS)) return 0; if(!do_all && (type->flag & RE_USE_POSTPROCESS)) return 0; /* create render result */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) { RE_FreeRenderResult(re->result); re->result= new_render_result(re, &re->disprect, 0, 0); } BLI_rw_mutex_unlock(&re->resultmutex); if(re->result==NULL) return 1; /* set render info */ re->i.cfra= re->scene->r.cfra; BLI_strncpy(re->i.scenename, re->scene->id.name+2, sizeof(re->i.scenename)); re->i.totface=re->i.totvert=re->i.totstrand=re->i.totlamp=re->i.tothalo= 0; /* render */ engine = RE_engine_create(type); engine->re= re; if(re->flag & R_ANIMATION) engine->flag |= RE_ENGINE_ANIMATION; if(re->r.scemode & R_PREVIEWBUTS) engine->flag |= RE_ENGINE_PREVIEW; if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0) scene_update_for_newframe(re->main, re->scene, re->lay); if(type->update) type->update(engine, re->main, re->scene); if(type->render) type->render(engine, re->scene); free_render_result(&engine->fullresult, engine->fullresult.first); RE_engine_free(engine); return 1; }
/* For cache, makes exact copy of render result */ bool render_result_exr_file_cache_read(Render *re) { char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = ""; char *root = U.render_cachedir; RE_FreeRenderResult(re->result); re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); /* First try cache. */ render_result_exr_file_cache_path(re->scene, root, str); printf("read exr cache file: %s\n", str); if (!render_result_exr_file_read_path(re->result, NULL, str)) { printf("cannot read: %s\n", str); return false; } return true; }
/* only for temp buffer, makes exact copy of render result */ int render_result_exr_file_read_sample(Render *re, int sample) { RenderLayer *rl; char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = ""; bool success = true; RE_FreeRenderResult(re->result); re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS); for (rl = re->result->layers.first; rl; rl = rl->next) { render_result_exr_file_path(re->scene, rl->name, sample, str); printf("read exr tmp file: %s\n", str); if (!render_result_exr_file_read_path(re->result, rl, str)) { printf("cannot read: %s\n", str); success = false; } } return success; }
/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */ void render_result_single_layer_end(Render *re) { SceneRenderLayer *srl; RenderLayer *rlpush; RenderLayer *rl; int nr; if (re->result == NULL) { printf("pop render result error; no current result!\n"); return; } if (!re->pushedresult) return; if (re->pushedresult->rectx == re->result->rectx && re->pushedresult->recty == re->result->recty) { /* find which layer in re->pushedresult should be replaced */ rl = re->result->layers.first; /* render result should be empty after this */ BLI_remlink(&re->result->layers, rl); /* reconstruct render result layers */ for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) { if (nr == re->r.actlay) { BLI_addtail(&re->result->layers, rl); } else { rlpush = RE_GetRenderLayer(re->pushedresult, srl->name); if (rlpush) { BLI_remlink(&re->pushedresult->layers, rlpush); BLI_addtail(&re->result->layers, rlpush); } } } } RE_FreeRenderResult(re->pushedresult); re->pushedresult = NULL; }
/* only for temp buffer files, makes exact copy of render result */ int render_result_exr_file_read(Render *re, int sample) { RenderLayer *rl; char str[FILE_MAX]; int success = TRUE; RE_FreeRenderResult(re->result); re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS); for (rl = re->result->layers.first; rl; rl = rl->next) { render_result_exr_file_path(re->scene, rl->name, sample, str); printf("read exr tmp file: %s\n", str); if (!render_result_exr_file_read_path(re->result, rl, str)) { printf("cannot read: %s\n", str); success = FALSE; } } return success; }
static void sss_create_tree_mat(Render *re, Material *mat) { SSSPoints *p; RenderResult *rr; ListBase points; float (*co)[3] = NULL, (*color)[3] = NULL, *area = NULL; int totpoint = 0, osa, osaflag, partsdone; if (re->test_break(re->tbh)) return; points.first= points.last= NULL; /* TODO: this is getting a bit ugly, copying all those variables and * setting them back, maybe we need to create our own Render? */ /* do SSS preprocessing render */ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); rr= re->result; osa= re->osa; osaflag= re->r.mode & R_OSA; partsdone= re->i.partsdone; re->osa= 0; re->r.mode &= ~R_OSA; re->sss_points= &points; re->sss_mat= mat; re->i.partsdone = FALSE; if (!(re->r.scemode & R_PREVIEWBUTS)) re->result= NULL; BLI_rw_mutex_unlock(&re->resultmutex); RE_TileProcessor(re); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (!(re->r.scemode & R_PREVIEWBUTS)) { RE_FreeRenderResult(re->result); re->result= rr; } BLI_rw_mutex_unlock(&re->resultmutex); re->i.partsdone= partsdone; re->sss_mat= NULL; re->sss_points= NULL; re->osa= osa; if (osaflag) re->r.mode |= R_OSA; /* no points? no tree */ if (!points.first) return; /* merge points together into a single buffer */ if (!re->test_break(re->tbh)) { for (totpoint=0, p=points.first; p; p=p->next) totpoint += p->totpoint; co= MEM_mallocN(sizeof(*co)*totpoint, "SSSCo"); color= MEM_mallocN(sizeof(*color)*totpoint, "SSSColor"); area= MEM_mallocN(sizeof(*area)*totpoint, "SSSArea"); for (totpoint=0, p=points.first; p; p=p->next) { memcpy(co+totpoint, p->co, sizeof(*co)*p->totpoint); memcpy(color+totpoint, p->color, sizeof(*color)*p->totpoint); memcpy(area+totpoint, p->area, sizeof(*area)*p->totpoint); totpoint += p->totpoint; } } /* free points */ for (p=points.first; p; p=p->next) { MEM_freeN(p->co); MEM_freeN(p->color); MEM_freeN(p->area); } BLI_freelistN(&points); /* build tree */ if (!re->test_break(re->tbh)) { SSSData *sss= MEM_callocN(sizeof(*sss), "SSSData"); float ior= mat->sss_ior, cfac= mat->sss_colfac; float *radius= mat->sss_radius; float fw= mat->sss_front, bw= mat->sss_back; float error = mat->sss_error; error= get_render_aosss_error(&re->r, error); if ((re->r.scemode & R_PREVIEWBUTS) && error < 0.5f) error= 0.5f; sss->ss[0]= scatter_settings_new(mat->sss_col[0], radius[0], ior, cfac, fw, bw); sss->ss[1]= scatter_settings_new(mat->sss_col[1], radius[1], ior, cfac, fw, bw); sss->ss[2]= scatter_settings_new(mat->sss_col[2], radius[2], ior, cfac, fw, bw); sss->tree= scatter_tree_new(sss->ss, mat->sss_scale, error, co, color, area, totpoint); MEM_freeN(co); MEM_freeN(color); MEM_freeN(area); scatter_tree_build(sss->tree); BLI_ghash_insert(re->sss_hash, mat, sss); } else { if (co) MEM_freeN(co); if (color) MEM_freeN(color); if (area) MEM_freeN(area); } }