Border rendering now works for all scenes used in compositor,

before this only active scene would be rendered with border.

When do_render_fields_blur_3d() is finished, it'll modify
render's display rect so it'll correspond bordered render
result placed on black backgrund. Actual border is stored
nowhere, which makes it only way to re-calculate disprect
for all other renders used in compo based on source. Not
so big deal actually.

Also needed to modify Cycles a bit, because before this
patch it used border settings from scene being rendered.
Now made it so render data is passing to external engines.

Using a property inside RenderEngine structure for this.
Not best ever design for passing render data, but this
would prevent API breakage. So now external engines could
access engine.render to access active rendering settings.

Reviewed by Brecht, thanks!
This commit is contained in:
Sergey Sharybin 2013-03-14 07:38:37 +00:00
parent 6a51379bf7
commit 9d896f8f84
8 changed files with 111 additions and 56 deletions

@ -65,7 +65,7 @@ struct BlenderCamera {
Transform matrix;
};
static void blender_camera_init(BlenderCamera *bcam, BL::Scene b_scene)
static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene)
{
memset(bcam, 0, sizeof(BlenderCamera));
@ -82,10 +82,8 @@ static void blender_camera_init(BlenderCamera *bcam, BL::Scene b_scene)
bcam->pano_viewplane.top = 1.0f;
/* render resolution */
BL::RenderSettings r = b_scene.render();
bcam->full_width = (int)(r.resolution_x()*r.resolution_percentage()/100);
bcam->full_height = (int)(r.resolution_y()*r.resolution_percentage()/100);
bcam->full_width = (int)(b_render.resolution_x()*b_render.resolution_percentage()/100);
bcam->full_height = (int)(b_render.resolution_y()*b_render.resolution_percentage()/100);
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@ -351,24 +349,22 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* Sync Render Camera */
void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height)
{
BlenderCamera bcam;
blender_camera_init(&bcam, b_scene);
blender_camera_init(&bcam, b_render, b_scene);
/* pixel aspect */
BL::RenderSettings r = b_scene.render();
bcam.pixelaspect.x = r.pixel_aspect_x();
bcam.pixelaspect.y = r.pixel_aspect_y();
bcam.shuttertime = r.motion_blur_shutter();
bcam.pixelaspect.x = b_render.pixel_aspect_x();
bcam.pixelaspect.y = b_render.pixel_aspect_y();
bcam.shuttertime = b_render.motion_blur_shutter();
/* border */
if(r.use_border()) {
bcam.border.left = r.border_min_x();
bcam.border.right = r.border_max_x();
bcam.border.bottom = r.border_min_y();
bcam.border.top = r.border_max_y();
if(b_render.use_border()) {
bcam.border.left = b_render.border_min_x();
bcam.border.right = b_render.border_max_x();
bcam.border.bottom = b_render.border_min_y();
bcam.border.top = b_render.border_max_y();
}
/* camera object */
@ -406,7 +402,7 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
/* Sync 3D View Camera */
static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box);
static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
@ -428,7 +424,7 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
/* in panorama camera view, we map viewplane to camera border */
BoundBox2D view_box, cam_box;
blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height,
blender_camera_view_subset(b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
bcam->pano_viewplane = view_box.make_relative_to(cam_box);
@ -466,16 +462,15 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box)
{
// BL::RenderSettings r = b_scene.render(); /* UNUSED */
BoundBox2D cam, view;
float view_aspect, cam_aspect, sensor_size;
/* get viewport viewplane */
BlenderCamera view_bcam;
blender_camera_init(&view_bcam, b_scene);
blender_camera_init(&view_bcam, b_render, b_scene);
blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
@ -483,7 +478,7 @@ static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::S
/* get camera viewplane */
BlenderCamera cam_bcam;
blender_camera_init(&cam_bcam, b_scene);
blender_camera_init(&cam_bcam, b_render, b_scene);
blender_camera_from_object(&cam_bcam, b_ob, true);
blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
@ -494,10 +489,9 @@ static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::S
*cam_box = cam * (1.0f/cam_aspect);
}
static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d,
static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height)
{
BL::RenderSettings r = b_scene.render();
bool is_camera_view;
/* camera view? */
@ -517,7 +511,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
return;
}
}
else if(!r.use_border())
else if(!b_render.use_border())
return;
BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
@ -525,15 +519,15 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
if(!b_ob)
return;
bcam->border.left = r.border_min_x();
bcam->border.right = r.border_max_x();
bcam->border.bottom = r.border_min_y();
bcam->border.top = r.border_max_y();
bcam->border.left = b_render.border_min_x();
bcam->border.right = b_render.border_max_x();
bcam->border.bottom = b_render.border_min_y();
bcam->border.top = b_render.border_max_y();
/* determine camera viewport subset */
BoundBox2D view_box, cam_box;
blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height,
blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
/* determine viewport subset matching camera border */
@ -544,14 +538,14 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
{
BlenderCamera bcam;
blender_camera_init(&bcam, b_scene);
blender_camera_init(&bcam, b_scene.render(), b_scene);
blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height);
blender_camera_border(&bcam, b_scene, b_v3d, b_rv3d, width, height);
blender_camera_border(&bcam, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
blender_camera_sync(scene->camera, &bcam, width, height);
}
BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
{
BufferParams params;
bool use_border = false;
@ -562,7 +556,7 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b
if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
use_border = b_v3d.use_render_border();
else
use_border = b_scene.render().use_border();
use_border = b_render.use_border();
if(use_border) {
/* border render */

@ -41,13 +41,13 @@ CCL_NAMESPACE_BEGIN
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_)
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_render(b_engine_.render()), b_scene(b_scene_),
b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL)
{
/* offline render */
width = b_engine.resolution_x();
height = b_engine.resolution_y();
width = (int)(b_render.resolution_x()*b_render.resolution_percentage()/100);
height = (int)(b_render.resolution_y()*b_render.resolution_percentage()/100);
background = true;
last_redraw_time = 0.0f;
@ -58,10 +58,11 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_,
BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_)
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_render(b_scene_.render()), b_scene(b_scene_),
b_v3d(b_v3d_), b_rv3d(b_rv3d_)
{
/* 3d view render */
width = width_;
height = height_;
background = false;
@ -102,10 +103,10 @@ void BlenderSession::create_session()
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
sync->sync_camera(b_engine.camera_override(), width, height);
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
/* set buffer parameters */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@ -119,13 +120,14 @@ void BlenderSession::create_session()
void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
{
b_data = b_data_;
b_render = b_engine.render();
b_scene = b_scene_;
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
width = b_engine.resolution_x();
height = b_engine.resolution_y();
width = b_render.resolution_x();
height = b_render.resolution_y();
if(scene->params.modified(scene_params) ||
session->params.modified(session_params) ||
@ -155,9 +157,9 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
/* sync object should be re-created */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
sync->sync_camera(b_engine.camera_override(), width, height);
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@ -307,7 +309,7 @@ void BlenderSession::render()
/* get buffer parameters */
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
/* render each layer */
BL::RenderSettings r = b_scene.render();
@ -471,14 +473,14 @@ void BlenderSession::synchronize()
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
sync->sync_camera(b_engine.camera_override(), width, height);
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
/* unlock */
session->scene->mutex.unlock();
/* reset if needed */
if(scene->need_reset()) {
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
}
}
@ -515,7 +517,7 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if(reset) {
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, w, h);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, w, h);
session->reset(buffer_params, session_params.samples);
}
@ -528,7 +530,7 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
return !session->draw(buffer_params);
}

@ -80,6 +80,7 @@ public:
BL::RenderEngine b_engine;
BL::UserPreferences b_userpref;
BL::BlendData b_data;
BL::RenderSettings b_render;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;

@ -56,7 +56,7 @@ public:
/* sync */
bool sync_recalc();
void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0);
void sync_camera(BL::Object b_override, int width, int height);
void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height);
void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
int get_layer_samples() { return render_layer.samples; }
@ -64,7 +64,7 @@ public:
static SceneParams get_scene_params(BL::Scene b_scene, bool background);
static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background);
static bool get_session_pause(BL::Scene b_scene, bool background);
static BufferParams get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
static BufferParams get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
private:
/* sync */

@ -226,6 +226,20 @@ static StructRNA *rna_RenderEngine_refine(PointerRNA *ptr)
return (engine->type && engine->type->ext.srna) ? engine->type->ext.srna : &RNA_RenderEngine;
}
static PointerRNA rna_RenderEngine_render_get(PointerRNA *ptr)
{
RenderEngine *engine = (RenderEngine *)ptr->data;
if (engine->re) {
RenderData *r = RE_engine_get_render_data(engine->re);
return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, r);
}
else {
return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, NULL);
}
}
static void rna_RenderResult_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
RenderResult *rr = (RenderResult *)ptr->data;
@ -407,6 +421,12 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "resolution_y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
/* Render Data */
prop = RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "RenderSettings");
RNA_def_property_pointer_funcs(prop, "rna_RenderEngine_render_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Render Data", "");
prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);

@ -33,12 +33,14 @@
#define __RE_ENGINE_H__
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "RNA_types.h"
struct bNode;
struct bNodeTree;
struct Object;
struct Render;
struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderLayer;
@ -134,6 +136,7 @@ void RE_engines_exit(void);
RenderEngineType *RE_engines_find(const char *idname);
void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
struct RenderData *RE_engine_get_render_data(struct Render *re);
#endif /* __RE_ENGINE_H__ */

@ -385,6 +385,11 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
*tiles_r = tiles;
}
RenderData *RE_engine_get_render_data(Render *re)
{
return &re->r;
}
/* Render */
int RE_engine_render(Render *re, int do_all)

@ -457,12 +457,42 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->i.starttime = PIL_check_seconds_timer();
re->r = *rd; /* hardcopy */
if (source) {
/* reuse border flags from source renderer */
re->r.mode &= ~(R_BORDER | R_CROP);
re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
/* dimensions shall be shared between all renderers */
re->r.xsch = source->r.xsch;
re->r.ysch = source->r.ysch;
re->r.size = source->r.size;
}
re->winx = winx;
re->winy = winy;
if (disprect) {
if (source && (source->r.mode & R_BORDER)) {
/* eeh, doesn't seem original bordered disprect is storing anywhere
* after insertion on black happening in do_render_fields_blur_3d(),
* so for now simply re-calculate disprect using border from source
* renderer (sergey)
*/
re->disprect.xmin = source->r.border.xmin * winx;
re->disprect.xmax = source->r.border.xmax * winx;
re->disprect.ymin = source->r.border.ymin * winy;
re->disprect.ymax = source->r.border.ymax * winy;
re->rectx = BLI_rcti_size_x(&re->disprect);
re->recty = BLI_rcti_size_y(&re->disprect);
/* copy border itself, since it could be used by external engines */
re->r.border = source->r.border;
}
else if (disprect) {
re->disprect = *disprect;
re->rectx = BLI_rcti_size_x(disprect);
re->recty = BLI_rcti_size_y(disprect);
re->rectx = BLI_rcti_size_x(&re->disprect);
re->recty = BLI_rcti_size_y(&re->disprect);
}
else {
re->disprect.xmin = re->disprect.ymin = 0;