예제 #1
0
/* executes blocking render */
static int screen_opengl_render_exec(bContext *C, wmOperator *op)
{
	const bool is_animation = RNA_boolean_get(op->ptr, "animation");

	if (!screen_opengl_render_init(C, op))
		return OPERATOR_CANCELLED;

	if (!is_animation) { /* same as invoke */
		/* render image */
		screen_opengl_render_apply(op->customdata);
		screen_opengl_render_end(C, op->customdata);

		return OPERATOR_FINISHED;
	}
	else {
		bool ret = true;

		if (!screen_opengl_render_anim_initialize(C, op))
			return OPERATOR_CANCELLED;

		while (ret) {
			ret = screen_opengl_render_anim_step(C, op);
		}
	}

	/* no redraw needed, we leave state as we entered it */
//	ED_update_for_newframe(C, 1);
	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, CTX_data_scene(C));

	return OPERATOR_FINISHED;
}
예제 #2
0
static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
	OGLRender *oglrender = op->customdata;
	const bool anim = RNA_boolean_get(op->ptr, "animation");
	bool ret;

	switch (event->type) {
		case ESCKEY:
			/* cancel */
			screen_opengl_render_end(C, op->customdata);
			return OPERATOR_FINISHED;
		case TIMER:
			/* render frame? */
			if (oglrender->timer == event->customdata)
				break;
			/* fall-through */
		default:
			/* nothing to do */
			return OPERATOR_RUNNING_MODAL;
	}

	/* run first because screen_opengl_render_anim_step can free oglrender */
	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
	
	if (anim == 0) {
		screen_opengl_render_apply(op->customdata);
		screen_opengl_render_end(C, op->customdata);
		return OPERATOR_FINISHED;
	}
	else {
		ret = screen_opengl_render_anim_step(C, op);
	}

	/* stop at the end or on error */
	if (ret == false) {
		return OPERATOR_FINISHED;
	}

	return OPERATOR_RUNNING_MODAL;
}
예제 #3
0
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	OGLRender *oglrender = op->customdata;
	Scene *scene = oglrender->scene;
	char name[FILE_MAX];
	bool ok = false;
	const bool view_context = (oglrender->v3d != NULL);
	bool is_movie;
	RenderResult *rr;

	/* go to next frame */
	if (CFRA < oglrender->nfra)
		CFRA++;
	while (CFRA < oglrender->nfra) {
		unsigned int lay = screen_opengl_layers(oglrender);

		if (lay & 0xFF000000)
			lay &= 0xFF000000;

		BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
		CFRA++;
	}

	is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);

	if (!is_movie) {
		BKE_image_path_from_imformat(
		        name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
		        &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);

		if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
			BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
			ok = true;
			goto finally;
		}
	}

	WM_cursor_time(oglrender->win, scene->r.cfra);

	BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));

	if (view_context) {
		if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
			/* since BKE_scene_update_for_newframe() is used rather
			 * then ED_update_for_newframe() the camera needs to be set */
			if (BKE_scene_camera_switch_update(scene)) {
				oglrender->v3d->camera = scene->camera;
			}
		}
	}
	else {
		BKE_scene_camera_switch_update(scene);
	}

	/* render into offscreen buffer */
	screen_opengl_render_apply(oglrender);

	/* save to disk */
	rr = RE_AcquireResultRead(oglrender->re);

	if (is_movie) {
		ok = RE_WriteRenderViewsMovie(oglrender->reports, rr, scene, &scene->r, oglrender->mh, oglrender->sizex,
		                              oglrender->sizey, oglrender->movie_ctx_arr, oglrender->totvideos, PRVRANGEON != 0);
		if (ok) {
			printf("Append frame %d", scene->r.cfra);
			BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
		}
	}
	else {
		ok = RE_WriteRenderViewsImage(op->reports, rr, scene, scene->camera, true, name);
		if (ok) {
			printf("Saved: %s", name);
			BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
		}
		else {
			printf("Write error: cannot save %s\n", name);
			BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
		}
	}

	RE_ReleaseResult(oglrender->re);


	/* movie stats prints have no line break */
	printf("\n");


finally:  /* Step the frame and bail early if needed */

	/* go to next frame */
	oglrender->nfra += scene->r.frame_step;

	/* stop at the end or on error */
	if (CFRA >= PEFRA || !ok) {
		screen_opengl_render_end(C, op->customdata);
		return 0;
	}

	return 1;
}
예제 #4
0
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	OGLRender *oglrender = op->customdata;
	Scene *scene = oglrender->scene;
	ImBuf *ibuf, *ibuf_save = NULL;
	void *lock;
	char name[FILE_MAX];
	int ok = 0;
	const short view_context = (oglrender->v3d != NULL);
	Object *camera = NULL;
	int is_movie;

	/* go to next frame */
	if (CFRA < oglrender->nfra)
		CFRA++;
	while (CFRA < oglrender->nfra) {
		unsigned int lay = screen_opengl_layers(oglrender);

		if (lay & 0xFF000000)
			lay &= 0xFF000000;

		BKE_scene_update_for_newframe(bmain, scene, lay);
		CFRA++;
	}

	is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);

	if (!is_movie) {
		BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);

		if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
			BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
			ok = true;
			goto finally;
		}
	}

	WM_cursor_time(oglrender->win, scene->r.cfra);

	BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender));

	if (view_context) {
		if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
			/* since BKE_scene_update_for_newframe() is used rather
			 * then ED_update_for_newframe() the camera needs to be set */
			if (BKE_scene_camera_switch_update(scene)) {
				oglrender->v3d->camera = scene->camera;
			}

			camera = oglrender->v3d->camera;
		}
	}
	else {
		BKE_scene_camera_switch_update(scene);

		camera = scene->camera;
	}

	/* render into offscreen buffer */
	screen_opengl_render_apply(oglrender);

	/* save to disk */
	ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);

	if (ibuf) {
		int needs_free = FALSE;

		ibuf_save = ibuf;

		if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
			ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, true, true, &scene->view_settings,
			                                                &scene->display_settings, &scene->r.im_format);

			needs_free = TRUE;
		}

		/* color -> grayscale */
		/* editing directly would alter the render view */
		if (scene->r.im_format.planes == R_IMF_PLANES_BW) {
			ImBuf *ibuf_bw = IMB_dupImBuf(ibuf_save);
			IMB_color_to_bw(ibuf_bw);

			if (needs_free)
				IMB_freeImBuf(ibuf_save);

			ibuf_save = ibuf_bw;
		}
		else {
			/* this is lightweight & doesnt re-alloc the buffers, only do this
			 * to save the correct bit depth since the image is always RGBA */
			ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf_save->x, ibuf_save->y, scene->r.im_format.planes, 0);

			ibuf_cpy->rect = ibuf_save->rect;
			ibuf_cpy->rect_float = ibuf_save->rect_float;
			ibuf_cpy->zbuf_float = ibuf_save->zbuf_float;

			if (needs_free) {
				ibuf_cpy->mall = ibuf_save->mall;
				ibuf_save->mall = 0;
				IMB_freeImBuf(ibuf_save);
			}

			ibuf_save = ibuf_cpy;
		}

		if (is_movie) {
			ok = oglrender->mh->append_movie(&scene->r, PSFRA, CFRA, (int *)ibuf_save->rect,
			                                 oglrender->sizex, oglrender->sizey, oglrender->reports);
			if (ok) {
				printf("Append frame %d", scene->r.cfra);
				BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
			}
		}
		else {
			ok = BKE_imbuf_write_stamp(scene, camera, ibuf_save, name, &scene->r.im_format);

			if (ok == 0) {
				printf("Write error: cannot save %s\n", name);
				BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
			}
			else {
				printf("Saved: %s", name);
				BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
			}
		}

		if (needs_free)
			IMB_freeImBuf(ibuf_save);
	}

	BKE_image_release_ibuf(oglrender->ima, ibuf, lock);

	/* movie stats prints have no line break */
	printf("\n");


finally:  /* Step the frame and bail early if needed */

	/* go to next frame */
	oglrender->nfra += scene->r.frame_step;

	/* stop at the end or on error */
	if (CFRA >= PEFRA || !ok) {
		screen_opengl_render_end(C, op->customdata);
		return 0;
	}

	return 1;
}