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;
}
示例#2
0
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;
}
示例#6
0
/* 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;
}
示例#7
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);
	}
}