static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) { RenderPreview *rp = customdata; Render *re; RenderStats *rstats; RenderData rdata; rctf viewplane; rcti cliprct; float clipsta, clipend, pixsize; bool orth, restore = 0; char name[32]; int update_flag; update_flag = rp->engine->job_update_flag; rp->engine->job_update_flag = 0; //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE); G.is_break = FALSE; if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth)) return; rp->stop = stop; rp->do_update = do_update; // printf("Enter previewrender\n"); /* ok, are we rendering all over? */ sprintf(name, "View3dPreview %p", (void *)rp->ar); re = rp->engine->re = RE_GetRender(name); /* set this always, rp is different for each job */ RE_test_break_cb(re, rp, render_view3d_break); RE_display_draw_cb(re, rp, render_view3d_draw_update); RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb); rstats = RE_GetStats(re); if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) { /* no osa, blur, seq, layers, etc for preview render */ rdata = rp->scene->r; rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA); rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE); rdata.scemode |= R_VIEWPORT_PREVIEW; /* we do use layers, but only active */ rdata.scemode |= R_SINGLE_LAYER; /* initalize always */ if (render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct)) { rdata.mode |= R_BORDER; RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct); } else RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL); } if (orth) RE_SetOrtho(re, &viewplane, clipsta, clipend); else RE_SetWindow(re, &viewplane, clipsta, clipend); RE_SetPixelSize(re, pixsize); if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { unsigned int lay = rp->scene->lay; /* allow localview render for objects with lights in normal layers */ if (rp->v3d->lay & 0xFF000000) lay |= rp->v3d->lay; else lay = rp->v3d->lay; RE_SetView(re, rp->viewmat); /* copying blender data while main thread is locked, to avoid crashes */ WM_job_main_thread_lock_acquire(rp->job); RE_Database_Free(re); RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view WM_job_main_thread_lock_release(rp->job); /* do preprocessing like building raytree, shadows, volumes, SSS */ RE_Database_Preprocess(re); /* conversion not completed, need to do it again */ if (!rstats->convertdone) { if (render_view3d_is_valid(rp)) { rp->engine->job_update_flag |= PR_UPDATE_DATABASE; } } // printf("dbase update\n"); } else { // printf("dbase rotate\n"); RE_DataBase_IncrementalView(re, rp->viewmat, 0); restore = 1; } RE_DataBase_ApplyWindow(re); /* OK, can we enter render code? */ if (rstats->convertdone) { RE_TileProcessor(re); /* always rotate back */ if (restore) RE_DataBase_IncrementalView(re, rp->viewmat, 1); } }
static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) { RenderPreview *rp = customdata; Render *re; RenderStats *rstats; RenderData rdata; rctf viewplane; rcti cliprct; float clipsta, clipend, pixsize; bool orth, restore = 0; char name[32]; G.is_break = FALSE; if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth)) return; rp->stop = stop; rp->do_update = do_update; // printf("Enter previewrender\n"); /* ok, are we rendering all over? */ sprintf(name, "View3dPreview %p", (void *)rp->ar); re = rp->engine->re = RE_GetRender(name); if (rp->engine->re == NULL) { re = rp->engine->re = RE_NewRender(name); rp->keep_data = 0; } /* set this always, rp is different for each job */ RE_test_break_cb(re, rp, render_view3d_break); RE_display_draw_cb(re, rp, render_view3d_draw_update); RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb); rstats = RE_GetStats(re); if (rp->keep_data == 0 || rstats->convertdone == 0 || (rp->keep_data & PR_UPDATE_RENDERSIZE)) { /* no osa, blur, seq, layers, etc for preview render */ rdata = rp->scene->r; rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA); rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE); rdata.scemode |= R_VIEWPORT_PREVIEW; /* we do use layers, but only active */ rdata.scemode |= R_SINGLE_LAYER; /* initalize always */ if (render_view3d_disprect(rp->scene, rp->ar, rp->v3d, rp->rv3d, &cliprct)) { rdata.mode |= R_BORDER; RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct); } else RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL); } if (orth) RE_SetOrtho(re, &viewplane, clipsta, clipend); else RE_SetWindow(re, &viewplane, clipsta, clipend); RE_SetPixelSize(re, pixsize); /* database free can crash on a empty Render... */ if (rp->keep_data == 0 && rstats->convertdone) RE_Database_Free(re); if (rstats->convertdone == 0) { unsigned int lay = rp->scene->lay; /* allow localview render for objects with lights in normal layers */ if (rp->v3d->lay & 0xFF000000) lay |= rp->v3d->lay; else lay = rp->v3d->lay; RE_SetView(re, rp->viewmat); RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view // printf("dbase update\n"); } else { // printf("dbase rotate\n"); RE_DataBase_IncrementalView(re, rp->viewmat, 0); restore = 1; } RE_DataBase_ApplyWindow(re); /* OK, can we enter render code? */ if (rstats->convertdone) { RE_TileProcessor(re); /* always rotate back */ if (restore) RE_DataBase_IncrementalView(re, rp->viewmat, 1); rp->engine->flag &= ~RE_ENGINE_DO_UPDATE; } }
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); } }