Esempio n. 1
0
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;
	}
}
Esempio n. 3
0
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);
	}
}