diff options
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 239 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/buffers.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/render/camera.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/camera.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/session.cpp | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 55 |
8 files changed, 245 insertions, 82 deletions
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index bdd02bb5086..9bc82344fcc 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -56,6 +56,11 @@ struct BlenderCamera { float sensor_width; float sensor_height; + float border_left; + float border_right; + float border_bottom; + float border_top; + Transform matrix; }; @@ -70,6 +75,8 @@ static void blender_camera_init(BlenderCamera *bcam) bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; + bcam->border_right = 1.0f; + bcam->border_top = 1.0f; } static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) @@ -188,85 +195,94 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type) return transform_clear_scale(result); } -static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) +static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height, + float *left, float *right, float *bottom, float *top, float *aspectratio, float *sensor_size) { - /* copy camera to compare later */ - Camera prevcam = *cam; - /* dimensions */ float xratio = width*bcam->pixelaspect.x; float yratio = height*bcam->pixelaspect.y; /* compute x/y aspect and ratio */ - float aspectratio, xaspect, yaspect; + float xaspect, yaspect; /* sensor fitting */ bool horizontal_fit; - float sensor_size; - - cam->sensorwidth = bcam->sensor_width; - cam->sensorheight = bcam->sensor_height; if(bcam->sensor_fit == BlenderCamera::AUTO) { horizontal_fit = (xratio > yratio); - sensor_size = bcam->sensor_width; + *sensor_size = bcam->sensor_width; } else if(bcam->sensor_fit == BlenderCamera::HORIZONTAL) { horizontal_fit = true; - sensor_size = bcam->sensor_width; + *sensor_size = bcam->sensor_width; } else { horizontal_fit = false; - sensor_size = bcam->sensor_height; + *sensor_size = bcam->sensor_height; } if(horizontal_fit) { - aspectratio= xratio/yratio; - xaspect= aspectratio; + *aspectratio= xratio/yratio; + xaspect= *aspectratio; yaspect= 1.0f; } else { - aspectratio= yratio/xratio; + *aspectratio= yratio/xratio; xaspect= 1.0f; - yaspect= aspectratio; + yaspect= *aspectratio; } /* modify aspect for orthographic scale */ if(bcam->type == CAMERA_ORTHOGRAPHIC) { - xaspect = xaspect*bcam->ortho_scale/(aspectratio*2.0f); - yaspect = yaspect*bcam->ortho_scale/(aspectratio*2.0f); - aspectratio = bcam->ortho_scale/2.0f; + xaspect = xaspect*bcam->ortho_scale/(*aspectratio*2.0f); + yaspect = yaspect*bcam->ortho_scale/(*aspectratio*2.0f); + *aspectratio = bcam->ortho_scale/2.0f; } if(bcam->type == CAMERA_PANORAMA) { /* set viewplane */ - cam->left = 0.0f; - cam->right = 1.0f; - cam->bottom = 0.0f; - cam->top = 1.0f; + *left = 0.0f; + *right = 1.0f; + *bottom = 0.0f; + *top = 1.0f; } else { /* set viewplane */ - cam->left = -xaspect; - cam->right = xaspect; - cam->bottom = -yaspect; - cam->top = yaspect; + *left = -xaspect; + *right = xaspect; + *bottom = -yaspect; + *top = yaspect; /* zoom for 3d camera view */ - cam->left *= bcam->zoom; - cam->right *= bcam->zoom; - cam->bottom *= bcam->zoom; - cam->top *= bcam->zoom; + *left *= bcam->zoom; + *right *= bcam->zoom; + *bottom *= bcam->zoom; + *top *= bcam->zoom; /* modify viewplane with camera shift and 3d camera view offset */ - float dx = 2.0f*(aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); - float dy = 2.0f*(aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); + float dx = 2.0f*(*aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f); + float dy = 2.0f*(*aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f); - cam->left += dx; - cam->right += dx; - cam->bottom += dy; - cam->top += dy; + *left += dx; + *right += dx; + *bottom += dy; + *top += dy; } +} + +static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) +{ + /* copy camera to compare later */ + Camera prevcam = *cam; + float aspectratio, sensor_size; + + /* viewplane */ + blender_camera_viewplane(bcam, width, height, + &cam->left, &cam->right, &cam->bottom, &cam->top, &aspectratio, &sensor_size); + + /* sensor */ + cam->sensorwidth = bcam->sensor_width; + cam->sensorheight = bcam->sensor_height; /* clipping distances */ cam->nearclip = bcam->nearclip; @@ -294,6 +310,12 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->use_motion = false; cam->shuttertime = bcam->shuttertime; + /* border */ + cam->border_left = bcam->border_left; + cam->border_right = bcam->border_right; + cam->border_bottom = bcam->border_bottom; + cam->border_top = bcam->border_top; + /* set update flag */ if(cam->modified(prevcam)) cam->tag_update(); @@ -313,6 +335,14 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height) bcam.pixelaspect.y = r.pixel_aspect_y(); bcam.shuttertime = r.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(); + } + /* camera object */ BL::Object b_ob = b_scene.camera(); @@ -348,67 +378,142 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion) /* Sync 3D View Camera */ -void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) +static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) { - BlenderCamera bcam; - blender_camera_init(&bcam); - /* 3d view parameters */ - bcam.nearclip = b_v3d.clip_start(); - bcam.farclip = b_v3d.clip_end(); - bcam.lens = b_v3d.lens(); - bcam.shuttertime = b_scene.render().motion_blur_shutter(); + bcam->nearclip = b_v3d.clip_start(); + bcam->farclip = b_v3d.clip_end(); + bcam->lens = b_v3d.lens(); + bcam->shuttertime = b_scene.render().motion_blur_shutter(); if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { /* camera view */ BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); if(b_ob) { - blender_camera_from_object(&bcam, b_ob); + blender_camera_from_object(bcam, b_ob); /* magic zoom formula */ - bcam.zoom = (float)b_rv3d.view_camera_zoom(); - bcam.zoom = (1.41421f + bcam.zoom/50.0f); - bcam.zoom *= bcam.zoom; - bcam.zoom = 2.0f/bcam.zoom; + bcam->zoom = (float)b_rv3d.view_camera_zoom(); + bcam->zoom = (1.41421f + bcam->zoom/50.0f); + bcam->zoom *= bcam->zoom; + bcam->zoom = 2.0f/bcam->zoom; /* offset */ - bcam.offset = get_float2(b_rv3d.view_camera_offset()); + bcam->offset = get_float2(b_rv3d.view_camera_offset()); } } else if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_ORTHO) { /* orthographic view */ - bcam.farclip *= 0.5; - bcam.nearclip = -bcam.farclip; + bcam->farclip *= 0.5; + bcam->nearclip = -bcam->farclip; - bcam.type = CAMERA_ORTHOGRAPHIC; - bcam.ortho_scale = b_rv3d.view_distance(); + bcam->type = CAMERA_ORTHOGRAPHIC; + bcam->ortho_scale = b_rv3d.view_distance(); } - bcam.zoom *= 2.0f; + bcam->zoom *= 2.0f; /* 3d view transform */ - bcam.matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); + bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix())); +} + +static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, + BL::RegionView3D b_rv3d, int width, int height) +{ + BL::RenderSettings r = b_scene.render(); + + if(!r.use_border()) + return; + + /* camera view? */ + if(!(b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA)) + return; + + BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera(); + + 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(); + + float cam_left, cam_right, cam_bottom, cam_top; + float view_left, view_right, view_bottom, view_top; + float view_aspect, cam_aspect, sensor_size; + + /* get viewport viewplane */ + BlenderCamera view_bcam; + blender_camera_init(&view_bcam); + blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height); + + blender_camera_viewplane(&view_bcam, width, height, + &view_left, &view_right, &view_bottom, &view_top, &view_aspect, &sensor_size); + + view_left /= view_aspect; + view_right /= view_aspect; + view_bottom /= view_aspect; + view_top /= view_aspect; + + /* get camera viewplane */ + BlenderCamera cam_bcam; + blender_camera_init(&cam_bcam); + blender_camera_from_object(&cam_bcam, b_ob); + + width = (int)(r.resolution_x()*r.resolution_percentage()/100); + height = (int)(r.resolution_y()*r.resolution_percentage()/100); + + blender_camera_viewplane(&cam_bcam, width, height, + &cam_left, &cam_right, &cam_bottom, &cam_top, &cam_aspect, &sensor_size); + + cam_left /= cam_aspect; + cam_right /= cam_aspect; + cam_bottom /= cam_aspect; + cam_top /= cam_aspect; + + /* determine viewport subset matching camera border */ + float tmp_left = ((cam_left - view_left) / (view_right - view_left)); + float tmp_right = ((cam_right - view_left) / (view_right - view_left)); + float tmp_bottom = ((cam_bottom - view_bottom) / (view_top - view_bottom)); + float tmp_top = ((cam_top - view_bottom) / (view_top - view_bottom)); + + bcam->border_left = tmp_left + bcam->border_left*(tmp_right - tmp_left); + bcam->border_right = tmp_left + bcam->border_right*(tmp_right - tmp_left); + bcam->border_bottom = tmp_bottom + bcam->border_bottom*(tmp_top - tmp_bottom); + bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom); + + /* clamp */ + bcam->border_left = max(bcam->border_left, 0.0f); + bcam->border_right = min(bcam->border_right, 1.0f); + bcam->border_bottom = max(bcam->border_bottom, 0.0f); + bcam->border_top = min(bcam->border_top, 1.0f); +} + +void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) +{ + BlenderCamera bcam; + blender_camera_init(&bcam); + 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); - /* sync */ blender_camera_sync(scene->camera, &bcam, width, height); } -BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height) +BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height) { BufferParams params; params.full_width = width; params.full_height = height; - /* border render */ - BL::RenderSettings r = b_scene.render(); - - if(!b_rv3d && r.use_border()) { - params.full_x = r.border_min_x()*width; - params.full_y = r.border_min_y()*height; - params.width = (int)(r.border_max_x()*width) - params.full_x; - params.height = (int)(r.border_max_y()*height) - params.full_y; + if(b_scene.render().use_border()) { + /* border render */ + params.full_x = cam->border_left*width; + params.full_y = cam->border_bottom*height; + params.width = (int)(cam->border_right*width) - params.full_x; + params.height = (int)(cam->border_top*height) - params.full_y; } else { params.width = width; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 997909f1b92..9726f7b94cf 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -106,7 +106,7 @@ void BlenderSession::create_session() session->set_pause(BlenderSync::get_session_pause(b_scene, background)); /* set buffer parameters */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } @@ -181,7 +181,7 @@ void BlenderSession::render() { /* get buffer parameters */ SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); int w = buffer_params.width, h = buffer_params.height; /* create render result */ @@ -326,7 +326,7 @@ void BlenderSession::synchronize() /* reset if needed */ if(scene->need_reset()) { - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); session->reset(buffer_params, session_params.samples); } } @@ -364,7 +364,7 @@ bool BlenderSession::draw(int w, int h) /* reset if requested */ if(reset) { SessionParams session_params = BlenderSync::get_session_params(b_userpref, b_scene, background); - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, w, h); session->reset(buffer_params, session_params.samples); } @@ -374,7 +374,7 @@ bool BlenderSession::draw(int w, int h) update_status_progress(); /* draw */ - BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height); + BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height); return !session->draw(buffer_params); } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 10afd468850..bc6258d35ac 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -63,7 +63,7 @@ public: static SceneParams get_scene_params(BL::Scene b_scene, bool background); static SessionParams get_session_params(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::RegionView3D b_rv3d, int width, int height); + static BufferParams get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height); private: /* sync */ diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index a80851b945a..a7fd47c94cf 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -311,8 +311,14 @@ void DisplayBuffer::draw_set(int width, int height) void DisplayBuffer::draw(Device *device) { - if(draw_width != 0 && draw_height != 0) + if(draw_width != 0 && draw_height != 0) { + glPushMatrix(); + glTranslatef(params.full_x, params.full_y, 0.0f); + device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent); + + glPopMatrix(); + } } bool DisplayBuffer::draw_ready() diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 3ecffab7cbc..ed239074cd4 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -58,6 +58,11 @@ Camera::Camera() bottom = -1.0f; top = 1.0f; + border_left = 0.0f; + border_right = 1.0f; + border_bottom = 0.0f; + border_top = 1.0f; + screentoworld = transform_identity(); rastertoworld = transform_identity(); ndctoworld = transform_identity(); @@ -248,6 +253,10 @@ bool Camera::modified(const Camera& cam) (right == cam.right) && (bottom == cam.bottom) && (top == cam.top) && + (border_left == cam.border_left) && + (border_right == cam.border_right) && + (border_bottom == cam.border_bottom) && + (border_top == cam.border_top) && (matrix == cam.matrix) && (motion == cam.motion) && (use_motion == cam.use_motion) && diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 7a09b5981e4..647423d88ba 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -67,6 +67,9 @@ public: int width, height; float left, right, bottom, top; + /* border */ + float border_left, border_right, border_bottom, border_top; + /* transformation */ Transform matrix; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 34a0c0ff877..173d73ea2c7 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -27,6 +27,7 @@ #include "util_foreach.h" #include "util_function.h" +#include "util_opengl.h" #include "util_task.h" #include "util_time.h" diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 7c12816741d..a36c14151e6 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1146,7 +1146,6 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* border */ if (scene->r.mode & R_BORDER) { - cpack(0); x3 = x1 + scene->r.border.xmin * (x2 - x1); y3 = y1 + scene->r.border.ymin * (y2 - y1); @@ -2735,12 +2734,15 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); } -static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) +static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); + +static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw_border) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); RenderEngineType *type; + GLint scissor[4]; /* create render engine */ if (!rv3d->render_engine) { @@ -2757,17 +2759,48 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); /* background draw */ + ED_region_pixelspace(ar); + + if (draw_border) { + /* for border draw, we only need to clear a subset of the 3d view */ + rctf viewborder; + rcti cliprct; + + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * (viewborder.xmax - viewborder.xmin); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * (viewborder.ymax - viewborder.ymin); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * (viewborder.xmax - viewborder.xmin); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * (viewborder.ymax - viewborder.ymin); + + cliprct.xmin += ar->winrct.xmin; + cliprct.xmax += ar->winrct.xmin; + cliprct.ymin += ar->winrct.ymin; + cliprct.ymax += ar->winrct.ymin; + + cliprct.xmin = MAX2(cliprct.xmin, ar->winrct.xmin); + cliprct.ymin = MAX2(cliprct.ymin, ar->winrct.ymin); + cliprct.xmax = MIN2(cliprct.xmax, ar->winrct.xmax); + cliprct.ymax = MIN2(cliprct.ymax, ar->winrct.ymax); + + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + } + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ED_region_pixelspace(ar); - - /* render result draw */ if (v3d->flag & V3D_DISPBGPICS) view3d_draw_bgpic(scene, ar, v3d, FALSE, TRUE); else fdrawcheckerboard(0, 0, ar->winx, ar->winy); + if (draw_border) { + /* restore scissor as it was before */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } + + /* render result draw */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, C); @@ -3028,15 +3061,21 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha void view3d_main_area_draw(const bContext *C, ARegion *ar) { + Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; + int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); - /* draw viewport using external renderer? */ - if (!(v3d->drawtype == OB_RENDER && view3d_main_area_draw_engine(C, ar))) { - /* draw viewport using opengl */ + /* draw viewport using opengl */ + if (v3d->drawtype != OB_RENDER || draw_border) { view3d_main_area_draw_objects(C, ar, &grid_unit); ED_region_pixelspace(ar); } + + /* draw viewport using external renderer */ + if (v3d->drawtype == OB_RENDER) + view3d_main_area_draw_engine(C, ar, draw_border); view3d_main_area_draw_info(C, ar, grid_unit); |